sql >> Database teknologi >  >> RDS >> Mysql

Sådan bruger du fremmednøgler med PHP

Disambiguation af fremmednøglekolonner/-begrænsninger

Forudsat at du henviser til de fremmednøglebegrænsninger , ville det korte svar være du bruger dem bare ikke .

Og her kommer den lange:

Vi er vant til at henvise til, at kolonner er fremmednøgler til andre borde. Især under normaliseringsprocessen, sætninger som "user_purchase.i_id er en fremmednøgle til items tabel" ville være meget almindeligt. Selvom det er en helt gyldig måde at beskrive forholdet på, kan det blive lidt uklart, når vi når implementeringsfasen.

Antag, at du har oprettet dine tabeller uden FOREIGN KEY klausuler:

CREATE TABLE user(
  id INT(11) NOT NULL AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL,
  password VARCHAR(20) NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE items(
  i_id INT(11) NOT NULL AUTO_INCREMENT,
  name TINYTEXT NOT NULL,
  price DECIMAL(8,2) NOT NULL,
  PRIMARY KEY (i_id)
);

CREATE TABLE user_purchase(
  i_id INT(11) NOT NULL,
  name TINYTEXT NOT NULL,
  id INT(11) NOT NULL,
);
 

Bemærk, at relationsmæssigt er fremmednøglen kolonner er stadig implementeret . Der er en kolonne, der refererer til user tabel (id ) og en anden, der refererer til items tabel (i_id ) -- lad os sætte name kolonne til side et øjeblik. Overvej følgende data:

  user              user_purchase    items
| id  username |    | id  i_id |    | i_id  name            price |
| 23  john     |    | 55   10  |    |  10   chocolate bar    3.42 |
| 55  mary     |    | 70   10  |    |  33   mobile phone    82.11 |
| 70  fred     |    | 70   33  |    |  54   toothpaste       8.67 |
                    | 55   10  |    |  26   toy car          6.00 |
                    | 70   26  |
 

Forholdet er der. Det implementeres ved hjælp af user_purchase tabel, som indeholder oplysninger om hvem købte hvad . Hvis vi skulle forespørge databasen for en relevant rapport, ville vi gøre:

select * from user_purchase p
join user u on (p.id=u.id)
join items i on (p.i_id=i.i_id)
 

Og det er sådan, vi bruger relationen og fremmednøgle kolonner involveret.

Hvad nu hvis vi gør:

insert into user_purchase (id,i_id) values (23,99)
 

Tilsyneladende er dette en ugyldig post. Selvom der er en bruger med id=23 , der er intet element med i_id=99 . RDBMS ville tillade det at ske, fordi det ved ikke bedre . Endnu.

Det er her fremmednøgle begrænsninger komme i spil. Ved at angive FOREIGN KEY (i_id) REFERENCES items(i_id) i user_purchase tabeldefinition, giver vi i det væsentlige RDBMS en regel at følge:indgange med i_id værdier, der ikke er indeholdt i items.i_id kolonne er ikke acceptable . Med andre ord, mens en fremmednøgle kolonne implementerer referencen , en fremmednøgle begrænsning håndhæver henvisningsintegriteten .

Bemærk dog, at ovenstående select ville ikke ændre sig, bare fordi du definerede en FK-begrænsning. Således dig brug ikke FK-begrænsninger, det gør RDBMS for at beskytte dine data.

Afskedigelser

Spørg dig selv:Hvorfor vil du det? Hvis de to fremmednøgler skal tjene det samme formål, vil redundansen i sidste ende få dig i problemer. Overvej følgende data:

 user_purchase                   items
| id  i_id  name           |    | i_id  name            price |
| 55   10   chocolate bar  |    |  10   chocolate bar    3.42 |
| 70   10   chocolate bar  |    |  33   mobile phone    82.11 |
| 70   33   mobile phone   |    |  54   toothpaste       8.67 |
| 55   10   toothpaste     |    |  26   toy car          6.00 |
| 70   26   toy car        |
 

Hvad er der galt med dette billede? Gjorde bruger 55 købe to chokoladebarer, eller en chokoladebar og en tandpasta? Denne form for tvetydighed kan føre til en stor indsats for at holde data synkroniseret, hvilket ville være unødvendigt, hvis vi bare beholdt en af ​​fremmednøglerne. Faktisk, hvorfor ikke droppe name kolonne helt, da det er underforstået af relationen.

Selvfølgelig kunne vi løse dette ved at implementere en sammensat fremmednøgle ved at indstille PRIMARY KEY(i_id,name) for items tabel (eller definere en ekstra UNIQUE(i_id,name) indeks, er det ligegyldigt) og derefter indstille en FOREIGN KEY(i_id,name) REFERENCES items(i_id,name) . På denne måde er det kun (i_id,name) par, der findes i items tabel ville være gyldig for user_purchases . Bortset fra det faktum, at du stadig ville have en fremmednøgle , er denne tilgang fuldstændig unødvendig, forudsat at i_id kolonnen er allerede nok til at identificere et element (kan ikke sige det samme for name kolonne...).

Der er dog ingen regel mod at bruge flere fremmednøgler til en tabel. Faktisk er der omstændigheder, der kræver en sådan tilgang. Overvej en person(id,name) tabel og en parent(person,father,mother) en med følgende data:

person parent | id name | | person father mother | | 14 John | | 21 14 59 | | 43 Jane | | 14 76 43 | | 21 Mike | | 76 Frank | | 59 Mary |

Det er klart, at alle tre kolonner i parent tabel er fremmednøgler til person . Ikke for samme relation , dog, men for tre forskellige :Da en persons forældre også er personer, skal de to tilsvarende kolonner referere til den samme tabel person gør. Bemærk dog, at de tre felter ikke kun kan men også skal henvis anden person er i samme parent række, da ingen er hans egen forælder, og ingens far også er hans mor.



  1. Sådan defineres en auto-inkrement primær nøgle i Oracle

  2. Datamodel for autoværksted

  3. Brug af Laravel Raw Query med pladsholder

  4. auto_increment efter gruppe