[db algemeen] variabele relaties

Pagina: 1
Acties:

  • orf
  • Registratie: Augustus 2005
  • Laatst online: 22:14
Zo af en toe loop ik tegen hetzelfde probleem op, waar ik al meerdere keren mijn hoofd over heb gebroken.

Stel ik heb een tabel studenten en een tabel docenten. Deze twee soorten personen zitten in verschillende tabellen omdat er verschillende rechten aan hangen, verschillende persoonsgegevens, etc.

Nu heb ik een tabel chat. Docenten en studenten moeten met elkaar kunnen chatten. Daaronder hangt een tabel chatberichten met een chat_id, het getypte bericht en ....
Een koppeling naar de student of docent. Hoe kun je dat goed koppelen terwijl het om twee tabellen gaat? Ik kan een student_id opnemen en een docent_id, maar dat klinkt nogal ranzig en bij queries is het niet handig.

Iemand een slim idee om dit soort problemen te verhelpen?

Dank!

  • Janoz
  • Registratie: Oktober 2000
  • Nu online

Janoz

Moderator Devschuur®

!litemod

Wat je vaak ziet is dat studenten en docenten in 1 tabel komen. Dit in 1 tabel zetten kun je doen door een superset te nemen (alle velden in die tabel voor docent en student), maar je kunt ook een subset nemen en een soort overerving toepassen. 1 tabel met personen waarin de gegevens staan die je van beiden hebt, en een specifieke tabel studenten en een specifieke tabel docenten. De keuze tussen deze twee wordt ook veel behandeld in OR-mapping discussies (het mappen van Object georienteerde data op relationele data en omgekeerd).

Wat je ook nog zou kunnen doen is gebruik maken van een personen view. Deze view bestaat uit een union tussen docenten en studenten. Het enige probleem is het ID, maar je zou hier eventueel een gecombineerde PK van kunnen maken (het specifieke ID samen met het type) of een nieuwe PK introduceren (een apparte koppeltabel).

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


  • orf
  • Registratie: Augustus 2005
  • Laatst online: 22:14
Als je studenten en docenten in 1 tabel zit; hoe bepaal je dan wat iemand is? Je kunt dat natuurlijk opslaan in een kolom; maar dan moet je op basis van die waarde de gegevens erbij zoeken in de studententabel óf de docententabel.

Dat 'op basis van een waarde' steekt me; je kunt geen mooie query schrijven die ineens resultaten ophaalt. Voor veruit de meeste functionaliteiten (vakken / huiswerk / rechten) is het handig dat docenten en studenten in verschillende tabellen zitten, maar voor enkele (mededelingen, algemene agenda, chat) is het juist niet handig.

Bedankt voor je reactie :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
orf schreef op donderdag 14 juni 2007 @ 14:41:
Als je studenten en docenten in 1 tabel zit; hoe bepaal je dan wat iemand is?
Discriminator veld
Je kunt dat natuurlijk opslaan in een kolom; maar dan moet je op basis van die waarde de gegevens erbij zoeken in de studententabel óf de docententabel.
Idd. Of in dezelfde tabel. Laat ons zeggen dat er 3 aanpakken zijn voor dit probleem:
• Table per Concrete Class
• Table per class hierarchy
• Table per subclass

Even googlen op deze termen zou -denk ik- je toch wel wat leesvoer hierover moeten verschaffen. :)
Dat 'op basis van een waarde' steekt me; je kunt geen mooie query schrijven die ineens resultaten ophaalt. Voor veruit de meeste functionaliteiten (vakken / huiswerk / rechten) is het handig dat docenten en studenten in verschillende tabellen zitten, maar voor enkele (mededelingen, algemene agenda, chat) is het juist niet handig.
Ik zie het probleem niet. Je data-model moet je zo maken, zodanig dat je data integriteit bewaard blijft, op dat niveau moet je geen toegevingen doen omdat dit of dat op een makkelijkere manier zou kunnen.
Je kan één root-table hebben, waarin je alle gemeenschappelijke gegevens opslaat, + een discriminator. Op basis van dat veld, weet je welke gegevens je moet ophalen.

https://fgheysels.github.io/


  • Janoz
  • Registratie: Oktober 2000
  • Nu online

Janoz

Moderator Devschuur®

!litemod

uitgaande van 1 tabel:
Het verschil tussen een docent en student is natuurlijk makkelijk. Bij elke join moet je gewoon 'tabel.studentid = student.id' vervangen door 'tabel.personid = persons.id AND type=student'.

De gegevens erbij zoeken is ook geen enkel probleem. Je kunt de persoon tabel joinen met beide subtabellen. Zolang je de juiste join gebruikt worden de velden die bij student horen bij een docent gewoon null. Die query is dus helemaal niet moeilijk en ook helemaal niet lastig. Bijkomend voordeel is dat een docent tegelijk ook een student kan zijn. Of je dit wilt moet je nog even bepalen. Het is een beetje afhankelijk van de requirments en bepaald hoe je je restricties moet leggen.

Het is gewoon veel makkelijker om 1 tabel te benaderen alsof er 2 types inzitten (zolang ze bijna hetzelfde zijn) dan om twee tabellen te benaderen alsof het 1 is.

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


  • orf
  • Registratie: Augustus 2005
  • Laatst online: 22:14
Goede dingen; ik ga me eens goed inlezen. :)
Bedankt voor de inzichten!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Stel je hebt 3 tabellen:

persoon
- id
- naam
- telefoon
- email
- etc

docent
- id
- persoon_id

student
- id
- persoon_id

Je kunt simpel checken of iemand student is door een join te doen tussen de persoon en student tabel, daar heb je dan nieteens een aparte kolom voor nodig in de persoon tabel. Je kunt gewoon persoon.id gebruiken als key voor chatberichten, en je personen kunnen ook nog eens zowel student als docent zijn. De docent- en studentspecifieke waarden stop je in de desbetreffende velden. Alle 'generieke' waarden (email, geboortedatum, etc.) zit dan in het persoonsveld.

Alle personen, studenten en docenten ophalen op basis van selectiecriteria kan ook gewoon in een enkele query.

https://niels.nu


  • MicroWhale
  • Registratie: Februari 2000
  • Laatst online: 01-12 10:46

MicroWhale

The problem is choice

Zoals hydra zegt:

Docent en Leerling generaliseren naar Persoon.

Het enige belangrijke is dat je vandaag altijd rijker bent dan gisteren. Als dat niet in centen is, dan wel in ervaring.


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

orf schreef op donderdag 14 juni 2007 @ 14:07:
Iemand een slim idee om dit soort problemen te verhelpen?
Het probleem generaliseren. Dan kom je al snel problemen tegen als: wat als studenten met elkaar chatten? Wat als een student ook een docent is (student-assistent)? Wat als er een 'derde soort' bij komt? Op welke andere manieren kan het veld nog redelijkerwijs veranderen?

De enige oplossing is een tabel te hebben waarin iedere entiteit die kan communiceren een uniek ID heeft, zodat je altijd twee ID's uit die tabel in de 'communicatie' tabel op kan slaan. Of dat nu een view is, een tabel met 'personen' als supersoort of een redundante tabel: zo'n tabel moet er zijn.

[ Voor 5% gewijzigd door Confusion op 15-06-2007 15:50 ]

Wie trösten wir uns, die Mörder aller Mörder?


  • orf
  • Registratie: Augustus 2005
  • Laatst online: 22:14
Vanuit historisch oogpunt niet fijn, maar inderdaad in het datamodel nu één tabel personen.
Bedankt allen. :)

Verwijderd

Het algemene probleem is dus simpelweg overerving in een relationeel model. Daar zijn 3 verschillende oplossingen voor.
- tabel per type (volgens mij nog niet benoemd in dit topic)
- 1 tabel voor alles (Janoz)
- afgeleide tabellen (Hydra)
Opzich bij dit vraagstuk is doorgaans de 'Janoz oplossing' het meest interessant. Het presteert het beste en is vaak flexibel genoeg. Maar uiteraard heeft alles zijn voor en zijn nadeel.

Een punt wat enigzins gepaseerd wordt, is je huidige opzet van je model. Ik denk dat er wat haken en ogen aan zitten. Je zegt namelijk dat docenten en studenten andere rechten hebben. Dit impliceert dat je alsware twee rechten modellen hebt: 1 voor studenten en 1 voor docenten.

Het lijkt me dat het juist onder brengen van je rechten al een groot deel van je problemen oplost.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Verwijderd schreef op vrijdag 15 juni 2007 @ 16:20:
- tabel per type (volgens mij nog niet benoemd in dit topic)
- 1 tabel voor alles (Janoz)
- afgeleide tabellen (Hydra)
Opzich bij dit vraagstuk is doorgaans de 'Janoz oplossing' het meest interessant.
Euh sorry, maar je "Janoz" oplossing wordt al snel compleet crap als je docent- of studentspecifieke informatie hebt, zoals door de TS al gemeld werd. Dan heb je dus een hele zooi kolommen die voor een deel van de dataset gewoon nutteloos zijn. Om het nog maar niet te hebben over dat het vanuit een dataanalyseoogpunt gewoon rammelt aan alle kanten.

https://niels.nu


Verwijderd

Hydra schreef op vrijdag 15 juni 2007 @ 16:26:
Euh sorry, maar je "Janoz" oplossing wordt al snel compleet crap als je docent- of studentspecifieke informatie hebt, zoals door de TS al gemeld werd. Dan heb je dus een hele zooi kolommen die voor een deel van de dataset gewoon nutteloos zijn.
En wat is nu je punt? Het is algemeen bekend dat bij die oplossing je gebruik maakt van kolommen die ten alle tijde null moeten toestaan. Daarom zeg ik ook dat alles zijn voor en nadeel heeft.
Hydra schreef op vrijdag 15 juni 2007 @ 16:26:Om het nog maar niet te hebben over dat het vanuit een dataanalyseoogpunt gewoon rammelt aan alle kanten.
Lekker belangrijk, je kunt sowieso geen high-performance db schema maken zonder hier en daar wat puristische regels te schenden.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Verwijderd schreef op vrijdag 15 juni 2007 @ 16:37:
Lekker belangrijk, je kunt sowieso geen high-performance db schema maken zonder hier en daar wat puristische regels te schenden.
High performance my ass. Een dergelijke join heeft vrijwel geen impact, tenzij je zo dom bent geen index op de keys te zetten. En ruimte verspillen heeft OOK invloed op performance.

https://niels.nu


Verwijderd

Hydra schreef op vrijdag 15 juni 2007 @ 16:49:
High performance my ass. Een dergelijke join heeft vrijwel geen impact, tenzij je zo dom bent geen index op de keys te zetten. En ruimte verspillen heeft OOK invloed op performance.
Yeah sure :+

Let's agree to disagree maar weer heh :D

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Verwijderd schreef op vrijdag 15 juni 2007 @ 16:20:

Opzich bij dit vraagstuk is doorgaans de 'Janoz oplossing' het meest interessant. Het presteert het beste en is vaak flexibel genoeg. Maar uiteraard heeft alles zijn voor en zijn nadeel.
Prestatie is idd goed, flexibiliteit ook; het is alleen moeilijker om je data integriteit te bewaren, en je DB model 'te lezen'; althans, da's mijn ervaring.
Hydra schreef op vrijdag 15 juni 2007 @ 16:26:
Dan heb je dus een hele zooi kolommen die voor een deel van de dataset gewoon nutteloos zijn.
Hoeft dat ? 't Is niet omdat je tabel op een bepaalde manier gemodelleerd is, dat je business objecten of datasets een één op één mapping moeten zijn van je tabel.

[ Voor 28% gewijzigd door whoami op 15-06-2007 20:01 ]

https://fgheysels.github.io/


Verwijderd

whoami schreef op vrijdag 15 juni 2007 @ 20:00:
Prestatie is idd goed, flexibiliteit ook; het is alleen moeilijker om je data integriteit te bewaren, en je DB model 'te lezen'; althans, da's mijn ervaring.
Je integriteit wordt inderdaad, zoals vermeld, niet meer afgedwongen door je datastore. Maar tegenwoordig is dat ook niet echt meer een probleem. We hebben immers tegenwoordig allemaal hippe domein, dao en manager lagen. Ook spreken verschillende applicaties niet meer tegen dezelfde datastore, maar gaat dat via een service applicatie (wat ook logischer is want je hebt meer validatie vrijheid in een applicatie dan in een datastore). De noodzaak om dus integriteit af te dwingen in een datastore is overbodig te noemen en hoe dan ook onvolledig (een geboortedatum van voor 1800 kan ik met integriteits regels niet tegen gaan).

Het lezen en schrijven kan inderdaad onoverzichtelijk zijn maar gelukkig maken OR mappers het leven een stuk makkelijker.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Verwijderd schreef op vrijdag 15 juni 2007 @ 19:31:
[...]
Yeah sure :+

Let's agree to disagree maar weer heh :D
Dat een dergelijke join vrijwel geen impact heeft op performance is gewoon een feit. Dat je het daar niet mee 'eens' bent geeft aan dat je je meer druk maakt over je gelijk halen dan over feitelijkheden.

https://niels.nu


Verwijderd

Hydra schreef op dinsdag 19 juni 2007 @ 11:39:
Dat een dergelijke join vrijwel geen impact heeft op performance is gewoon een feit. Dat je het daar niet mee 'eens' bent geeft aan dat je je meer druk maakt over je gelijk halen dan over feitelijkheden.
Je argument 'een dergelijke join' heeft weinig tot geen inhoudelijke waarde op het moment dat de rest in dit topic het in zijn algemeenheid over het probleem heeft. Dus je zegt feitelijk helemaal niets.

  • Janoz
  • Registratie: Oktober 2000
  • Nu online

Janoz

Moderator Devschuur®

!litemod

Integriteit is wel weer een stuk beter af te dwingen wanneer je generieke gegevens in de ene tabel zet en specifieke gegevens in de student en/of docent tabel opslaat. Je kunt los voor de docent tabel rustig constraints opnemen.

In mijn topic haalde ik trouwens twee mogelijke oplossingen aan. De methode die nu omgedoopt is tot de 'janoz' manier, en ongeveer de Hydra manier. Ikzelf zou dan echter niet een extra ID introduceren. Voor de Student en de Docent tabel zou ik gewoon de persoonId gebruiken als PK

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


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Verwijderd schreef op dinsdag 19 juni 2007 @ 11:57:
Je argument 'een dergelijke join' heeft weinig tot geen inhoudelijke waarde op het moment dat de rest in dit topic het in zijn algemeenheid over het probleem heeft. Dus je zegt feitelijk helemaal niets.
Ik zeg dat je performance argument onzinnig is omdat een dergelijke join tussen 2 tabellen niet wezenlijk trager is dan wanneer alle info in 1 tabel zou staan. Dat zeg ik. Dat jij dat er niet uit haalt, tja...

https://niels.nu


Verwijderd

Hydra schreef op dinsdag 19 juni 2007 @ 14:22:
Ik zeg dat je performance argument onzinnig is omdat een dergelijke join tussen 2 tabellen niet wezenlijk trager is dan wanneer alle info in 1 tabel zou staan. Dat zeg ik. Dat jij dat er niet uit haalt, tja...
Ik weet wat je zegt, maar je argument is niet van toepassing op de context. Dat jij dat er niet uit haalt, tsja...

En al passen we het wel toe op de context dan heb je simpelweg ongelijk. Een join, ongeacht de indexen, vertraagt het geheel simpelweg. De significatie is afhankelijk van de hoeveelheid data. Dus is het in zijn algemeenheid veilig om te stellen dat de oplossing waar 1 tabel wordt gebruikt met een discriminator veld het beste presteert.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Modbreak:Houden we het wel gezellig en niet op de man? Dank u voor uw aandacht ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Verwijderd schreef op dinsdag 19 juni 2007 @ 14:34:
En al passen we het wel toe op de context dan heb je simpelweg ongelijk. Een join, ongeacht de indexen, vertraagt het geheel simpelweg.
Dat is te kort door de bocht. Een join kan een query significant vertragen. In het bovenstaande geval zal dit alleen absoluut niet het geval zijn, mits er een index op de keys aanwezig is. De database hoeft hiervoor namelijk geen tijdelijke tabel aan te gaan maken. Hij kan gewoon balance-line door de tabellen lopen en deze richting client uitspugen.

Een oplossing met 2 tabellen zat dus niet significant trager zijn.
De significatie is afhankelijk van de hoeveelheid data.
Nee. Bij een join tussen de door mij beschreven tabellen is de hoeveelheid data niet significant. De snelheid (dus het aantal rows/second dat uitgespuugd kan worden) is constant. Het maakt niet uit of de tabellen 100 of 100000 rows bevatten.

Performance wordt over het algemeen een probleem als er tijdelijke in-memory tabellen gemaakt moeten worden omdat er bijvoorbeeld gesorteerd moet worden, maar dat is in dit geval niet ins frage. je bewering dat performance een overweging is om voor een oplossing te gaan die niet correct genormaliseerd is, is dus nog steeds niet valid.
RobIII schreef op dinsdag 19 juni 2007 @ 14:39:
Houden we het wel gezellig en niet op de man? Dank u voor uw aandacht ;)
Ik hou het graag gezellig, mits een discussie op feiten gebaseerd blijft.

[ Voor 11% gewijzigd door Hydra op 20-06-2007 13:55 ]

https://niels.nu


Verwijderd

Hydra schreef op woensdag 20 juni 2007 @ 13:53:
[..]Een join kan een query significant vertragen.[..]
Dat zeg ik. Niet meer en niet minder.

[ Voor 85% gewijzigd door Verwijderd op 22-06-2007 06:41 ]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Verwijderd schreef op donderdag 21 juni 2007 @ 22:17:
Dat zeg ik. Niet meer en niet minder.
En ik zeg dat dat in de genoemde situatie, en dat benadruk ik steeds, niet het geval zal zijn.

https://niels.nu

Pagina: 1