sql >> Databáze >  >> RDS >> Mysql

Jak používat cizí klíče s PHP

Zjednodušení sloupců/omezení cizího klíče

Za předpokladu, že máte na mysli omezení cizího klíče , stručná odpověď by byla prostě je nepoužíváte .

A tady přichází ten dlouhý:

Jsme zvyklí označovat sloupce za cizí klíče na další stoly. Zejména během procesu normalizace se fráze jako "user_purchase.i_id je cizí klíč k items tabulka" by bylo velmi časté. I když je to dokonale platný způsob, jak popsat vztah, může to být trochu nejasné, když se dostaneme do fáze implementace.

Předpokládejme, že jste své tabulky vytvořili bez FOREIGN KEY klauzule:

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,
);

Všimněte si, že ve vztahu k cizímu klíči sloupce jsou stále implementovány . Je tam sloupec, který odkazuje na user tabulka (id ) a další, který odkazuje na items tabulka (i_id ) -- dodejme name sloup na chvíli stranou. Zvažte následující údaje:

  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  |

Vztah tam je. Je implementován pomocí user_purchase tabulka, která obsahuje informace o tom, kdo co koupil . Pokud bychom v databázi požádali o relevantní zprávu, udělali bychom:

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

A tak používáme vztah a sloupce cizího klíče zapojeni.

A teď, co když uděláme:

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

Zdá se, že se jedná o neplatný záznam. Ačkoli existuje uživatel s id=23 , není zde žádná položka s i_id=99 . RDBMS by to umožnil, protože nezná nic lepšího . Dosud.

To je místo, kde cizí klíč omezuje Pojď do hry. Zadáním položky FOREIGN KEY (i_id) REFERENCES items(i_id) v user_purchase definice tabulky, v podstatě dáváme RDBMS pravidlo, které se má dodržovat:položky s i_id hodnoty, které nejsou obsaženy v items.i_id sloupec nejsou přijatelné . Jinými slovy, zatímco cizí klíč sloupec implementuje odkaz , omezení cizího klíče vynucuje referenční integritu .

Pamatujte však, že výše uvedený select by se nezměnilo jen proto, že jste definovali omezení FK. Tedy vy nepoužívejte omezení FK, to dělá RDBMS, abyste ochránili svá data.

Propouštění

Zeptejte se sami sebe:Proč byste to chtěli? Pokud mají dva cizí klíče sloužit stejnému účelu, redundance vás nakonec dostane do problémů. Zvažte následující údaje:

 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        |

Co je na tomto obrázku špatného? Udělal uživatel 55 koupit dvě čokoládové tyčinky, nebo čokoládovou tyčinku a zubní pastu? Tento druh nejednoznačnosti může vést k velkému úsilí udržovat data v synchronizaci, což by bylo zbytečné, pokud bychom si ponechali pouze jeden z cizích klíčů. Vlastně proč nevypustit name sloupec úplně, protože je implikován vztahem.

Samozřejmě bychom to mohli vyřešit implementací složeného cizího klíče nastavením PRIMARY KEY(i_id,name) pro items tabulka (nebo definování extra UNIQUE(i_id,name) index, na tom opravdu nezáleží) a poté nastavením FOREIGN KEY(i_id,name) REFERENCES items(i_id,name) . Tímto způsobem pouze (i_id,name) páry, které existují v items tabulka bude platná pro user_purchases . Nehledě na to, že by jste ještě měli jednu cizí klíč , je tento přístup zcela zbytečný za předpokladu, že i_id sloupec je již dostatečný k identifikaci položky (nelze říci totéž pro name sloupec...).

Neexistuje však žádné pravidlo proti použití více cizích klíčů v tabulce. Ve skutečnosti existují okolnosti, které takový přístup vyžadují. Zvažte person(id,name) stůl a parent(person,father,mother) jedna s následujícími údaji:

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

Je zřejmé, že všechny tři sloupce parent tabulka jsou cizí klíče pro person . Ne pro stejný vztah , ale pro tři různé :Protože rodiče osoby jsou také osoby, dva odpovídající sloupce musí odkazovat na stejnou tabulku person dělá. Upozorňujeme však, že tato tři pole nejen umí ale také musíte odkazovat na jinou person s ve stejném parent řádek, protože nikdo není jeho vlastním rodičem a nikoho otce není jeho matka.



  1. Jak zvládnout vývoj databáze Play Framework 2 v produkci

  2. Android Sqlite při upgradu odstraňte tabulku z databáze

  3. MYSQL:Tabulka sekvenčních čísel

  4. Jak spravovat uživatelské role v databázi?