Enitity met meerdere primary keys
bij een many to many relation gebruiken we een koppeltabel. In sommige situaties kan het handig zijn om in de koppeltabel een derde kolom op te nemen.
Dit wil ik nu met entities doen in Symfony en dat lukt. Ik gebruik zoals de documentatie voorschrijft een aparte entity als koppel tabel. laten we zeggen team --> teamrole <-- role
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
class TeamRole
{
/**
* @var string
*
* @ORM\Id
* @ORM\ManyToOne(targetEntity="TeamroleChoice")
* @ORM\JoinColumn(name="teamrole_id", referencedColumnName="id")
**/
private $role;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Member", inversedBy="teamroles")
* @ORM\JoinColumn(name="member_id", referencedColumnName="id")
**/
private $member;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Team", inversedBy="teamroles")
* @ORM\JoinColumn(name="team_id", referencedColumnName="id")
**/
private $team;
}
?>
class TeamRole
{
/**
* @var string
*
* @ORM\Id
* @ORM\ManyToOne(targetEntity="TeamroleChoice")
* @ORM\JoinColumn(name="teamrole_id", referencedColumnName="id")
**/
private $role;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Member", inversedBy="teamroles")
* @ORM\JoinColumn(name="member_id", referencedColumnName="id")
**/
private $member;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Team", inversedBy="teamroles")
* @ORM\JoinColumn(name="team_id", referencedColumnName="id")
**/
private $team;
}
?>
echter wil ik het volgende in de tabel kunnen invoegen:
Hierop kreeg ik een fout: in de role kolom kwam de waarde 1 al voor.
wat ik wil is dat waardes per kolom meerdere keren mogen voorkomen maar dat als dezelfde combinatie al voorkomt wel een foutmelding gegeven wordt:
Code (php)
1
2
3
4
5
2
3
4
5
role | member | team
1 | 2 | 3
1 | 4 | 5
--------------------
1 | 2 | 3 <----- Foutmelding: deze combinatie komt al eerder voor
1 | 2 | 3
1 | 4 | 5
--------------------
1 | 2 | 3 <----- Foutmelding: deze combinatie komt al eerder voor
Hoe bereik ik in Symfony / Doctrine / ORM het makkelijkste mijn doel? dat is mijn vraag.
Gewijzigd op 09/04/2014 00:31:11 door Frank Nietbelangrijk
Als het je doel is om te tellen hoeveel doublures er zijn, zou je kunnen overwegen om een extra veld 'teller' aan de tabel toe te voegen dat geen onderdeel is van de key. Bij je insert query zou je dan die teller kunnen verhogen als het record al bestaat. Iets als:
insert into tabel (a, b, c) values (x, y, z) on duplicate key update teller=teller+1;
Ongetwijfeld zal dat wel weer tegen een of andere normaalvorm indruisen, maar het komt volgens mij wel het dichtst bij wat ik denk dat je wilt. En hoe je dat in je favoriete framework moet coderen? Geen flauw idee. ;-)
Gewijzigd op 09/04/2014 02:07:26 door Willem vp
Dank je wel voor je reactie. De bedoeling is inderdaad niet om een koppeling nog een keer aan te brengen. Ik heb inmiddels bedacht dat mijn benamingen misleidend zijn dus hier nog een beetje extra info:
Member = een lid van een sportclub
Team = een team van de sportclub waar de member in meespeelt/helpt.
Role = de rol die de member heeft binnen dat team. (denk aan speler, coach of keeper)
De feitelijke koppeling is dus tussen members en teams. De entity had dus beter TeamMember kunnen heten dan TeamRole. De role is dus de extra kolom in de koppeltabel. Ik heb hier een ManyToOne van gemaakt omdat ik wil dat de gebruikers straks uit een vast rijtje een keuze kunnen maken. Feitelijk had het ook gewoon een type="string" kunnen zijn.
Jouw oplossing met die insert komt wel in de richting hoe ik het wil hebben maar ik vroeg me af of er andere oplossingen mogelijk zijn. Misschien door de annotations te wijzigen?
Door unique constraints (een PK heeft dat automatisch) op bepaalde (combinaties van) kolommen te zetten voorkom je dat dubbele waardes worden ingevoerd.
Hoe je dat in je applicatie oplost is een keuze, de één controleert eerst zelf, de ander doet gewoon botweg een insert, en vangt daarna de duplicate key entry error af.
Gewijzigd op 09/04/2014 20:57:58 door Ger van Steenderen
Ger van Steenderen op 09/04/2014 20:57:31:
Meerdere primary keys bestaan niet. Je hebt één primary key die uit meerdere kolommen kan bestaan.
Okee, dat is duidelijk.
Ger van Steenderen op 09/04/2014 20:57:31:
Door unique constraints (een PK heeft dat automatisch) op bepaalde (combinaties van) kolommen te zetten voorkom je dat dubbele waardes worden ingevoerd.
Hieruit lees ik dat het mogelijk is om één unique constraint te zetten over meerdere kolommen?
Kun jij hier een voorbeeld van geven Ger?
Ger van Steenderen op 09/04/2014 20:57:31:
Hoe je dat in je applicatie oplost is een keuze, de één controleert eerst zelf, de ander doet gewoon botweg een insert, en vangt daarna de duplicate key entry error af.
Ik zou dan zeker voor de eerste optie kiezen. Dus dat betekend in PHP gewoon een query draaien en als er een record gevonden is dan bestaat die combinatie al en geef je een foutmelding. Dat is toch wat je bedoelt?
Gewijzigd op 09/04/2014 21:16:30 door Frank Nietbelangrijk
Op je eerste vraag:
Wat voor voorbeeld? Hoe je dat moet doen of .... ?
ja, Hoe ik dat moet doen inderdaad?
Volgens mij heb je geen unique constraints nodig als je al in de API in check inbouwt? Dat zou toch dubbelop zijn?
Nee, de uiteindelijke verantwoording ligt niet bij de app, verschillende apps kunnen met dezelfde db moeten/kunnen werken.
@Frank
Code (php)
1
2
2
ALTER TABLE tabelnaam
ADD INDEX aindexname UNIQUE (kolom1[ASC[DESC]], kolom2[ASC[DESC]])
ADD INDEX aindexname UNIQUE (kolom1[ASC[DESC]], kolom2[ASC[DESC]])
Gewijzigd op 09/04/2014 22:44:16 door Ger van Steenderen
Super Ger! dank u dank u :-)
Wat me nog een beetje vreemd in de ogen doet schijnen is dit: [ASC[DESC]] ?
Maar ik zal de google er eens bij pakken.