[ALG] Hoe implementeer ik een mappen-systeem?

Pagina: 1
Acties:
  • 463 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Tot nu toe bevat maakt mijn cms twee folders aan: "image" en "documents". Gebruikers kunnen plaatjes en andere bestanden uploaden. Deze komen vervolgens allemaal in de respectievelijke folder terecht.

Het probleem is nu dat het slecht navigeren is door de bestanden of plaatjes omdat je geen aparte submappen kunt aanmaken. Alles wordt in 1 folder geplempt. Dat wil ik nu gaan veranderen: ik wil gebruikers de mogelijkheid geven om submappen aan te maken in de image- en documents mappen. Ik vraag me alleen af hoe je dat het beste kunt implementeren. Zoals ik het zie zijn er drie mogelijkheden:
  • maak de submappen fysiek op de harde schijf aan
  • sla de plaatjes en andere bestanden niet meer op in een folder, maar in de database. Creer in die tabel een extra kolommen waarin staat in welke (virtuele) map het bestand zit. Een fysieke mappenstructuur bestaat niet; deze wordt bijgehouden in een parent-child tabel
  • een combinatie van beide: sla de bestanden niet in de database maar fysiek in de image of documents map op. Maak voor elk bestand in een database tabel een record aan waar staat in welke "map" het bestand zit. Ook hier hou je de "virtuele" mappen bij in bijvoorbeeld een parent-child tabel
Hebben jullie ervaring hiermee? Ik zou zeggen dat de eerste mogelijkheid het meest voor de hand ligt, maar ik zie ook voordelen in manier 2 en 3: stel dat de gebruiker een (groot) aantal bestanden naar een andere submap wil verplaatsen, dan moet je bij manier 1 al die bestanden daadwerkelijk ergens anders op de harde schijf gaan neerplempen. Bij manier 2 en 3 hoef je in de database alleen de naam van de map aan te passen. Zo'n query is denk ik veel sneller / efficienter. Wat is jullie mening?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Ik zou voor optie 3 gaan. Bestanden in databases zijn niet zo handig, vooral niet bij migraties. Het gewoon kopieren van de bestanden gaat veel sneller dan dmv. de database.
Fysiek submappen aanmaken lijkt me weer lastig coden en introduceerd ook extra veiligheids risico's als je niet extra voorzichtig bent. Vooral met mapnamen zoals "../../../etc/passwd".

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 21:37

mulder

ik spuug op het trottoir

ik zou niet te moeilijk doen en optie 1 gaan. Bestanden sowieso niet opslaan in database, daar staan ze toch eigenlijk al in? ;)

oogjes open, snaveltjes dicht


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Optie 3 vind ik het makkelijkst, omdat je dan ( mits goed afgevangen in geval van editten ) voor elke user in een eigen map een bestand kunt hebben staan, terwijl dit op schijf maar 1 bestand is.

Ik gebruik over het algemeen gewoon een specifieke code als naam van het bestand ( md5 + laatste tijd en datum van opslaan ) en zet dan in de dbase ook nog eens de filenaam. In mijn cms verwijst alles naar de dbase lokatie, en met een diff op nieuwe bestanden die wekelijks gebeurt voorkom ik zelfs dat nieuwe bestanden dubbel op de schijf terecht komen ( indien dubbel verwijder dan bestand b en verander in de dbase de verwijzing van b naar a ). Volgens de dbase heb ik op dit moment bij de grootste installatie 1 Tb opgeslagen terwijl ik op schijf maar 600Gb heb opgeslagen. 400Gb zou anders dubbel opgeslagen zijn.

Dit systeem werkt heel erg goed mits je weet dat er een x percentage dubbele bestanden komen, of als je denkt dat mensen veel bestanden onder dezelfde naamgeving willen opslaan. ( Vb. ik heb het meegemaakt dat mensen gewoon een maandelijkse actiekrant hebben en dan elke keer het bestand "Actiekrant.pdf" uploaden )

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Reveller schreef op dinsdag 07 juni 2005 @ 18:25:
stel dat de gebruiker een (groot) aantal bestanden naar een andere submap wil verplaatsen, dan moet je bij manier 1 al die bestanden daadwerkelijk ergens anders op de harde schijf gaan neerplempen.
Als het goed is word alleen de referentie van de folder naar de file aangepast in de filesystem tabel. En worden bestanden dus niet over de harddisk geslingert.

Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Voordeel van optie 3 is dat je de files eventueel op een andere (file)server kan hosten. En ze beveiligen door ze op raid op te slaan. Dat kan met de db natuurlijk ook, maar nu kan je bv. de db op raid 0/1 zetten en de files op raid 5.

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

gegevens in de database en de bestanden zijn net zo belangrijk. Het is dan ook onzinnig om de database op een raid 0 op te slaan. Verlies je je bestanden dan heb je niks aan je database, en verlies je je database dan heb je niks aan je bestanden.

De enige reden om bestanden niet in de database te zetten is (aangenomen) efficientie. Qua veiligheid en zekerheid is het juist handiger om de bestanden zelf wel in de database te zetten. Op dat moment heb je alle gegevens op 1 plek. Backups en beveiliging hoef je dan slechts op 1 onderdeel te doen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

PrisonerOfPain schreef op dinsdag 07 juni 2005 @ 20:02:
Als het goed is word alleen de referentie van de folder naar de file aangepast in de filesystem tabel. En worden bestanden dus niet over de harddisk geslingert.
Dat is gelukkig wel zo, anders zou het maar lang duren om een bestand te verplaatsen :+

Ik gebruik zelf in mijn CMS systeemen altijd methode 3, met wat verschillende opslag methodes:
  • Object gebonde plaatjes: Plaatjes voor de documenten (news, articles, howtos, whatever/etc) in de images dir. bv: "/images/news/$id/$md5.$extentie".
  • Non-Object plaatjes: Deze kan je zelf indelen in een speciale map. Dan krijg je iets als "/images/etc/$md5.$extentie". Hier kan je zelf submappen aanmaken, en een beetje een leuke indeling geven. Dit kan je in mijn CMS systeemen alleen als ik je daartoe rechten gegeven heb. Dus gebruikers / nieuwsposters / etc hebben daar geen toegang tot. Ik als admin kan daar dus wel dingen plaatsen.
Dit kan je dan ook nog uitwerken voor de andere bestandstypes (documenten etc). Ik doe het alleen met plaatjes ;)

Een md5 string voor de bestandsnaam van het plaatje maak ik altijd ongeveer op de volgende manier:
PHP:
1
$md5ding = md5($filename.time().'@##$^@$DGdsasr');
Waar de @##$^@$DGdsasr een extra toevoeging is, dat zorgt er voor dat de gebruiker niet zelf md5's kan gaan raden. Dat door zelf $filename icm een tijd te hashen, wat al aardig moeilijk is, maar "just in case of" ;)

Ik plaats de object-images in submappen binnen ieder apart soort objects (news, etc). Zodat ik zelf ook nog een redelijk overzichtelijk iets heb als ik er via FTP op ga. Ik heb geen zin om 1 vergaarbak van bestanden te hebben.

[ Voor 9% gewijzigd door Verwijderd op 07-06-2005 21:02 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
Ik gebruik zelf een systeem zoals aangegeven onder 3. Alle bestanden staan opgeslagen in een enkele map en in de database staat metadata over de bestanden. De redenen waarvoor ik hiervoor gekozen heb zijn:
1. dat ik meer wilde dan dat eenvoudig in fysieke submappen te implementeren is (versioning, omschrijvingen, etc)
2. bestanden in de database opslaan me geen goed idee leek vanwege de totale bestandsgrootte

edit---
@KingOfDos... Ik zou voor het bepalen van de naam toch een check invoeren of het bestand niet al bestaat. De kans is weliswaar erg klein, maar je weet maar nooit

[ Voor 18% gewijzigd door T-MOB op 07-06-2005 21:05 ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Verwijderd schreef op dinsdag 07 juni 2005 @ 20:58:
Een md5 string voor de bestandsnaam van het plaatje maak ik altijd ongeveer op de volgende manier:
PHP:
1
$md5ding = md5($filename.time().'@##$^@$DGdsasr');
KoD: Heb jij hier niet het risico dat je heel erg snel dubbele md5's hebt omdat je waarde waarover je hash gaat ( bestandsnaam is voor het gemak maar even gelimiteerd op 100 characters, ik ken niet veel mensen die hier serieus overheen gaan ) dus komt een hash over 116 characters niet veel vaker voor dan een hash over de bestandsinhoud zelf. En volgens mij is dit een vrij groot probleem als iemand veel korte namen gebruikt.

Principe van hash is inderdaad dat het over het algemeen ( uit mijn hoofd 2^52 ) uniek is, maar verklein je dit niet enorm door het over de de bestandsnaam +tijd te gaan doen.

Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Janoz schreef op dinsdag 07 juni 2005 @ 20:46:
[...] Verlies je je bestanden dan heb je niks aan je database, en verlies je je database dan heb je niks aan je bestanden.
Daar ben ik het niet mee eens. Natuurlijk is je referentie weg tussen (in database opgeslagen) meta data en de eigenlijkse bestanden, maar de bestanden zelf heb je in ieder geval nog; en dat is voor zover ik weet anders wanneer je database corrupt raakt en je de bestanden in de database opgeslagen had liggen. De kans dat die situatie zich voor doet is dan ook weer niet zo groot, maar ook gezien de reakties tot dusver denk ik dat het meer common is de bestanden niet in de database op te slaan.
Verwijderd schreef op dinsdag 07 juni 2005 @ 20:58:
[...] bv: "/images/news/$id/$md5.$extentie". [...]
Momenteel werkt mijn systeem ook zo: als de gebruiker een plaatje uploadt, wordt deze hernoemd naar md5.extensie. Nadeel vind ik dan alleen dat als je op naam door de plaatjes browsed, deze je helemaal niets meer zeggen. Ik zit eraan te denken om de naam die het plaatje op de lokale computer heeft, over te nemen op de server, met bv. spaties vervangen door _underscores_ en de hele naam lowercase te maken. Dit lijkt me gebruiksvriendelijker. Met md5 namen ben je altijd afhankelijk van thumbnails om te zien wat het plaatje nu eigenlijk is. Nadeel van de naam overnemen is natuurlijk wel dat de gebruiker vaak geprompt zal worden met een soort van "er bestaat al een plaatje met deze naam op de server" boodschap. Dat is dan ook weer niet gebruiksvriendelijk. Welke methode heeft jullie voorkeur en waarom?
T-MOB schreef op dinsdag 07 juni 2005 @ 20:59:
Ik gebruik zelf een systeem zoals aangegeven onder 3. Alle bestanden staan opgeslagen in een enkele map en in de database staat metadata over de bestanden. De redenen waarvoor ik hiervoor gekozen heb zijn:
1. dat ik meer wilde dan dat eenvoudig in fysieke submappen te implementeren is (versioning, omschrijvingen, etc)
[...]
Dus als ik het goed begrijp kan een gebruiker bij jou submappen aanmaken en daar plaatjes in stoppen? En deze mappen bestaan niet op de server, maar slechts in een database tabel?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
Reveller schreef op dinsdag 07 juni 2005 @ 22:25:
Dus als ik het goed begrijp kan een gebruiker bij jou submappen aanmaken en daar plaatjes in stoppen? En deze mappen bestaan niet op de server, maar slechts in een database tabel?
Jep, alleen gaat het bij mij niet om een CMS met gebruikers en plaatjes maar om de organisatie van "mijn documenten". Op mijn server staat alleen een directory /webfs/ met een bult md5-hashes zonder extensie.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Reveller schreef op dinsdag 07 juni 2005 @ 22:25:
Momenteel werkt mijn systeem ook zo: als de gebruiker een plaatje uploadt, wordt deze hernoemd naar md5.extensie. Nadeel vind ik dan alleen dat als je op naam door de plaatjes browsed, deze je helemaal niets meer zeggen. Ik zit eraan te denken om de naam die het plaatje op de lokale computer heeft, over te nemen op de server, met bv. spaties vervangen door _underscores_ en de hele naam lowercase te maken. Dit lijkt me gebruiksvriendelijker. Met md5 namen ben je altijd afhankelijk van thumbnails om te zien wat het plaatje nu eigenlijk is. Nadeel van de naam overnemen is natuurlijk wel dat de gebruiker vaak geprompt zal worden met een soort van "er bestaat al een plaatje met deze naam op de server" boodschap. Dat is dan ook weer niet gebruiksvriendelijk. Welke methode heeft jullie voorkeur en waarom?
In het door mij geschreven systeem loop ik hier ook tegen aan. De images met MD5 hashes zeggen mij weinig. Dit heb ik opgelost door de images aan een album te koppelen. Deze album bestaan niet als fysieke folder op schijf maar alleen in de db.

Per album weet ik dus nu welke plaatjes erbij horen. Om het verwijderen makkelijker te maken heeft de admin een delete knopje per album en per foto.

Dit systeem werkt dus heel goed aangezien de filenaam er niet meer toe doet omdat je kunt zien wat je verwijderd en of bewerkt middels de thumbnail of de grote foto.

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Reveller schreef op dinsdag 07 juni 2005 @ 22:25:
Daar ben ik het niet mee eens. Natuurlijk is je referentie weg tussen (in database opgeslagen) meta data en de eigenlijkse bestanden, maar de bestanden zelf heb je in ieder geval nog; en dat is voor zover ik weet anders wanneer je database corrupt raakt en je de bestanden in de database opgeslagen had liggen. De kans dat die situatie zich voor doet is dan ook weer niet zo groot, maar ook gezien de reakties tot dusver denk ik dat het meer common is de bestanden niet in de database op te slaan.
Aan een lijst van enkele duizenden bestanden met als naam md5($rand).$extentie heb je natuurlijk enorm weinig. Credo blijft altijd backups maken.

Het toverwoord is integriteit. Je hebt alle gegevens bij elkaar en een backup draai je simpel uit de database. Je hoeft niet 2 backups van verschillende systemen te maken die vervolgens ook nog afhankelijk van elkaar zijn. (Stel tussen het backuppen van de bestanden en de database voegt een gebruiker een bestand toe. Het bestand zit wel in de backup, maar de metadata niet. De backup is op dat moment niet meer integer). Daarnaast zorgt het opslaan van alle content op 1 plek ervoor dat de verschillende onderdelen van je site/(web)applicatie duidelijk gescheiden zijn. Alle logica staat in bestanden, alle vormgeving staat in bestanden en alle content staat in de db. Vormgeving en logica sla je over het algemeen op in je versie beher systeem. Om ergens je applicatie te deployen hoef je enkel nog maar de logica en vormgeving er neer te zetten en de database bereikbaar te maken. Je hoeft niet een speciaal mapje aan te maken met world schrijfrechten en de locatie van dit mapje in allerlei config bestandjes op te nemen.

Dat de reacties tot nu toe vooral neigen naar optie drie komt meer omdat het common is in de php/mysql (hobby-)wereld. Daar wordt meestal de nadruk op snel ontwikkelen en efficient draaien gelegd ipv efficient onderhoud en SLA´s.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 21:37

mulder

ik spuug op het trottoir

Alle bestanden staan opgeslagen in een enkele map
Dit gaat problemen overleveren? Teveel bestanden in 1 map is volgens mij niet echt aan te raden.

oogjes open, snaveltjes dicht


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
Don Facundo schreef op woensdag 08 juni 2005 @ 09:35:
[...]
Dit gaat problemen overleveren? Teveel bestanden in 1 map is volgens mij niet echt aan te raden.
Als je er handmatig niets in hoeft te zoeken maakt het niet zoveel uit. Zie ACM in: MySql en veel BLOB data.

Over het opslaan van plaatjes in een database zijn trouwens nog veel meer topics te vinden. Een redelijk recente is [PHP] plaatje uit mysql database. Bottom-line is meestal dat het (enige) voordeel van de database-opslag ligt in wat Janoz hier ook al aangeeft: backups en integriteit daarvan.
Het nadeel van database-opslag is de snelheid. Volgens een benchmark van ACM (zie eerste link) duurt het invoegen van data in de DB minimaal 10x zo lang als het opslaan in het FS. Wat betreft het ophalen van de data scheelt het ongeveer een factor 4.5 in het voordeel van het FS. In geval van MySQL that is... Een ander DBMS kan het allicht sneller.

Wat dan het beste is lijkt me af te hangen van de waarschijnlijkheid van integriteitsissues. In een CMS dat door slechts weinig users gebruikt gaat worden heb je daar weinig last van. Eventueel blokkeer je het toevoegen van bestanden op het moment dat er een backup gedraait wordt. Op een profielensite met duizenden bezoekers die plaatjes kunnen toevoegen ligt dat ietsje anders.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

Janoz schreef op woensdag 08 juni 2005 @ 09:34:
[...]
Dat de reacties tot nu toe vooral neigen naar optie drie komt meer omdat het common is in de php/mysql (hobby-)wereld. Daar wordt meestal de nadruk op snel ontwikkelen en efficient draaien gelegd ipv efficient onderhoud en SLA´s.
Helemaal mee eens, voor mijn eiegn hobby project (PHP/MySQL) maak ik dus gebruik van optie drie (virtueel FS met meta dat in DB en files in map op server) op mijn werk maken we echter gebruik van de DB(BLOB) om bestanden op te slaan. Dus de files worden direct in de DB geladen. Nu werken we op mijn werk ook met Oracle 8 en 9 en MS SQL server. Deze hebben als voordeel dat je bepaalde tabellen naar andere tablespaces kan laten verwijzen. Zeker als er veel grote bestanden in komen te staan is het wel eens noodzakelijk om tablespaces te scheiden en dat kan nu vrij eenvoudig. De files worden in een aparte objecten tabel opgeslagen welke via FK is gelinkt aan de hoofdentiteit. Dus de basis data kan heel snel worden opgehaald en pas bij het opvragen van de objecten wordt de objecten tabel aangesproken.

Daarnaast kan je met een backup van de database en een clean install binnen no time weer een draaiende applicatie opleveren. En het gaat hier dus gewoon om een advanced web applicatie. Voordeel voor de beheer organisatie is dat ze precies weten wat ze moeten backupen en dat dit over het algemeen al redelijk tot goed geregeld is in de beheer organisatie. Als je te maken hebt met een simple hoster is het wel eens lastig als je grote databases wil aanmaken. Als je een behoorlijke grote hoeveelheid files hebt groeit je DB aardig snel.

Voor een simpel CMS je heb je enkele tabellen met hier en daar wat data(tekst). Stel dat je uiteindelijk een pagina of 1000 aan teksten hebt zal je niet snel boven de 10MB aan ruimte innemen. Maar wil je bijvoorbeeld 1000 foto's opslaan heb je al snel 60 MB aan harddisk space nodig. Dit zal in je database nog wat groter worden van wege overhead ect.

buit is binnen sukkel


Acties:
  • 0 Henk 'm!

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 21:37

mulder

ik spuug op het trottoir

En daar is zijn conclusie:
Owja, de conclusie:
Een goed fs op een goed os kan makkelijk meer dan 400.000 files aan, als je het maar netjes in dirs organiseert.
;)

oogjes open, snaveltjes dicht


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Ik zou de boel niet gaan combineren, eigenlijk. Bestanden opslaan in een database is geen ramp, daar zijn tenslotte BLOBs voor, alleen moet je back-ups wel anders maken dan met dumps is SQL-script formaat. Bovendien kan het serven van data uit de database wel iets minder efficient zijn, omdat de boel via sockets en via PHP verstuurd moet worden, wat een stuk meer overhead is dan Apache heeft bij het serveren van statische bestanden. Daar staat wel tegenover dat je met de database alles onder controle hebt.

De bestandsmethode zie ik ook wel werken (met mappen als directories in het bestandssysteem). HTMLArea gebruikt bijvoorbeeld deze aanpak, dus heel onzinnig is het niet. Groot nadeel is altijd dat je er geen metadata bij kunt opslaan (rechten, omschrijvingen, etcetera) en het is natuurlijk altijd gepruts met permissies op de directory waarin geschreven wordt (vooral in shared hosting omgevingen kan dat vervelend zijn).

Qua onderhoud en migratie lijkt de databasegebaseerde oplossing me het makkelijkste, want je hoeft dan alleen de database up to date te houden. De twee combineren lijkt me een hoop onderhoudsproblemen geven zonder dat er duidelijke voordelen tegenover staan.

[ Voor 6% gewijzigd door Soultaker op 08-06-2005 13:40 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
Hmm, daar had ik overheen gelezen. Een benchmarkje die alles in 1 dir gooit laat idd zien dat de performance achteruitholt met een groot aantal bestanden in één map:
Doing files 0-9999      Took: 25.275 s
Doing files 10000-19999 Took: 68.832 s
Doing files 20000-29999 Took: 121.514 s
Doing files 30000-39999 Took: 177.192 s

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Hoe heb je dat getest? ACM komt namelijk tot de conclusie dat het níét veel uitmaakt.

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:34
Soultaker schreef op woensdag 08 juni 2005 @ 14:46:
Hoe heb je dat getest? ACM komt namelijk tot de conclusie dat het níét veel uitmaakt.
ACM gebruikt dan ook een submap voor elke 1000 files (vandaar ook de conclusie die hierboven al werd aangehaald). De test in een enkele map zag er btw zo uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
function getmicrotime() {
    list($usec, $sec) = explode(" ",microtime());
    return ((float)$usec + (float)$sec);
}
      
for($i = 0; $i < 100; $i++) {
    set_time_limit(180);    

    echo 'Doing files'  .$i .'0000';
    flush();                
    $start = getmicrotime();
    
    for($j = 0; $j < 10000; $j++) {
     touch('fs/' .$i .'-' .$j);
    }    
    $end = getmicrotime();
    echo " Took: " . number_format(($end - $start), 3) . " s \n<br>";
}
?>

Getest op een PIII500 met een ext3 filesystem. (deze poogt tot 1 miljoen files te gaan, rond de 45.000 kreeg ik echter al een time-out ;) )

[ Voor 7% gewijzigd door T-MOB op 08-06-2005 14:55 ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Met UFS (FreeBSD 5.3) heb ik daar geen last van:
code:
1
2
3
4
5
6
7
8
9
10
11
12
Doing files 00000-09999  Took: 11.295 s
Doing files 10000-19999  Took: 12.718 s
Doing files 20000-29999  Took: 12.617 s
Doing files 30000-39999  Took: 12.312 s
Doing files 40000-49999  Took: 12.777 s
Doing files 50000-59999  Took: 12.614 s
Doing files 60000-69999  Took: 13.473 s
Doing files 70000-79999  Took: 12.198 s
Doing files 80000-89999  Took: 12.607 s
Doing files 90000-99999  Took: 13.104 s
Doing files 100000-109999 Took: 13.759 s
Doing files 110000-119999 Took: 12.522 s

... enzovoorts. De tijd blijft netjes rond de 12,5 seconde schommelen. Het is dus zeker geen universeel probleem en onder BSD hoef je het er dus niet om te laten.

Acties:
  • 0 Henk 'm!

  • Wacky
  • Registratie: Januari 2000
  • Laatst online: 05-09 21:19

Wacky

Dr. Lektroluv \o/

T-MOB schreef op woensdag 08 juni 2005 @ 14:54:
[...]

ACM gebruikt dan ook een submap voor elke 1000 files (vandaar ook de conclusie die hierboven al werd aangehaald). De test in een enkele map zag er btw zo uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
function getmicrotime() {
    list($usec, $sec) = explode(" ",microtime());
    return ((float)$usec + (float)$sec);
}
      
for($i = 0; $i < 100; $i++) {
    set_time_limit(180);    

    echo 'Doing files'  .$i .'0000';
    flush();                
    $start = getmicrotime();
    
    for($j = 0; $j < 10000; $j++) {
     touch('fs/' .$i .'-' .$j);
    }    
    $end = getmicrotime();
    echo " Took: " . number_format(($end - $start), 3) . " s \n<br>";
}
?>

Getest op een PIII500 met een ext3 filesystem. (deze poogt tot 1 miljoen files te gaan, rond de 45.000 kreeg ik echter al een time-out ;) )
Die time-out zegt niks meer als dat het uitvoeren van het script langer dan bijv. 30 seconden duurde ;)

[ Voor 7% gewijzigd door Wacky op 08-06-2005 15:40 ]

Nu ook met Flickr account


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

EXT3 is ook een gaar filesysteem.

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik moet zeggen dat ik ten tijde van de topic start erg neigde naar methode 3: bestanden op filesystem en meta data in database. Maar na het lezen van de reakties tot nu toe wordt ook de optie om alles in een database op te slaan wel aantrekkelijk. Ik kom terug op mijn commentaar op Janoz; de integriteit van alles in de dbase opslaan heeft toch wel een groot voordeel. Ik hoop een een voortzetting van deze discussie; ik heb al een hoop extra info waar ik anders pas later over zou zijn gaan nadenken zoals benchmarks.

Wel een vraag die nu in me opkomt: hoe zit je eigenlijk met je mysql backups? Ik heb nooit een grotere backup gedraaid dan van een database van 10 mb ofzo. Als je een 100-tal bestanden in een database opslaat, hoe stabiel kun je dan een backup draaien? En hoe snel is zo'n backup terug te zetten? Heeft iemand hier meer info over? Intussen ga ik eens op Google kijken...

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Pas wel op dat je database server een goede verbinding (zelfde machine?) heeft met je webserver. Alles wat je ophaalt uit je database moet over een lijn naar je webserver. Sommige hosts doen daar moeilijk over als jij gigantische hoeveelheden raw data (of recordsets met slechte queries) van database naar webserver gaat pompen.

Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Het is slechts een klein cms; in eerste instantie voor mezelf en daarna wellicht voor de school waar ik werk. In principe zullen de web- en database server altijd op dezelfde machine staan. De omvang van de hoeveelheid data zal dus beperkt zijn; uiteindelijk maximaal enkele honderden documenten en afbeeldingen. Vandaar dat ik telkens meer gecharmeerd raak van de bestanden in dbase oplossing, om de integriteit te behouden.

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Reveller schreef op woensdag 08 juni 2005 @ 17:27:
Wel een vraag die nu in me opkomt: hoe zit je eigenlijk met je mysql backups? Ik heb nooit een grotere backup gedraaid dan van een database van 10 mb ofzo. Als je een 100-tal bestanden in een database opslaat, hoe stabiel kun je dan een backup draaien? En hoe snel is zo'n backup terug te zetten? Heeft iemand hier meer info over? Intussen ga ik eens op Google kijken...
Je kunt gewoon de tables locken en flushen, dan de database files kopiëren, en dan weer unlocken. Dat werkt natuurlijk alleen als je de back-ups gebruikt om dezelfde server te herstellen; niet als je migreert naar een andere server versie, denk ik.

Verder is er ook een tooltje "mysqlhotcopy" dat back-ups kan maken en er zijn externe programma's voor, zoals mysqlsnapshot.

Mogelijkheden zat dus. Als het niet erg is dat (schrijvende!) transacties even moeten wachten zou ik gewoon de eerste methode gebruiken (simpel en effectief). Anders kun je een van de andere methoden gebruiken. Ook kan MySQL tegenwoordig incrementele back-ups maken, zodat je niet alle tabellen hoeft te locken, maar hoe dat precies werkt zoek je zelf maar in de manual op. ;)

Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik denk erover om het volgende systeem te maken:
  • plaatjes worden in de images/ map opgeslagen op het FS
  • de gebruiker kan fysieke submappen aanmaken in de images/ map
  • meta info wordt gewaard in de database, de koppeling vind plaats dmv bestandsnaam van het plaatje
Als een gebruiker een plaatje uploadt, kan ik twee dingen doen:
  • het plaatje op de server dezelfde naam geven als het op de lokale pc van de gebruiker heeft
  • het plaatje hernoemen naar een unieke naam, bv. met behulp van md5 hash icm random getal
Het voordeel van de md5 hash is dat je de user theoretisch nooit hoeft te prompten "plaatje bestaat al op de server". Bovendien is het wel zo netjes: elk plaatje heeft een naam van 32 karakters :) Het nadeel is dat de naam van het plaatje geen enkele info meer geeft over het plaatje zelf. In principe hoeft dat geen probleem te zijn, omdat de gebruiker via een de wysiwyg editor plaatjes kiest via een thumbnail popup. Nadelig is wel als iemand in het geval iemand een template voor de site aan het ontwerpen is en bv. < img src="images/template/432lkj45klj6kl43h64kj3l4364.gif"> ipv < img src="images/template/logo.gif"> moet tikken. Graag jullie mening hierover. Hoe werkt het bij jullie cms? Een voordeel van plaatjes in een database is dat je ontzettend goed rechten kunt regelen, maar dat vind ik niet zo belangrijk bij plaatjes. Die zijn in principe voor iedereen toegankelijk. En ik zie niet zoveel in een < img src="plaatjes.php?id=8"> constructie. Dit veroorzaakt op een beetje pagina al snel 20 extra queries ofzo. Bovendien vraag ik me af of je je stylesheets dan ook zo gaat doen?

code:
1
2
3
#body {
  background: url(plaatjes.php?id=31);
}

Dat heb ik eerlijk gezegd nog nooit ergens gezien. Je zou natuurlijk mbv mod_rewrite een src="plaatjes/31.gif" kunnen omzetten naar plaatjes.php?id=31.gif; ik weet niet hoeveel sites op de achtergrond hier gebruik van maken. Voor mijn documenten beheer (.doc, .xls, etc) wil ik wel met bestanden in de database werken, omdat je daar wel de (download-)rechten per gebruikersgroep van wilt kunnen bepalen. En dat gaat veel minder goed / makkelijk als je ze in een fysieke folder zet, volgens mij. Graag hoor ik jullie ervaringen met plaatjes- en documentenbeheer. Hoe benoem jij je plaatjes? Geef jij de gebruiker de mogelijkheid op het aanmaken van fysieke subfolders of dump je alles in 1 folder (wat al snel onoverzichtelijk wordt denk ik)?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Jrz
  • Registratie: Mei 2000
  • Laatst online: 23:54

Jrz

––––––––––––

Ik zou bestanden apart opslaan van de db.
maakt backuppen, en tooltjes gebruiken een stuk handiger.
Die bestanden zijn archief, die veranderen bijna nooit.

Als je je database gebackupped, is die vaak wel veranderd.
Als je AL je files elke backup moet mee backuppen als ze hetzelfde zijn, is dat behoorlijk zonde

Ook zijn de file tools voor files, en niet voor blobs..

Dat over queries, je kan toch gewoon cachen..

[ Voor 22% gewijzigd door Jrz op 05-07-2005 13:54 ]

Ennnnnnnnnn laat losssssssss.... https://github.com/jrz/container-shell (instant container met chroot op current directory)


Acties:
  • 0 Henk 'm!

Verwijderd

Wij zijn nu aan het migreren van een bestanden op HD naar bestanden in DB structuur. De hoofdreden is inderdaad toch gewoon single point of storage. Dit heeft een groot aantal voordelen boven de ' hibride' oplossing van bestanden op de HD en de info in de DB.

1. Consistentie

Alle operaties op bestanden kunnen nu in SQL worden uitgevoerd. Delete, kopieren, alle operaties doen we nu in SQL wat de consistentie en vooral de onderhoudbaarheid van de applicatie ten goede komt.

2. Onafhankelijkheid

Door de volledige handling van de bestanden in de DB af te handelen, zijn we niet meer afhankelijk van het file system, wat weer een hoop zorgen over rechten en pad configuraties bespaart.

Daarnaast kunnen we de bestanden nu ook benaderen met alleen een verbinding naar de database, wat het mogelijk maakt om andere applicaties toegang te geven tot de bestanden, zonder een hoop workarounds om bij de fysieke bestanden op de server te komen.

3. Single point of storage

Dit is altijd handig, vooral als je met backup en replicatie aan de slag moet. Tot nu toe gebruikten we DFS van Windows voor de replicatie van de bestanden en MySQL master/slave replicatie voor de DB, maar dit leidde keer op keer weer tot problemen omdat de replicatie niet 1-op-1 synchroon te krijgen was.

4. Versiebeheer van bestanden

Met de bestanden in de DB was dit eenvoudig te implementeren, terwijl hier met de hybride oplossing de nodige haken en ogen aan zaten.


Daarnaast biedt deze aanpak ons nog een aantal andere (applicatie specifieke) voordelen en maakt het ons mogelijk een aantal tools tegen dit systeem aan te programmeren die met de hybride oplossing op z'n minst lastig te maken zouden zijn.

We maken gebruik van de ingebouwde MySQL file handling functies in combinatie met het cachen van geraadpleegde files op de HD. De enige tradeoff die we dus hebben hoeven maken met dit systeem is een minimale performance vermindering bij het uploaden van bestanden, tegenover een aantal structurele verbeteringen.

Dus mijn voorkeur is wel duidelijk :)

Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

Waarom heb je bij het serveren van een plaatje een database connectie nodig, zeker als je geen rechten wil checken, kan je gewoon passthru() gebruiken. Het probleem in jouw geval is dat je ook fysliek filesystem folders wil hebben. Ik zie in ieder geval niet in waarom je hiervoor een file system folders nodig hebt. Immers heb je al een virtueel filesystem dus is het niet noodzakelijk dat je ook beschikt over een fysieke representatie.

Je probleem met documenten kan je heel snel tackelen. Zorg er gewoon voor dat de gehele images maap niet via apache te bereiken is en haal de files met passthru() op uit een directory buiten je webroot.

Zelf dump ik alle files in een folder. In de databases staan de orginele filename, de nieuw gegeven naam, omschrijving en extra meta data. In het nieuwe systeem wordt het zelfs zo dat de meta data via koppel tabellen wordt gelinkt.

In mijn geval worden de images en data wel uit de database gehaald en worden de thumbnails on the fly gemaakt door PHP/GD. Met het aantal hits/pageview wat er nu is maakt dat op het totaal helemaal niet uit. Voor een website als t.net is dat veel belangrijker.

Verder maak ik duidelijk onderscheid tussen template images en cms images. CMS images zijn onderdeel van de content en worden ook door het CMS heheerd. Voor mijn templates werkt ik net iets anders.

code:
1
2
3
4
5
6
/templates
/templates/<naam>
/templates/<naam>/images
/templates/<naam>/js
/templates/<naam>/css
/templates/<naam>/html

Zo ziet mijn template directory structuur eruit. Elke template heeft zijn eigen template specifieke files. Alle gedeelde code wordt ergens anders opgeslagen. Template images hebben gewoon logisch enamen zoals header.jpg of logo.gif. Hierdoor is het beheer van templates eenvoudig. Het CMS zorgt ervoor dat de content logische benamingen heeft.

buit is binnen sukkel


Acties:
  • 0 Henk 'm!

  • supakeen
  • Registratie: December 2000
  • Laatst online: 09-09 14:42
Mijn idee zou zijn om alles in 1 map te gooien met 32 tekens (+ extensie) filenames gemaakt van je md5 hashes (die wel voor de netheid moeten worden gechecked of ze al bestaan ;) ) en dan de informatie over deze bestanden (original_filename bijvoorbeeld) op te slaan in een database net zoals een virtueel FS.

Daarna kunnen mensen deze bestanden via multiviews met een nette url opgevraagd worden (bijvoorbeeld: [url]http://localhost/getfile.php/sub/dir/original_filename.php[/url])

Zo heb je de opzoeksnelheid van de database, je hebt ook je nette URL's en je zorgt ervoor dat je database backups handelbaar blijven.

De file-directory tarball je (of maak je tot een archive hoe je ook wilt) en stelt deze ter beschikking voor download (hopen dat je een snelle lijn hebt en veel dataverkeer mag hebben :P ) of je schrijft weg naar een andere server of je doet ermee wat je wilt ;)

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
zmn schreef op dinsdag 05 juli 2005 @ 15:27:
[...]
Zo heb je de opzoeksnelheid van de database, je hebt ook je nette URL's en je zorgt ervoor dat je database backups handelbaar blijven. [...]
Je hebt dan voor elke afbeelding een query, en dus een database connectie nodig. Is dat optimaal?

Acties:
  • 0 Henk 'm!

  • supakeen
  • Registratie: December 2000
  • Laatst online: 09-09 14:42
djluc schreef op dinsdag 05 juli 2005 @ 15:38:
[...]
Je hebt dan voor elke afbeelding een query, en dus een database connectie nodig. Is dat optimaal?
Dat heb je ook nodig wanneer je ook de tekens van dat plaatje in de database zet. En waar wil je anders informatie over het plaatje opslaan? In de filename? Of in een textfile?

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Als je een mappenstructuur op de server hebt kan je met 1 query alle afbeeldingen uit de database halen en dan urls als:
/images/jemap/jefile.jpg in de html code plaatsen.

Als je een url als: http://localhost/getfile.php/sub/dir/original_filename.php plaatst moet je allereerst deze uit de database halen, vervolgens moet je elke keer in getfile.php opzoeken welk bestand bij getfile hoort.

Acties:
  • 0 Henk 'm!

  • supakeen
  • Registratie: December 2000
  • Laatst online: 09-09 14:42
djluc schreef op dinsdag 05 juli 2005 @ 16:13:
Als je een mappenstructuur op de server hebt kan je met 1 query alle afbeeldingen uit de database halen en dan urls als:
/images/jemap/jefile.jpg in de html code plaatsen.

Als je een url als: http://localhost/getfile.php/sub/dir/original_filename.php plaatst moet je allereerst deze uit de database halen, vervolgens moet je elke keer in getfile.php opzoeken welk bestand bij getfile hoort.
Dat zie je fout, getfile krijgt een variable mee (original_filename.ext) daarna voert het een query uit op de database en opent het bestand van de correcte locatie. De variabelen daarvoor zijn slechts tussenvariabelen die er niet echt toe doen, je pakt gewoon telkens de laatste variabele uit de request.

Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
zmn schreef op dinsdag 05 juli 2005 @ 17:24:
[...] daarna voert het een query uit [...]
Met andere woorden, hoe licht misschien ook, voer je wel voor elk plaatje een query uit. Dat heb ik liever niet, vandaar dat ik erover zit te denken om de plaatjes op het filesystem te zetten met originele naam, zodat ze direct op te halen zijn zonder tussenkomst van een dbase.

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • CubicQ
  • Registratie: September 1999
  • Laatst online: 20:16
Waarom zou je voor elk plaatje een query moeten uitvoeren? Dit soort meta-informatie is erg makkelijk te cachen.

Verder: MD5 hashes gebruiken voor bestandsnamen vind ik zelf niet zo'n goed idee. Als je een database gebruikt voor de meta-informatie, dan kan je ook gegevens uit die database gebruiken (PK/GUID) om een unieke waarde terug te krijgen om als filenaam te gebruiken. Dan scheelt je dat een boel gedoe met checks of een MD5 hash misschien toch niet hetzelfde is.

Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Verwijderd schreef op dinsdag 05 juli 2005 @ 14:20:
Wij zijn nu aan het migreren van een bestanden op HD naar bestanden in DB structuur. De hoofdreden is inderdaad toch gewoon single point of storage. Dit heeft een groot aantal voordelen boven de ' hibride' oplossing van bestanden op de HD en de info in de DB.
<voordelen>
Dus mijn voorkeur is wel duidelijk :)
Hoe zit het dan precies als je de data naar een andere db wil overzetten? Ik neem aan dat je geen simpele sql dump kunt maken?

Acties:
  • 0 Henk 'm!

  • CubicQ
  • Registratie: September 1999
  • Laatst online: 20:16
Bij de meeste database systemen kan je daarvoor een binaire dump maken.

Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

Reveller schreef op dinsdag 05 juli 2005 @ 19:02:
[...]

Met andere woorden, hoe licht misschien ook, voer je wel voor elk plaatje een query uit. Dat heb ik liever niet, vandaar dat ik erover zit te denken om de plaatjes op het filesystem te zetten met originele naam, zodat ze direct op te halen zijn zonder tussenkomst van een dbase.
Maar waarom implementeer je dan een virtueel mappen systeem in de database als je er helemaal geen gebruik van maakt? Je gaat dan normale systeem mappen en orginele filenames gebruiken. Dus wat is de toegevoegde waarde van het opslaan van alle meta data? Verder kan je met een paar simpele filesystem functie ook een goede backend maken. :? Verder is de overhead op zich ook verwaarloosbaar. Verder is de prijs van server power zo laag dat dat bijna geen issue is. Als je kijkt naar bijvoorbeeld React dan zie je dat er bij elk request al snel 20+ queries worden uitgevoerd. En als ik kijk naar mijn eigen knutsel werk dan zit ik ook aan +/- 10 queries. Een goede select op een primary key kan binnen enkele duizendste van seconden gebeuren en zijn dus niet echt een probleem. :)

buit is binnen sukkel


Acties:
  • 0 Henk 'm!

Verwijderd

-FoX- schreef op dinsdag 05 juli 2005 @ 19:54:
[...]

Hoe zit het dan precies als je de data naar een andere db wil overzetten? Ik neem aan dat je geen simpele sql dump kunt maken?
We maken momenteel gebruik van een 3rd party replicatie tool, maar we zijn nu ook bezig met het opzetten van het ingebouwde MySQL master-slave replicatie systeem. Dit verzorgt het overzetten van de data bij ons, zodat we eenvoudig mirrors kunnen opzetten zonder dat we hier verder naar hoeven om te kijken. Tis wel even sleutelen, maar dan heb je ook wat :)

De data overzetten m.b.v. sql dumps is bij ons zowiezo geen optie omdat we periodiek repliceren naar mirrors op verschillende locaties in de US en Azie en ik pas er voor om dit 's nachts te gaan doen met handmatige dumps ;) Verder zijn dumps om data over te zetten meestal toch al geen goed idee als je gebruik maakt van auto_increment columns...
Pagina: 1