Ik ben bezig met het implementeren van het verwerken van geuploade afbeeldingen op een website. Hierbij stel ik me een aantal vragen omtrent het bewaren van deze bestanden en hoe de database (mysql in mijn geval) er mee moet omgaan.
Mijn huidige strategie is afbeeldingen bijhouden in een `image` tabel, met de kolommen `path`, `width`, `height`, `sizeName` en `mimeType`. `sizeName` bevat een door de configuratie bepaalde naam als "small", "medium" en "large". De redenering hierachter is dat ik een geuploade afbeelding in meerdere groottes wil bewaren, zoals de `product` tabel die een many-to-many relatie (`product_has_image`) met de `image` tabel heeft.
Met deze strategie heb ik een aantal problemen. Het eerste probleem is dat niet elke afbeelding per se een `sizeName` nodig heeft omdat sommige afbeeldingen slechts 1 grootte hebben (het bewaren van de oorspronkelijk geuploade afbeelding bijvoorbeeld, als je later andere groottes wilt genereren). Misschien de `sizeName` kolom verwijderen en plaatsen binnen de associatie tabel `product_has_image` en een unique index op combinatie `product_id` en `size_name` zetten?
Een andere vraag die ik me stel is hoe ik best omga met het indelen en verwijderen van bestanden. Een mogelijk idee voor de indeling is elk bestand een unieke naam geven in hex notatie, en deze verdelen over 2 niveaus van directories om te vermijden dat deze directories te groot worden (filesystem performance). Bijvoorbeeld bestand `4a5e4f5610c24f5a41d53aa1e1213cb2.jpg` gaat in directory `4a/5e/4a5e4f5610c24f5a41d53aa1e1213cb2.jpg` waarbij de eerste 2 en de volgende 2 karakters gebruikt worden als directories. Dit zou de afbeeldingen maximaal spreiden over 16^4 directories.
Het synchroniseren van de bestanden met de `image` tabel lijkt me een moeilijkere kwestie. Wat ik wil vermijden is dat bij het verwijderen van een record uit de `image` tabel het bestand achterblijft wegens een databasefout. Dit geldt ook voor een fout bij het inserten van een `image` record waar de bij afbeelding "referentieloos" achterblijft.
De oplossing voor het opslaan van een bestand lijkt me relatief eenvoudig; maak het opslaan deel van de database transactie en verwijder het bestand bij de rollback indien er een fout optreedt. Het verwijderen lijkt me iets ingewikkelder. Ik zou binnen de transactie eerst het bestand kunnen verwijderen zodat het nooit zonder referentie achterblijft bij een databasefout tijdens het verwijderen van een `image` record. Dit betekent wel dat ik bij een fout het bestand "magisch" terug tot leven moet roepen.
Tot slot stel ik me de vraag hoe ik met lege directories van verwijderde bestanden moet omgaan. Aangezien de bestanden hoogswaarschijnlijk in de cloud (s3) opgeslagen zullen worden, lijkt het me niet zo verstandig na elke verwijdering van een bestand de directory tree en zijn de inhoud af te lopen om te checken of ze leeg zijn. Ik neem aan dat de lege directories achterlaten weinig problemen veroorzaakt?
-----------
Ik geef bij veel van mijn probleemstellingen waarschijnlijk reeds zelf het antwoord, maar ik zou voornamelijk gewoon wat feedback willen of ik op het juiste denkpad zit en waar er plaats is voor verbetering
. Bedankt!
Mijn huidige strategie is afbeeldingen bijhouden in een `image` tabel, met de kolommen `path`, `width`, `height`, `sizeName` en `mimeType`. `sizeName` bevat een door de configuratie bepaalde naam als "small", "medium" en "large". De redenering hierachter is dat ik een geuploade afbeelding in meerdere groottes wil bewaren, zoals de `product` tabel die een many-to-many relatie (`product_has_image`) met de `image` tabel heeft.
Met deze strategie heb ik een aantal problemen. Het eerste probleem is dat niet elke afbeelding per se een `sizeName` nodig heeft omdat sommige afbeeldingen slechts 1 grootte hebben (het bewaren van de oorspronkelijk geuploade afbeelding bijvoorbeeld, als je later andere groottes wilt genereren). Misschien de `sizeName` kolom verwijderen en plaatsen binnen de associatie tabel `product_has_image` en een unique index op combinatie `product_id` en `size_name` zetten?
Een andere vraag die ik me stel is hoe ik best omga met het indelen en verwijderen van bestanden. Een mogelijk idee voor de indeling is elk bestand een unieke naam geven in hex notatie, en deze verdelen over 2 niveaus van directories om te vermijden dat deze directories te groot worden (filesystem performance). Bijvoorbeeld bestand `4a5e4f5610c24f5a41d53aa1e1213cb2.jpg` gaat in directory `4a/5e/4a5e4f5610c24f5a41d53aa1e1213cb2.jpg` waarbij de eerste 2 en de volgende 2 karakters gebruikt worden als directories. Dit zou de afbeeldingen maximaal spreiden over 16^4 directories.
Het synchroniseren van de bestanden met de `image` tabel lijkt me een moeilijkere kwestie. Wat ik wil vermijden is dat bij het verwijderen van een record uit de `image` tabel het bestand achterblijft wegens een databasefout. Dit geldt ook voor een fout bij het inserten van een `image` record waar de bij afbeelding "referentieloos" achterblijft.
De oplossing voor het opslaan van een bestand lijkt me relatief eenvoudig; maak het opslaan deel van de database transactie en verwijder het bestand bij de rollback indien er een fout optreedt. Het verwijderen lijkt me iets ingewikkelder. Ik zou binnen de transactie eerst het bestand kunnen verwijderen zodat het nooit zonder referentie achterblijft bij een databasefout tijdens het verwijderen van een `image` record. Dit betekent wel dat ik bij een fout het bestand "magisch" terug tot leven moet roepen.
Tot slot stel ik me de vraag hoe ik met lege directories van verwijderde bestanden moet omgaan. Aangezien de bestanden hoogswaarschijnlijk in de cloud (s3) opgeslagen zullen worden, lijkt het me niet zo verstandig na elke verwijdering van een bestand de directory tree en zijn de inhoud af te lopen om te checken of ze leeg zijn. Ik neem aan dat de lege directories achterlaten weinig problemen veroorzaakt?
-----------
Ik geef bij veel van mijn probleemstellingen waarschijnlijk reeds zelf het antwoord, maar ik zou voornamelijk gewoon wat feedback willen of ik op het juiste denkpad zit en waar er plaats is voor verbetering