Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да използвате външни ключове с PHP

Определяне на недвусмислени колони/ограничения за външни ключове

Ако приемем, че имате предвид ограниченията на външния ключ , краткият отговор би бил просто не ги използвате .

И тук идва дългият:

Свикнали сме да наричаме колоните като външни ключове към други маси. Особено по време на процеса на нормализиране, фрази като "user_purchase.i_id е външен ключ към items маса" би било много често. Въпреки че това е напълно валиден начин да се опише връзката, тя може да стане малко размита, когато достигнем фазата на внедряване.

Да предположим, че сте създали своите таблици без FOREIGN KEY клаузи:

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

Забележете, че по отношение на връзката външният ключ колони все още се прилагат . Има колона, която препраща към user таблица (id ) и друг, който препраща към items таблица (i_id ) -- нека поставим name колоната настрана за момент. Помислете за следните данни:

  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  |

Връзката е налице. Реализира се с помощта на user_purchase таблица, която съдържа информация за кой какво е купил . Ако трябва да запитаме базата данни за съответен отчет, бихме направили:

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

И така използваме релацията и колони на външния ключ участва.

Ами ако го направим:

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

Очевидно това е невалиден запис. Въпреки че има потребител с id=23 , няма елемент с i_id=99 . RDBMS ще позволи това да се случи, защото не знае нищо по-добре . Още.

Това е мястото, където ограниченията на външния ключ влезе в игра. Чрез посочване на FOREIGN KEY (i_id) REFERENCES items(i_id) в user_purchase дефиниране на таблица, ние по същество даваме на RDBMS правило, което да следва:записи с i_id стойности, които не се съдържат в items.i_id колона не са приемливи . С други думи, докато външен ключ колона прилага препратката , ограничение за външен ключ налага референтната цялост .

Имайте предвид обаче, че горният select няма да се промени, само защото сте дефинирали FK ограничение. И така, вие не използвайте FK ограничения, RDBMS го прави, за да защитите вашите данни.

Съкращения

Запитайте се:Защо бихте искали това? Ако двата външни ключа трябва да служат за една и съща цел, излишъкът в крайна сметка ще ви създаде проблеми. Помислете за следните данни:

 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        |

Какво не е наред с тази снимка? Потребителят 55 купи две шоколадови блокчета или шоколад и паста за зъби? Този вид неяснота може да доведе до много усилия за поддържане на синхронизиране на данните, което би било ненужно, ако просто запазим един от външните ключове. Всъщност защо не пуснете name колона като цяло, тъй като се подразбира от релацията.

Разбира се, бихме могли да разрешим това, като внедрим композитен външен ключ, като зададем PRIMARY KEY(i_id,name) за items таблица (или дефиниране на допълнителен UNIQUE(i_id,name)). индекс, това всъщност няма значение) и след това задаване на FOREIGN KEY(i_id,name) REFERENCES items(i_id,name) . По този начин само (i_id,name) двойки, които съществуват в items таблицата ще бъде валидна за user_purchases . Отделно от това, че все пак ще имашен външен ключ , този подход е напълно ненужен, при условие че i_id колоната вече е достатъчна за идентифициране на елемент (не може да се каже същото за name колона...).

Въпреки това, няма правило срещу използването на множество външни ключове към таблица. Всъщност има обстоятелства, които изискват такъв подход. Помислете за person(id,name) таблица и parent(person,father,mother) едно, със следните данни:

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

Очевидно и трите колони на parent таблицата са външни ключове за person . Не за същата връзка , но за три различни :Тъй като родителите на дадено лице също са лица, двете съответни колони трябва да препращат към една и съща таблица person прави. Имайте предвид обаче, че трите полета не само могат но също така трябва препращане към различен person е в същия parent ред, тъй като никой не е негов собствен родител и нечий баща е и негова майка.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. bind_param() е необходим само за въведени от потребителя стойности или всички?

  2. Проектиране на база данни за разработване на уеб приложение "Quiz" с помощта на PHP и MySQL

  3. Синтактична грешка на SQL близо до desc

  4. Как да форматирате низове на SQL IN клауза с Python

  5. Метод за цитиране на PDO