sql >> Database >  >> RDS >> Mysql

Door gebruikers geüploade afbeeldingen efficiënt opslaan in het bestandssysteem

We hebben zo'n systeem in zware productie met 30.000+ bestanden en 20+ GB tot nu toe...

   Column    |            Type             |                        Modifiers                         
-------------+-----------------------------+----------------------------------------------------------
 File_ID     | integer                     | not null default nextval('"ACRM"."File_pseq"'::regclass)
 CreateDate  | timestamp(6) with time zone | not null default now()
 FileName    | character varying(255)      | not null default NULL::character varying
 ContentType | character varying(128)      | not null default NULL::character varying
 Size        | integer                     | not null
 Hash        | character varying(40)       | not null
Indexes:
    "File_pkey" PRIMARY KEY, btree ("File_ID")

De bestanden worden gewoon opgeslagen in een enkele map met het gehele getal File_ID als de naam van het bestand. We zijn meer dan 30.000 zonder problemen. Ik heb zonder problemen hoger getest.

Dit gebruikt RHEL 5 x86_64 met ext3 als bestandssysteem.

Zou ik het nog een keer op deze manier doen? Nee. Laat me een paar gedachten delen over een herontwerp.

  1. De database is nog steeds de "hoofdbron" van informatie over de bestanden.

  2. Elk bestand is sha1() gehasht en opgeslagen in een bestandssysteemhiërarchie op basis van die hash:/FileData/ab/cd/abcd4548293827394723984723432987.jpg

  3. de database is een beetje slimmer in het opslaan van meta-informatie over elk bestand. Het zou een systeem met drie tafels zijn:

    File :slaat informatie op zoals naam, datum, ip, eigenaar en een verwijzing naar een Blob (sha1)
    File_Meta :slaat sleutel/waarde-paren op in het bestand, afhankelijk van het type bestand. Dit kan informatie bevatten zoals Image_Width, enz...
    Blob :slaat een verwijzing op naar de sha1 samen met zijn grootte.

Dit systeem zou de bestandsinhoud dedupliceren door de gegevens op te slaan waarnaar wordt verwezen door een hash (meerdere bestanden kunnen verwijzen naar dezelfde bestandsgegevens). Het zou heel gemakkelijk zijn om een ​​back-up van de bestandsdatabase te maken met rsync.

Ook zouden de beperkingen van een bepaalde map met veel bestanden worden geëlimineerd.

De bestandsextensie zou worden opgeslagen als onderdeel van de unieke bestandshash. Als de hash voor een leeg bestand bijvoorbeeld abcd8765 . is ... Een lege .txt bestand en leeg .php bestand zou verwijzen naar dezelfde hash. Ze zouden eerder moeten verwijzen naar abcd8765.php en abcd8765.txt . Waarom?

Apache, enz.. kan worden geconfigureerd om automatisch het inhoudstype en cachingregels te kiezen op basis van de bestandsextensie. Het is belangrijk om de bestanden op te slaan met een geldige naam en de extensie die overeenkomt met de inhoud van het bestand.

Zie je, dit systeem zou de prestaties echt kunnen verbeteren door de bestandslevering via nginx te delegeren. Zie http://wiki.nginx.org/XSendfile .

Ik hoop dat dit op de een of andere manier helpt. Wees voorzichtig.



  1. Hoe een tabel naar CSV te exporteren met Oracle SQL Developer?

  2. Hoe machtigingen voor externe toegang verlenen aan mysql-server voor gebruikers?

  3. Een SaaS-abonnementsgegevensmodel

  4. Tabelschema bijwerken zonder gegevens in Laravel te beïnvloeden