Alarmnummer schreef op vrijdag 04 februari 2005 @ 09:23:
Ik heb een vraag over relaties in de database en bij objecten. Ik begrijp hoe cardinaliteiten werken, maar wat niet helemaal duidelijk is zijn de 'types' relaties tussen objecten.
Tussen een order en een order regel bestaat een bepaalde relatie " order bestaat uit meerdere order regels". Bij mijn Order object zou ik dus ook graag een getOrderRegels methode willen zien.
Tussen een auto en een kleur kan ook een relatie bestaan "auto heeft kleur". Maar je zult nooit direct aan een kleur object getAuto`s opvragen.
Dat is maar net hoe je er naar kijkt.
Je hebt attributes, zoals customername, orderdate etc. Die hebben een relatie met elkaar en die noem je een entity. Zoals order, customer etc. Dan heb je relaties tussen attributes van verschillende entities, zoals order.customerid -> customer.customerid
Omdat attributes van verschillende entities die een relatie hebben met elkaar een relatie hebben met de andere attributes in de entity, spreek je van 'entity A heeft relatie met entity B'.
Nu heb je verschillende relatie typen:
1:1 (PK - FK/PK)
1:1 (PK - FK/UC)
1:1 (PK/FK - PK)
1:1 (FK/UC - PK)
1:n (PK - FK)
m:1 (FK - PK)
Verder is het zo dat wanneer je 3 entities hebt, A, B en C en B heeft een m:1 relatie naar A en een m:1 relatie naar C dat A en C een m:n relatie hebben via B.
Je kunt in algemene termen spreken over 'Customer heeft relatie met Order' maar daar heb je niet zoveel aan. Wat interessant is is wat je definieert wat de basis is van de relatie tussen Customer en Order, en dat is een referential constraint: Order.CustomerID == Customer.CustomerID.
Die constraint is de basis voor 2 relaties: Customer->Order (1:n) en Order -> Customer (m:1). Iedere constraint gaat 1 kant op en start altijd vanaf de FK side naar de PK side.
Binnen relational theory heb je hier niet zoveel last van. Bij O/R mappers is dat anders. Heb je in Customers nog een routine die bv GetOrders() heet, in Order heb je niet een routine die GetCustomers() heet, maar GetCustomer.
Fraaier wordt het wanneer we naar de 1:1 relaties gaan kijken. Is het bij een 1:n en m:1 relatie nog makkelijk te bepalen wat je moet nemen: een GetCustomer of een GetOrders, bij 1:1 relaties is dat lastig: hoe fetch je het related object? Via de PK? via een UC? Je moet dan weten aan welke kant van de relatie je zit: de FK side of de PK side.
Het gekke is dat ik mijn objecten altijd wel goed opzet, dus het is geen kwestie van hoe doe ik het goed.. mijn vraag is.. waarom doe ik het goed.. kan iemand mij misschien een duidelijke uitleg geven van de soorten relaties.
Dat komt omdat het relationele model en het E/R model eigenlijk heel natuurlijk werken, ZEKER wanneer je entities fysieke elementen representeren of elementen die je als entiteit ook tegenkomt in het dagelijks leven, bv Cursus, Auto, Customer, Product etc.
Het nare is: je kunt niet echt controlleren of iets 'goed' is, want een niet heel slim in elkaar gezet relational model werkt op zich best nog wel.
Even een oefening:
Department en Employee (istie weer). Stel ik model het zo:
Department: (DepartmentID* | Head | Name | Location)
Employee: (EmployeeID* | WorksAtDepartment | Name | ... )
waarbij Department.Head een FK is naar Employee.EmployeeID en Employee.WorksAtDepartment een FK is naar Department.DepartmentID
Niet gaan lachen, met addresses en customers zie je dit vaak terugkomen. Dit is een zg. loop. Je kunt dit niet saven in SQL zonder een nullable FK. Is dit goed? Geen idee. Er is een betere variant mogelijk met 3 entities ipv 2, zonder loop. Die ziet er niet natuurlijk uit:
Department: (DepartmentID* | Name | Location)
DepartmentEmployee: (DepartmentID* | EmployeeID* | IsHead)
Employee: (EmployeeID* | Name | ... )
Waarbij DepartmentEmployee.EmployeeID een UC heeft.
Dus of je het 'altijd' goed doet is niet altijd te zeggen. Soms denk je het goed gedaan te hebben, maar loop je toevallig NOG niet tegen de flaws aan die er in zitten. Het bovenstaande schemaatje is niet bedacht, maar een echt schema (onderdeel van).