Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Relatie leggen op een bepaalde tabel

Pagina: 1
Acties:

  • Eriksk
  • Registratie: December 2003
  • Niet online
Hallo,

ik zit nu met een 'waarom-probleem', waarop ik maar geen antwoord kan vinden. Niet door discussie hier en ook niet als ik diverse andere datamodels bekijk.

De volgende situatie heb ik (sterk vereenvoudigt en vertaald naar een alledaags onderwerp: Enquetes):
Er is een algemene lijst van gebruikers. Aangezien niet alle gebruikers meedoen aan enquetes is er een deelnemerlijst.

Vragen --> Enquetes <-- Deelnemers --> Gebruikers

De velden laten zich wel raden, maar de Deelnemers hebben een DeelnemerID, GebruikerID en EnqueteID (is nu eenmaal zo in dit voorbeeld).

Nu is er natuurlijk ook een tabel met antwoorden die gekoppeld is op de vragen en gekoppeld moet worden aan een gebruiker. Maar leg je nu de koppeling op de Deelnemers of Gebruikers-tabel?

Wat ik me kan bedenken is dat als je een koppeling legt op de deelnemertabel dat je dan op db-niveau al afvangt dat het antwoord altijd bij een deelnemer hoort en dus niet zomaar een antwoord in de db kan bevinden (snappie?). Anderen zeggen dat ze em op de gebruikerstabel zouden leggen, maar zonder een waarom (behalve 'nou ja, gewoon').

Greetz

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Eriksk schreef op vrijdag 08 februari 2008 @ 15:14:
ik zit nu met een 'waarom-probleem', waarop ik maar geen antwoord kan vinden. Niet door discussie hier en ook niet als ik diverse andere datamodels bekijk.

De volgende situatie heb ik (sterk vereenvoudigt en vertaald naar een alledaags onderwerp: Enquetes):
Er is een algemene lijst van gebruikers. Aangezien niet alle gebruikers meedoen aan enquetes is er een deelnemerlijst.

Vragen --> Enquetes <-- Deelnemers --> Gebruikers

De velden laten zich wel raden, maar de Deelnemers hebben een DeelnemerID, GebruikerID en EnqueteID (is nu eenmaal zo in dit voorbeeld).

Nu is er natuurlijk ook een tabel met antwoorden die gekoppeld is op de vragen en gekoppeld moet worden aan een gebruiker. Maar leg je nu de koppeling op de Deelnemers of Gebruikers-tabel?
Ik ga zeiken, dus als je een dunne huid hebt, niet verder lezen.

Je moet dit soort dingen formeel oplossen, niet gaan lopen knoeien op tabelniveau. De grootste reden waarom mensen in de knoei komen met datamodellen is dat ze op tabelniveau dingen willen aanpassen maar de tabellen zijn een RESULTAAT van een abstract model geprojecteerd op een relationeel schema. Als je bv een modelleringstechniek als NIAM/ORM gebruikt (http://www.orm.net) dan is dit heel simpel te doen. En echt, neem de moeite dit soort dingen te leren. Als je denkt "dat is onzin", dan heb je alleen jezelf maar te pakken, en als men zonder dit soort BASISKENNIS hier vragen gaat stellen, dan ook de mensen hier, maar goed, niet iedereen weet alles vanaf het begin, dus ik ga je wel antwoord geven, don't worry. Ik verwacht wel dat je op zn minst die site gaat bekijken en gaat lezen wat Halpin daar schrijft zodat je een beetje kennis vergaart van hoe dit soort dingen werken. Daar kun je bv lezen wat een objectified relation inhoudt wat ik hieronder ga bespreken.

Ok, je probleem.
Wat je hebt is een 'objectified relation'. Dit houdt in: je hebt een relatie tussen een paar entities en die relatie op zichzelf is weer een entity waarmee je een relatie kunt leggen met een andere entity.
Je hebt een relatie Enquete - Gebruiker. Die relatie is 'objectified' en op zichzelf een entity. Die heb je genoemd 'Deelnemer'. Je hebt ervoor gekozen het identifying attribute van dat entity te noemen 'DeelnemerID' en dat is neem ik aan een artificial key. Op zich prima, je had ook een compound PK kunnen kiezen, nl. GebruikerID-EnqueteID.

Ok, de gebruiker vult vragen in door het geven van antwoorden. Een antwoord is het antwoord op een vraag door een deelnemer. Je kunt dit modellen door een relatie te leggen tussen vraag en deelnemer, die als objectified beschouwt en wat dus een nieuwe entity is, bv 'Antwoord'. (entities hebben altijd enkelvoudige namen, je hebt 1 vraag, niet 1 vragen) Dat entity 'Antwoord' heeft een nieuw attribute: Antwoord (of 'value', whatever je passend vind om de opgegeven waarde door de deelnemer op te slaan). Het entity 'Antwoord' heeft, omdat het een objectified relation is, een relatie met vraag en een relatie met deelnemer.

Het mooie aan NIAM/ORM is dat je met het model daarna je tabellen automatisch bepaalt dmv een conversie methodiek (er zijn ook tools die dit automatisch doen voor je, bv visio).

Het komt er dus op neer dat je een nieuwe tabel aanmaakt, Antwoorden (ik blijf maar even bij jouw naamgevingstijl) en die heeft een nieuwe PK (omdat je artificial keys wilt), AntwoordID en een FK naar Vragen en een FK naar Deelnemer, Het heeft verder een veld 'Antwoord', waar het antwoord staat wat deelnemer gegeven heeft op vraag. That's it.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • ZanomiX
  • Registratie: Januari 2007
  • Laatst online: 13-06-2019
Zou je deelnemers en gebruikers trouwens niet in 1 tabel stoppen nl. personen en dan erbij zetten of het een gebruiker/deelnemer is?

http://parkingwerchter.be


  • EfBe
  • Registratie: Januari 2000
  • Niet online
ZanomiX schreef op zaterdag 09 februari 2008 @ 11:44:
Zou je deelnemers en gebruikers trouwens niet in 1 tabel stoppen nl. personen en dan erbij zetten of het een gebruiker/deelnemer is?
Het punt is dat de relatie enquete - gebruiker de entity 'deelnemer' vormt, en die entity heeft de relaties met vraag-antwoord, niet gebruiker.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:35
Als ik het goed begrijp is je datamodel in je database zoiets:
  • Vraag: id, enquete_id, vraag, ...
  • Enquête: id, titel, ...
  • Deelnemer: deelnemer_id (waarom?), enquête_id, gebruiker_id
  • Gebruiker: id, naam, ...
En je wil je een tabel met antwoorden toevoegen, die antwoorden van deelnemers op vragen in enquêtes vastlegt, en je hebt deze twee opties:
  1. Antwoord: gebruiker_id, vraag_id, antwoord, ..
  2. Antwoord: deelnemer_id, vraag_id, antwoord, ..
In het eerste geval heb je natuurlijk het probleem dat je rijen kunt toevoegen die inconsistent zijn: een antwoord van een gebruiker op een vraag die bij een enquête hoort, waaraan die gebruiker niet deelneemt. Het tweede geval lijkt dat te voorkomen doordat je aan een deelnemer koppelt. Je hebt dan sowieso een deelnemer te pakken, maar het is niet gezegd dat de enquête die bij de vraag hoort en die bij de deelnemer hoort, dezelfde zijn, en dat is wél wat je wil!

Naar mijn idee heb je dus in beide gevallen je datamodel niet volledig dichtgetimmerd. Dat is op zich geen ramp; je kunt het oplossen door een check constraint in je database toe te voegen of de consistentie in je applicatie te garanderen.

Een voordeel van optie 2 kan zijn dat die de mogelijkheid open houdt dat één gebruiker dezelfde enquête meer dan eens doet (en dus verschillende antwoorden op dezelfde vraag gegeven kan hebben). Uit je beschijving is niet direct duidelijk of dat wenselijk is of niet.

  • Eriksk
  • Registratie: December 2003
  • Niet online
Bedankt voor het meedenken en de antwoorden.

Die dunne huid valt wel mee... ik heb direct mijn NIAM dictaat er weer bijgepakt (jeetje, wat had ik daar een hekel aan zeg! :( ), maar moet toch wel zeggen dat de db conversie niet echt goed / duidelijk is uitgewerkt. Zal zeker de site over ORM beter bekijken.

Dat deelnemer geen samengestelde key heeft, heeft te maken dat dit in realiteit niet van toepassing was (het voorbeeld enquete was het beste dat ik kon verzinnen om het begrijpbaar te maken :) )

Nog wel een vraagje over je uitgangspunt mbt de naamgeving. Heb je er een bron van waarom deze nekelvoudig is? Aangezien ik een MS developer ben, probeer ik ook die regels te volgen. Die zijn volgens mij, dat als een tabel een verzameling entiteiten bevat, deze meervoud is.
Quote:
Tables represent the instances of an entity. For example, you store all your customer information in a table. Here, 'customer' is an entity and all the rows in the customers table represent the instances of the entity 'customer'. So, why not name your table using the entity it represents, 'Customer'. Since the table is storing 'multiple instances' of customers, make your table name a plural word
Hierbij wordt je identity: CustomerID (enkelvoud)

/edit:
Stel ik heb op deelnemer toch een samengesteld key van EnqueteID en GebruikerID, leg je dan alsnog de relatie tussen Antwoord en Deelnemer op het veld GebruikerID? Als ik dat namelijk doe, dan krijg ik de volgende foutmelding (MS SQL):
The columns in table 'Enquetes' do not match an existing primary key or UNIQUE constraint.

[ Voor 12% gewijzigd door Eriksk op 11-02-2008 12:22 ]


  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Eriksk schreef op maandag 11 februari 2008 @ 12:03:
Nog wel een vraagje over je uitgangspunt mbt de naamgeving. Heb je er een bron van waarom deze nekelvoudig is? Aangezien ik een MS developer ben, probeer ik ook die regels te volgen. Die zijn volgens mij, dat als een tabel een verzameling entiteiten bevat, deze meervoud is.
Quote:

[...]
Naar mijn bescheiden mening is dat dikke bull in die quote. De eerste objectgerichte ontwerper die zijn klasse Customers noemt, omdat er meerdere instanties van klanten zijn, in plaats van Customer moet ook nog geboren worden.

Dit is eigenlijk een typisch gevalletje van denken op ontwikkelaar- in plaats van ontwerper-niveau. Technisch gezien zitten er in die tabel meerdere klanten; conceptueel gezien gaat het hier om de modellering van een klant.

[ Voor 14% gewijzigd door Nick The Heazk op 11-02-2008 20:01 ]

Performance is a residue of good design.


  • wizzkizz
  • Registratie: April 2003
  • Laatst online: 04-11 04:01

wizzkizz

smile...tomorrow will be worse

Nick The Heazk schreef op maandag 11 februari 2008 @ 19:55:
[...]


Naar mijn bescheiden mening is dat dikke bull in die quote. De eerste objectgerichte ontwerper die zijn klasse Customers noemt, omdat er meerdere instanties van klanten zijn, in plaats van Customer moet ook nog geboren worden.

Dit is eigenlijk een typisch gevalletje van denken op ontwikkelaar- in plaats van ontwerper-niveau. Technisch gezien zitten er in die tabel meerdere klanten; conceptueel gezien gaat het hier om de modellering van een klant.
OT:
Wat is er mis met de klasse Customers? Als ik een klasse Customers heb geeft die aan dat het over alle klanten gaat (klasse Customer). Die klasse Customers kun je bijvoorbeeld gebruiken om bepaalde klanten te selecteren op gemeenschappelijke eigenschappen of name it.
De tabel Customers gaat over alle klanten, en elk record is een entiteit Customer. Als je de tabel beschouwt als een verzameling Customer-entiteiten, vind ik niets mis met een naam als Customers.

Maarja, ik ben dan ook meer ontwikkelaar dan ontwerper ;)

Make it idiot proof and someone will make a better idiot.
Real programmers don't document. If it was hard to write, it should be hard to understand.


  • FireMotion
  • Registratie: Augustus 2003
  • Niet online

FireMotion

De wereld is een plaatje.

Eriksk schreef op maandag 11 februari 2008 @ 12:03:
[..]
/edit:
Stel ik heb op deelnemer toch een samengesteld key van EnqueteID en GebruikerID, leg je dan alsnog de relatie tussen Antwoord en Deelnemer op het veld GebruikerID? Als ik dat namelijk doe, dan krijg ik de volgende foutmelding (MS SQL):
Je zegt het eigenlijk zelf al: bij Deelnemer heb je een samengestelde key van EnqueteID en GebruikerID.
Als je dus in Antwoord een foreign key naar Deelnemer wilt hebben, dan moet je dezelfde samengestelde key gebruiken (oftewel EnqueteID en GebruikerID).

  • EfBe
  • Registratie: Januari 2000
  • Niet online
wizzkizz schreef op woensdag 13 februari 2008 @ 14:27:
[...]

OT:
Wat is er mis met de klasse Customers? Als ik een klasse Customers heb geeft die aan dat het over alle klanten gaat (klasse Customer). Die klasse Customers kun je bijvoorbeeld gebruiken om bepaalde klanten te selecteren op gemeenschappelijke eigenschappen of name it.
De tabel Customers gaat over alle klanten, en elk record is een entiteit Customer. Als je de tabel beschouwt als een verzameling Customer-entiteiten, vind ik niets mis met een naam als Customers.

Maarja, ik ben dan ook meer ontwikkelaar dan ontwerper ;)
De tabel heeft zelf geen data. Je moet een tabeldefinitie zien als een class definitie, die maak je ook niet met een meervoudnaam wanneer het 1 element voorstelt (i.e. geen IList is).

Immers: je definieert 'Customer' in de database met de velden A, B en C, en daarna heb je 0 of meerdere instanties van die definitie in jouw database, nl. de data van die 3 rows.

heeft niets met ontwerper vs. developer te maken maar met basiskennis relationele algebra.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1