Ik ben momenteel bezig aan applicatie in PHP / MySQL waarbij er grote hoeveelheden documenten opgeslagen worden die, afhankelijk van het type document, een afwijkende structuur hebben.
Deze documenten kunnen door de gebruiker gefilterd / doorzocht worden en op basis hiervan worden er allerlei metrics en views gegenereerd.
De hoofd table bevat alle basisvelden die standaard zijn voor ieder document en per documenttype is er een extra table met een foreign key verwijzing naar de hoofdtable en de specifieke data voor dat
document type. Op het moment kent het systeem 5 verschillende types maar dit kan makkelijk oplopen tot 10 of meer.
voorbeeld :
table : document
-----------------------------------------------------------------------------------------------------------------
| document_id | documenttitle | documenttype_id | publishdate | documentcontent | author |
-----------------------------------------------------------------------------------------------------------------
table : document_twitter
--------------------------------------------------------------------------
| document_id | username | strid | touser | profileimg | geo |
--------------------------------------------------------------------------
Bij het querien van 1 document (of meerdere documenten van1 type) met alle specifieke gegevens en met eventuele condities en joins op andere tabellen is dit een makkelijk en efficient.
Nu ontstaat het probleem als ik grotere datasets wil querien met documenten van meerdere types waarbij alle specifieke data ook geladen moet worden, vaak afhankelijk van condities die ook betrekking kunnen hebben op andere tabellen die gejoined kunnen worden.
Op basis van de huidlge structuur heb ik zelf al een paar oplossingen bedacht, die allemaal hun pro's en cons hebben :
1 ) per mogelijk document type een LEFT JOIN toevoegen :
+ 1 redelijk simpele query die makkelijk te genereren is
- veel overhead aan columns met null values
- queries worden complexer en trager naarmate er meer types zijn.
2) Een query doen op de hoofdtable, uit de resulterende dataset de document_id's per type opslaan in een array en vervolgens per type de bijhordende rows uit de specifieke tabellen querien met een WHERE document_id IN condition :
+ geen overbodige columns;
- afhankelijk van de hoeveelheid types, meer queries
- meer parsen
3) per type een query uitvoeren met 1 join op de table die de specifiele data bevat
+ geen overhead aan data / columns
- meer queries
- meer parsen
Eigenlijk vind ik alle drie deze oplossingen niet echt mooi of efficient en gezien de hoeveelheid data en de hoeveelheid verschillende views / metrics die gegenereerd worden per scherm (soort dashboard achtige omgeving) met daarbovenop een aantal filtermogelijkheden.
Ik heb ook al gedacht aan een structuur waarbij alle specifieke data als serialized array/object in een column of losse table gepropt wordt, wat niet mijn voorkeur heeft omdat je dan condities op die specifieke data niet mogelijk is.
Ook heb ik gedacht om over te stappen naar MongoDb of een andere document based database maar dit zou toch aardig wat refactoring betekenen en omdat ik hier nog niet zoveel kennis van heb ook heel wat tijd kosten om me hier goed in te verdiepen.
Dus ... mijn vragen zijn eigenlijk :
- Hoe zouden jullie dit oplossen ?
- Zie ik mogelijkheden over het hoofd ?
Deze documenten kunnen door de gebruiker gefilterd / doorzocht worden en op basis hiervan worden er allerlei metrics en views gegenereerd.
De hoofd table bevat alle basisvelden die standaard zijn voor ieder document en per documenttype is er een extra table met een foreign key verwijzing naar de hoofdtable en de specifieke data voor dat
document type. Op het moment kent het systeem 5 verschillende types maar dit kan makkelijk oplopen tot 10 of meer.
voorbeeld :
table : document
-----------------------------------------------------------------------------------------------------------------
| document_id | documenttitle | documenttype_id | publishdate | documentcontent | author |
-----------------------------------------------------------------------------------------------------------------
table : document_twitter
--------------------------------------------------------------------------
| document_id | username | strid | touser | profileimg | geo |
--------------------------------------------------------------------------
Bij het querien van 1 document (of meerdere documenten van1 type) met alle specifieke gegevens en met eventuele condities en joins op andere tabellen is dit een makkelijk en efficient.
Nu ontstaat het probleem als ik grotere datasets wil querien met documenten van meerdere types waarbij alle specifieke data ook geladen moet worden, vaak afhankelijk van condities die ook betrekking kunnen hebben op andere tabellen die gejoined kunnen worden.
Op basis van de huidlge structuur heb ik zelf al een paar oplossingen bedacht, die allemaal hun pro's en cons hebben :
1 ) per mogelijk document type een LEFT JOIN toevoegen :
+ 1 redelijk simpele query die makkelijk te genereren is
- veel overhead aan columns met null values
- queries worden complexer en trager naarmate er meer types zijn.
2) Een query doen op de hoofdtable, uit de resulterende dataset de document_id's per type opslaan in een array en vervolgens per type de bijhordende rows uit de specifieke tabellen querien met een WHERE document_id IN condition :
+ geen overbodige columns;
- afhankelijk van de hoeveelheid types, meer queries
- meer parsen
3) per type een query uitvoeren met 1 join op de table die de specifiele data bevat
+ geen overhead aan data / columns
- meer queries
- meer parsen
Eigenlijk vind ik alle drie deze oplossingen niet echt mooi of efficient en gezien de hoeveelheid data en de hoeveelheid verschillende views / metrics die gegenereerd worden per scherm (soort dashboard achtige omgeving) met daarbovenop een aantal filtermogelijkheden.
Ik heb ook al gedacht aan een structuur waarbij alle specifieke data als serialized array/object in een column of losse table gepropt wordt, wat niet mijn voorkeur heeft omdat je dan condities op die specifieke data niet mogelijk is.
Ook heb ik gedacht om over te stappen naar MongoDb of een andere document based database maar dit zou toch aardig wat refactoring betekenen en omdat ik hier nog niet zoveel kennis van heb ook heel wat tijd kosten om me hier goed in te verdiepen.
Dus ... mijn vragen zijn eigenlijk :
- Hoe zouden jullie dit oplossen ?
- Zie ik mogelijkheden over het hoofd ?