sql >> Databasteknik >  >> RDS >> Mysql

Hur man använder främmande nycklar med PHP

Disambiguering av främmande nyckelkolumner/begränsningar

Förutsatt att du hänvisar till restriktioner för främmande nyckel , det korta svaret skulle vara du använder dem bara inte .

Och här kommer den långa:

Vi är vana vid att hänvisa till att kolumner är främmande nycklar till andra bord. Särskilt under normaliseringsprocessen, fraser som "user_purchase.i_id är en främmande nyckel till items tabell" skulle vara mycket vanligt. Även om det är ett helt giltigt sätt att beskriva förhållandet, kan det bli lite flummigt när vi når implementeringsfasen.

Anta att du har skapat dina tabeller utan 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,
);

Lägg märke till att, relationsmässigt, kolumnerna med främmande nyckel är fortfarande implementerade . Det finns en kolumn som refererar till user tabell (id ) och en annan som refererar till items tabell (i_id ) -- låt oss lägga in name kolumnen åt sidan för ett ögonblick. Tänk på följande 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  |

Relationen finns där. Det implementeras med hjälp av user_purchase tabell, som innehåller information om vem som köpte vad . Om vi ​​skulle fråga databasen efter en relevant rapport, skulle vi göra:

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

Och det är så vi använder relationen och kolumnerna med främmande nyckel involverade.

Vad händer nu om vi gör:

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

Tydligen är detta en ogiltig post. Även om det finns en användare med id=23 , det finns inget objekt med i_id=99 . RDBMS skulle tillåta det att hända, eftersom det inte vet bättre . Än.

Det är där främmande nyckel begränsningar komma till spel. Genom att ange FOREIGN KEY (i_id) REFERENCES items(i_id) i user_purchase tabelldefinition ger vi i huvudsak RDBMS en regel att följa:poster med i_id värden som inte finns i items.i_id kolumner är inte acceptabla . Med andra ord, medan en främmande nyckel kolumn implementerar referensen , en främmande nyckel begränsning upprätthåller referensintegriteten .

Observera dock att ovanstående select skulle inte ändras, bara för att du definierade en FK-begränsning. Alltså du använd inte FK-begränsningar, det gör RDBMS för att skydda dina data.

Uppsägningar

Fråga dig själv:Varför skulle du vilja det? Om de två främmande nycklarna ska tjäna samma syfte kommer redundansen så småningom att få dig i trubbel. Tänk på följande 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        |

Vad är det för fel på den här bilden? Gjorde användaren 55 köpa två chokladkakor, eller en chokladkaka och en tandkräm? Denna typ av oklarhet kan leda till mycket ansträngning för att hålla data synkroniserade, vilket skulle vara onödigt om vi bara behöll en av de främmande nycklarna. Faktum är att varför inte släppa name kolumn helt och hållet, eftersom det antyds av relationen.

Naturligtvis skulle vi kunna lösa detta genom att implementera en sammansatt främmande nyckel, genom att ställa in PRIMARY KEY(i_id,name) för items tabell (eller definiera en extra UNIQUE(i_id,name) index, det spelar ingen roll) och ställ sedan in en FOREIGN KEY(i_id,name) REFERENCES items(i_id,name) . På detta sätt är endast (i_id,name) par som finns i items Tabellen skulle vara giltig för user_purchases . Förutom det faktum att du fortfarande skulle ha en främmande nyckel , är detta tillvägagångssätt helt onödigt, förutsatt att i_id kolumnen räcker redan för att identifiera ett objekt (kan inte säga detsamma för name kolumn...).

Det finns dock ingen regel mot att använda flera främmande nycklar till en tabell. Det finns faktiskt omständigheter som kräver ett sådant tillvägagångssätt. Tänk på en person(id,name) tabell och en parent(person,father,mother) en, med följande data:

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

Uppenbarligen alla tre kolumnerna i parent tabellen är främmande nycklar till person . Inte för samma relation , dock, men för tre olika :Eftersom en persons föräldrar också är personer måste de två motsvarande kolumnerna referera till samma tabell person gör. Observera dock att de tre fälten inte bara kan men också måste hänvisa till annan person s i samma parent rad, eftersom ingen är hans egen förälder och ingens far är hans mamma också.



  1. Fråga att sortera efter de tre sista tecknen i en kolumn

  2. Kopiera PostgreSQL-databas till en annan server

  3. Konvertera OracleParameter.Value till Int32

  4. Råd om att använda pivottabellen i Oracle