Чи можна зробити первинний ключ зовнішнім




Чи можна зробити первинний ключ зовнішнім



Різниця між первинним ключем та зовнішнім ключем

Ключові відмінності між первинним ключем та зовнішнім ключем

  • Обмеження первинного ключа – це стовпець, який унікально ідентифікує кожен рядок у таблиці системи управління реляційною базою даних, а зовнішній ключ – це стовпець, що створює зв'язок між двома таблицями.
  • Первинний ключ ніколи не набуває нульових значень, тоді як зовнішній ключ може набувати кількох нульових значень.
  • У таблиці може бути лише один первинний ключ, а таблиці може бути кілька зовнішніх ключів.
  • Значення первинного ключа не можна видалити з батьківської таблиці, тоді як значення зовнішнього ключа можна видалити із дочірньої таблиці.
  • Жодні два рядки не можуть мати однакові значення первинного ключа; з іншого боку, зовнішній ключ може містити значення, що повторюються.
  • Немає обмежень на вставку значень у стовпець таблиці при вставці будь-якого значення таблицю зовнішнього ключа; переконайтеся, що значення є у стовпці первинного ключа.

Тут я проаналізував різницю між первинним ключем та зовнішнім ключем та всебічно оціню їх плюси та мінуси.

Що таке первинний ключ?

Обмеження первинного ключа - це стовпець або група стовпців, які однозначно ідентифікують кожен рядок у таблиці системи керування реляційною базою даних. Воно не може бути дублікатом, тобто те саме значення не повинно з'являтися в таблиці більше одного разу.

Таблиця не може мати більше одного первинного ключа. первинний ключ може бути визначений на рівні шпальти або таблиці. Якщо ви створюєте складовий первинний ключ, його слід визначити лише на рівні таблиці.

Приклад первинного ключа

Синтаксис:

Нижче наведено синтаксис первинного ключа:

CREATE TABLE (Column1 datatype, Column2 datatype, PRIMARY KEY (Column-Name).);
  • Table_Name — це ім'я таблиці, яку потрібно створити.
  • Column_Name - Ім'я стовпця, що має первинний ключ.

Це критично важливо для аналізу та вибору найбільш ефективних ключових слів для покращення рейтингу вашого сайту.

StudID Рол Ні Ім'я Прізвище Ел. адреса
1 11 Том Ціна [email protected]
2 12 Nick Райт [email protected]
3 13 Dana Натан [email protected]

У наведеному вище прикладі ми створили таблицю студентів зі стовпцями, такими як StudID, Roll No., First Name, Last Name та Email. StudID вибраний як первинний ключ, оскільки він може однозначно ідентифікувати інші рядки в таблиці.

Навіщо використати первинний ключ?

За роки роботи з системами баз даних я помітив такі недоліки та переваги використання первинного ключа:

  • Основною метою первинного ключа є ідентифікація кожного запису в таблиці бази даних.
  • Ви можете використовувати первинний ключ, якщо не дозволяєте будь-кому вводити нульові значення.
  • Якщо ви видалите або оновите записи, буде вжито вказану вами дію для забезпечення цілісності даних.
  • Виконайте операцію обмеження, щоб відхилити операцію видалення або оновлення батьківської таблиці.
  • При фізичної організації таблиці СУБД дані організуються у послідовність кластеризованих індексів.

СТАТТІ ЗА ТЕМОЮ

Що таке ключ?

Зовнішній ключ – це стовпець, що створює зв'язок між двома таблицями. Мета зовнішнього ключа – підтримувати цілісність даних та забезпечувати навігацію між двома різними екземплярами об'єкта. Він діє як перехресне посилання між двома таблицями, оскільки посилається на первинний ключ іншої таблиці. Кожне відношення у базі даних має підтримуватись зовнішнім ключем.

Приклад зовнішнього ключа

Синтаксис:

Нижче наведено синтаксис зовнішнього ключа:

CREATE TABLE (column1 datatype, column2 datatype, constraint (name of constraint) FOREIGN KEY [column1, column2.] REFERENCES [primary key table name] (List of primary key table column) .
  • Параметр Ім'я таблиці вказує ім'я таблиці, яку ви маєте намір створити.
  • Параметри стовпець1, стовпець2... позначають стовпці, які потрібно додати до таблиці.
  • Обмеження означає ім'я створюваного вами обмеження.
  • Посилання вказують на таблицю з первинним ключем.

Це критично важливо для аналізу та вибору найбільш ефективних ключових слів для покращення рейтингу вашого сайту.

Ідентифікатор вчителя Ім'я Ім'я
B002 Давид Сигналізатор
B017 Сара Джозеф
B009 Майк Брантон

У наведеному вище прикладі ми маємо дві таблиці: вчитель та факультет у школі. Однак немає можливості побачити, який пошук у якому відділі працює.

У цій таблиці, додавши зовнішній ключ Deptcode до імені вчителя, ми можемо створити зв'язок між двома таблицями.

Ідентифікатор вчителя Код відділу Ім'я Ім'я
B002 002 Давид Сигналізатор
B017 002 Сара Джозеф
B009 001 Майк Брантон

Ця концепція також відома як посилальна цілісність.

Для чого використовувати зовнішній ключ?

З того, що я бачив, ось важливі причини для реалізації зовнішніх ключів:

  • Зовнішні ключі допомагають вам мігрувати сутності, використовуючи первинний ключ із батьківської таблиці.
  • A зовнішній ключ дозволяє зв'язати дві або більше таблиць разом.
  • Це робить дані вашої бази даних узгодженими.
  • Зовнішній ключ можна використовувати для зіставлення стовпця або комбінації стовпців із первинним ключем у батьківській таблиці.
  • Обмеження зовнішнього ключа SQL використовується для забезпечення відповідності цілісності батьківських даних значенням у дочірній таблиці.

Різниця між первинним ключем та зовнішнім ключем

Дозвольте мені розповісти про важливу різницю між первинним ключем і зовнішнім ключем, яку я відчув на власному досвіді:

Первинний ключ проти зовнішнього ключа

Основа порівняння Основний ключ Зовнішній ключ
Визначення Обмеження первинного ключа - це стовпець або група стовпців, які однозначно ідентифікують кожен рядок таблиці. система керування реляційними базами даних. Зовнішній ключ – це стовпець, що створює зв'язок між двома таблицями.
Базовий Це допоможе вам однозначно ідентифікувати запис у таблиці. Це поле таблиці, що є первинним ключем іншої таблиці.
NULL, Первинний ключ ніколи не набуває нульових значень. Зовнішній ключ може набувати кількох нульових значень.
Індексування Первинний ключ є кластеризований індекс, а дані в таблиці СУБД фізично організовані в послідовності кластеризованого індексу. Зовнішній ключ не може автоматично створити індекс, кластеризований чи некластеризований.
Кількість У таблиці може бути первинний ключ. У таблиці може бути кілька ключів.
видалення Значення первинного ключа може бути видалено з батьківської таблиці. Значення зовнішнього ключа можна видалити із дочірньої таблиці.
Тимчасовий стіл Ви можете явно визначити первинний ключ у тимчасових таблицях. Ви не можете визначити зовнішні ключі у локальних або глобальних часових таблицях.
Спорідненість Первинний ключ – це кластеризований індекс. За умовчанням це кластеризований індекс.
дуплікація Жодні два рядки не можуть мати однакового значення первинного ключа. Зовнішній ключ може містити значення, що повторюються.
Внесені Немає обмежень на вставку значень у стовпчик таблиці. При вставці будь-якого значення в таблицю зовнішнього ключа переконайтеся, що це значення є у стовпці первинного ключа.

Як вибрати між первинним ключем та зовнішнім ключем

Зважаючи на те, що ми бачили, первинні ключі однозначно ідентифікують записи таблиці, а зовнішні ключі пов'язують ці записи між таблицями, що критично важливо для підтримки цілісності даних та полегшення ефективного пошуку даних.

Ви могли б:

Первинний та зовнішній ключі PostgreSQL

Стаття заснована на третьому відео із 30 тем курсу SQL c 0 від Арістова Євгена. Посилання на відео на платформах RUTUBE та VK відео.

У цій статті розберемо первинні та зовнішні ключі у PostgreSQL.

Первинний ключ

  1. Унікальність: Первинний ключ гарантує унікальність кожного запису таблиці. Кожен рядок повинен мати унікальне значення первинного ключа, що допомагає ідентифікувати конкретний запис однозначно.
  2. Упорядкованість: Первинний ключ також визначає впорядкованість записів у таблиці. Це може бути корисним при виконанні запитів або сортуванні даних за первинним ключем.
  3. Індексація: За замовчуванням у більшості СУБД створюється індекс для первинного ключа

Якщо говорити про штучний ключ (1, 2, 3 і т.д.), то за номером приблизно зрозуміло, коли було створено той чи інший запис.

Що стосується UUID, то зазвичай це не так, проте існує UUID 7 версії, який нумерує записи щодо порядку. UUID за замовчуванням забезпечує унікальність, але він більший за розміром, тому потрібно більше часу на його генерацію (знижується продуктивність), також збільшуються зовнішні ключі (більше індексів).

Плюси UUID – унікальність та безпека. Мінуси – швидкість роботи з ним та обсяг інформації, що зберігається.

UUID можна замінити класичним довідником. Можна використовувати в розрахункових даних та master-master реплікації (але краще генерувати послідовність зі зсувом)

Приклад використання ключів

Розглянемо таблиці з товарами та продажами. У таблицю із продажами записується не назва товару, а зовнішній ключ (посилання на товар).

По-перше, зовнішній ключ займає значно менше місця, оскільки є числом.

По-друге, при зміні даних у батьківській таблиці, дочірні оновлюватимуться автоматично, не потрібно змінювати значення зовнішнього ключа у всіх пов'язаних таблицях.

По-третє, до таблиці Продаж не можна додати продаж неіснуючого товару (того, якого немає в таблиці Товари). Номери у зовнішньому ключі завжди повинні бути у батьківській таблиці.

Також існує каскадне видалення та оновлення даних. При зміні ключа у яблук з “1” на “5” (таблиця Товари) у дочірній таблиці Продаж ключ змінюється автоматично.Аналогічно, при видаленні яблук зі списку товарів віддаляться всі продажі з ними. Рекомендується ставити distinct на каскадне видалення, оскільки може призвести до втрати даних. В даному прикладі, якщо магазин більше не продає яблука, це не означає, що всі дані з ними повинні бути видалені з фінансових звітів.

Природний та штучний ключі

Первинний ключ може бути штучним – sequence – послідовність. Робота з нею обговорюватиметься у наступній лекції. Також може бути і природним, наприклад, ІПН, державний номер машини і т.д.

Зазвичай штучний ключ важить 4 байти (int від -2 млрд до +2 млрд), а природний 8 байт (текстова змінна).

З плюсів можна відзначити, що людині легше працювати з природним ключем, так як використовуються вже існуючі дані (атрибути), що дають смислову інформацію.

Але є й низка недоліків. Природний ключ може повторити помилку оператора. Також природний ключ може змінити власника (наприклад, номер телефону). Зміна природного ключа також викликає проблеми (через каскадне оновлення). Тому використовувати його не рекомендується.

Зазвичай, штучним ключем є автоінкрементоване поле “ID”.

Штучний ключ генерується самим PostgreSQL. У той же час генерацією UUID займається операційна система, тому це потребує більше часу.

Штучний ключ забезпечує унікальність без посилання на комбінацію атрибутів. Він більш стабільний, оскільки змінюється при зміні інших даних.

Очевидний недолік – відсутність зв'язку із даними. Штучний ключ не інформативний для користувача через відсутність смислової інформації. Можуть бути потрібні додаткові зусилля при встановленні зв'язків між таблицями.

Послідовність ключів (стандартний int) починається з одиниці, закінчується двома мільярдами (оскільки PostgreSQL немає типу даних unsigned int).Якщо планується більше записів, необхідно змінити тип первинного ключа і типи всіх зовнішніх ключів, які посилаються нею, на big integer . Інакше станеться помилка через дублювання записів, оскільки після 2 млрд. послідовність знову почнеться з одиниці.

Є ще два варіанти вирішення проблеми із нестачею первинних ключів. По-перше, можна пошукати "дірки" у послідовності. Вони з'являються, коли ключі резервуються під дані (з допомогою транзакцій), але записи за підсумком не створюються (rollback).

По-друге, можна розпочати послідовність ключів не з 1, а з -2 млрд. У цьому випадку потрібно звернути увагу, чи нормально обробляються такі ключі у вашому софті.

Зовнішній ключ

Зовнішній ключ завжди посилається на первинний.

  1. Збереження цілісності даних: Зовнішні ключі гарантують, що дані, що зберігаються в стовпці, пов'язаному із зовнішнім ключем, завжди посилаються на існуючі коректні записи в іншій таблиці.
  2. Зв'язки між таблицями: Зовнішній ключ встановлює зв'язок між двома таблицями, дозволяючи створювати зв'язки один-до-одному, один-до-багатьом або багато-багатьом між даними в різних таблицях. Докладніше про зв'язки тут.
  3. Поліпшення продуктивності: Індекси, що створюються для зовнішніх ключів, допомагають прискорити виконання операцій з'єднання таблиць (join) та пошуку даних (select).
  4. Забезпечення узгодженості операцій: Використання зовнішніх ключів допомагає гарантувати узгодженість операцій між пов'язаними таблицями. Наприклад, при видаленні запису з батьківської таблиці можна автоматично видалити або оновити пов'язані записи в дочірній таблиці (вище рекомендувалося забороняти каскадне видалення та оновлення).

Зазвичай зовнішній ключ також створюється індекс.

Правила роботи із зовнішнім ключем

Рекомендується створювати такого ж типу даних, як і в батьківській таблиці. Vоже бути й різного, але приводного типу (наприклад, integer -> biginteger). Головне, щоб відповідав діапазон та зберігалася унікальність.

Існують правила іменування ключів:

  • У батьківській таблиці створюється поле id
  • У дочірній fk_ім'я_батьківської_таблиці (fk – скорочення від foreigh key)

Приклад на основі таблиць з товарами та продажами:

Зазвичай у літературі рекомендують іменувати goodID і goodID_fk.

Спосіб менш зручний, тому що:

  • не відразу видно, що поле є зовнішнім ключем, побачимо це тільки в кінці поля
  • при повній вказівці в запиті з використанням імені таблиці вийде олія - ​​goods.goodID, замість goods.id, також при з'єднанні - sales.goodID_fk = goods.goodID, в моєму варіанті sales.fk_goods = goods.id - більш коротко і очевидно

Категорично не рекомендується називати зовнішній ключ без fk.

Зверніть увагу, що я припустився неточності при назві таблиць - в чому вона полягає, розглянемо в 11 темі.

Презентація до статті тут.

Четверта з 30 тем буде незабаром доступна. Якщо ви хочете швидше отримати доступ – приєднуйтесь до онлайн-групи, посилання доступне в описі курсу.

Первинний та зовнішній ключ SQL

Зі статті ви дізнаєтеся, що таке первинний та зовнішній ключ у SQL. Навіщо вони потрібні та як їх використовувати. Я покажу на практиці як їх використовувати у PostgreSQL.

Теорія

Первинний ключ - це одне або кілька полів у таблиці. Він потрібний для унікальної ідентифікації будь-якого рядка. Первинний ключ накладає деякі обмеження:

  • Усі записи, що стосуються первинного ключа, повинні бути унікальними. Це означає, що якщо первинний ключ складається з одного поля, всі записи в ньому повинні бути унікальними. А якщо первинний ключ складається з кількох полів, то комбінація цих записів має бути унікальною, але в окремих полях допускаються повторення.
  • Записи в полях, що належать до первинного ключа, не можуть бути порожніми. Це обмеження у PostgreSQL називається not null.
  • У кожній таблиці може бути лише один первинний ключ.

До первинного ключа висувають таку вимогу:

  • Первинний ключ має бути мінімально достатнім.Тобто в ньому не повинно бути полів, видалення яких з первинного ключа не вплине на його унікальність. Це не обов'язкова вимога, але бажано її дотримуватися.

Первинний ключ може бути:

  • природним - існує в реальному світі, наприклад ПІБ, або номер та серія паспорта;
  • сурогатним — не існує в реальному світі, наприклад, якийсь порядковий номер, який існує лише в базі даних.

Я сам не маю великого досвіду роботи з SQL, але в книгах пишуть, що краще використовувати природний первинний ключ. Чому саме так, я поки що відповісти не зможу.

Зв'язок між таблицями

Першорядне завдання первинного ключа - Це унікальна ідентифікація кожного рядка. Але первинний ключ може вирішити ще одне завдання. У базі даних є можливість зв'язування кількох таблиць. Для такого зв'язку використовують первинний та зовнішній ключ sql. В одній із таблиць створюють зовнішній ключякий посилається на поля іншої таблиці. Але зовнішній ключ не може посилатися на будь-які поля іншої таблиці, а може посилатися лише на певні:

  • ці поля повинні бути присутніми і в таблиці, що посилається, і в тій таблиці на яку він посилається;
  • посилається зовнішній ключ з однієї таблиці зазвичай первинний ключ інший таблиці.

Наприклад, у вас є таблиця «Учні» (pupils) і виглядає вона так:

ПІБ
full_name
Вік
age
Клас
class
Іванов Іван Іванович15
Сумкін Федір Андрійович 15
Петров Олексій Миколайович14
Булгаков Олександр Геннадійович14

І є таблиця «Успішність» (evaluations):

Предмет
item
ПІБ
full_name
Оцінка
evaluation
Російська мова Іванов Іван Іванович4
Російська мова Петров Олексій Миколайович5
Математика Булгаков Олександр Геннадійович3
Література Сумкін Федір Андрійович5

В обох таблицях є однакове поле: ПІБ. При цьому у таблиці «Успішність» не може утримуватися ПІБ, якого немає в таблиці « Учні«. Адже не можна поставити учневі оцінку, якого немає.

Первинним ключем у нашому випадку може виступати поле «ПІБ» у таблиці « Учні«. А зовнішнім ключем буде «ПІБ» у таблиці «Успішність«. При цьому якщо ми видаляємо запис про якогось учня з таблиці «Учні", то всі його оцінки теж повинні піти з таблиці "Успішність«.

Ще варто зауважити що первинний ключ у PostgreSQL автоматично створює індекс. Індекс прискорює доступ до рядків таблиці та накладає обмеження на унікальність. Тобто двох Іванових Іванів Івановичів ми не можемо існувати. Щоб це обійти, можна використовувати:

  • складовий первинний ключ — наприклад, як первинний ключ взяти два поля: ПІБ і Клас;
  • сурогатний первинний ключ - у таблиці "Учні" додати поле "№ Учня" і зробити це поле первинним ключем;
  • додати більш унікальне поле — наприклад, можна використовувати унікальний номер залікової книжки та використовувати нове поле як первинний ключ;

Тепер спробуємо створити ці дві таблички і спробуємо з ними попрацювати.

Практика

Створимо базу даних school і підключимося до неї. Потім створимо таблицю pupils. Про створення таблиць вже писав тут, а про типи даних тут. Потім подивимося на табличку за допомогою команди \d:

postgres=# CREATE DATABASE school; CREATE DATABASE postgres=# \c school Ви вже зараз під'єднуємось до 데이터베이스 "school" як user "postgres". school=# CREATE TABLE pupils (full_name text, age integer, class varchar(3), PRIMARY KEY (full_name) ); CREATE TABLE school=# \dt pupils List of relations Schema | Name | Тип | Owner --------+--------+-------+---------- public | pupils | table | postgres (1 row) school=# \d pupils Table "public.pupils" Column | Тип | Collation | Nullable | Default -----------+----------------------+-----------+-- --------+--------- full_name | Text | | not null | age | integer | | | class | character varying(3) | | | Indexes: "pupils_pkey" PRIMARY KEY, btree (full_name)

Як ви могли помітити, первинний ключ створюється за допомогою конструкції PRIMARY KEY (ім'я поля) у момент створення таблиці.

Виведення команди \d нам показав, що в таблиці є первинний ключ. А також первинний ключ зробив два обмеження:

  • поле full_name, до якого відноситься первинний ключ не може бути порожнім, це видно в колонки Nullablenot null;
  • для поля full_name було створено індекс pupils_pkey з типом btree. Про типи індексів та про самі індекси розповім в іншій статті.

Індекс у свою чергу наклав ще одне обмеження – записи у полі full_name мають бути унікальні.

Наступним кроком створимо таблицю evaluations:

school=# CREATE TABLE evaluations (item text, full_name text, evaluation integer, FOREIGN KEY (full_name) REFERENCES pupils ON DELETE CASCADE ); CREATE TABLE school=# \d evaluations Table "public.evaluations" Column | Тип | Collation | Nullable | Default ------------+---------+-----------+----------+--- ------ item | Text | | | full_name | Text | | | evaluation | integer | | | Foreign-key constraints: "evaluations_full_name_fkey" FOREIGN KEY (full_name) REFERENCES pupils(full_name) ON DELETE CASCADE

В цьому випадку з висновку команди \d ви побачите, що створився зовнішній ключ (Foreign-key), який відноситься до поля full_name та посилається на таблицю pupils.

Зовнішній ключ створюється за допомогою конструкції FOREIGN KEY (назва_поля) REFERENCES таблиця_на_яку_посилаються.

Створюючи зовнішній ключ, ми додатково вказали опцію ON DELETE CASCADE. Це означає, що при видаленні рядка з певним учнем у таблиці pupilsвсі рядки пов'язані з цим учнем видаляться і в таблиці evaluations автоматично.

Заповнення таблиць та робота з ними

Заповнимо таблицю «pupils«:

school=# INSERT into pupils (full_name, age, class) VALUES ('Іванов Іван Іванович', 15, '9A'), ('Сумкін Федір Андрійович', 15, '9A'), ('Петров Олексій Миколайович', 14 , '8B'), ('Булгаков Олександр Геннадійович', 14, '8B'); INSERT 0 4

Заповнимо таблицю «evaluations«:

school=# INSERT into evaluations (item, full_name, evaluation) VALUES ('Російська мова', 'Іванов Іван Іванович', 4), ('Російська мова', 'Петров Олексій Миколайович', 5), ('Математика', ' Булгаков Олександр Геннадійович', 3), ('Література', 'Сумкін Федір Андрійович', 5); INSERT 0 4

А тепер спробуємо поставити оцінку не існуючому учневі:

school=# INSERT into evaluations (item, full_name, evaluation) VALUES ('Російська мова', 'Угаров Віктор Михайлович', 3); ERROR: insert або update on table "evaluations" violates foreign key constraint "evaluations_full_name_fkey" DETAIL: Key (full_name)=(Угаров Віктор Михайлович) is not present in table "pupils".

Як бачите, ми зазнали помилки. Вставляти (insert) або змінювати (update) у таблиці evaluations, у полі full_name можна тільки ті значення, які є в цьому ж полі у таблиці pupils.

Тепер видалимо якогось учня з таблиці pupils:

school=# delete from pupils WHERE full_name = 'Іванов Іван Іванович'; DELETE 1

І подивимося на рядки у таблиці evaluations:

school=# SELECT * FROM evaluations; item | full_name | evaluation --------------+--------------------------------+- ----------- Російська мова | Петров Олексій Миколайович | 5 Математика | Булгаков Олександр Геннадійович | 3 Література | Сумкін Федір Андрійович | 5 (3 rows)

Як видно, рядок з full_name рівна 'Іванов Іван Іванович' теж пішла. Якби в Іванова було б більше оцінок, вони все одно б удалилися. За це, якщо пам'ятаєте відповідає опція ON DELETE CASCADE.

Спробуємо тепер створити учня з таким самим ПІБ, як у одного з існуючих:

school=# INSERT в pupils (full_name, age, class) VALUES ('Петров Олексій Миколайович',15, '5B'); ERROR: duplicate key value violates unique constraint "pupils_pkey" DETAIL: Key (full_name)=(Петров Олексій Миколайович) already exists.

Нічого не вийшло, тому що такий запис вже існує у полі full_name, а це поле має індекс.Значить значення у ньому мають бути унікальні.

Складовий первинний ключ

Є велика ймовірність, що в одній школі навчатимуться два учні з однаковим ПІБ. Але менше ймовірності, що ці два учні навчатимуться в одному класі. Тому як первинний ключ ми можемо взяти два поля, наприклад full_name і class.

Давайте видалимо наші таблички і створимо їх заново, але тепер створимо їх використовуючи складовий первинний ключ:

school=# DROP table evaluations; DROP TABLE school=# DROP table pupils; DROP TABLE school=# CREATE TABLE pupils (full_name text, age integer, class varchar(3), PRIMARY KEY (full_name, class) ); CREATE TABLE school=# CREATE TABLE evaluations (item text, full_name text, class varchar(3), evaluation integer, FOREIGN KEY (full_name, class) REFERENCES pupils ON DELETE CASCADE ); CREATE TABLE

Як ви могли помітити, різниця не велика. Ми повинні в PRIMARY KEY вказати два поля замість одного. І в FOREIGN KEY точно також вказати два поля замість одного. Ну і не забудьте у таблиці evaluations при створенні додати поле class, тому що його там у попередньому варіанті не було.

Тепер подивимося на структури цих таблиць:

school=# \d pupils Table "public.pupils" Column | Тип | Collation | Nullable | Default -----------+----------------------+-----------+-- --------+--------- full_name | Text | | not null | age | integer | | | class | character varying(3) | | not null | Indexes: "pupils_pkey" PRIMARY KEY, btree (full_name, class) Referenced by: TABLE "evaluations" CONSTRAINT "evaluations_full_name_class_fkey" FOREIGN KEY (full_name, class) public.evaluations" Column | Тип | Collation | Nullable | Default ------------+----------------------+-----------+- ---------+--------- item | Text | | | full_name | Text | | | class | character varying(3) | | | evaluation | integer | | | Foreign-key constraints: "evaluations_full_name_class_fkey" FOREIGN KEY (full_name, class) REFERENCES pupils(full_name, class) ON DELETE CASCADE

Первинний ключ у таблиці pupils вже складається з двох полів, тому зовнішній ключ посилається ці два поля.

Тепер ми можемо учнів з однаковим ПІБ вбити в нашу базу даних, але за умови, що вони навчатимуться в різних класах:

school=# INSERT INTO pupils (full_name, age, class) VALUES ('Гришина Ольга Костянтинівна', 12, '5A'), ('Гришина Ольга Костянтинівна', 14, '7B'); INSERT 0 2 school=# SELECT * FROM pupils; full_name | age | class ------------------------------+-----+------- Гришина Ольга Костянтинівна | 12 | 5A Гришина Ольга Костянтинівна | 14 | 7B (2 rows)

І також за другою таблицею:

school=# INSERT INTO evaluations (item, full_name, class, evaluation) VALUES ('Російська мова', 'Гришина Ольга Костянтинівна', '5A', 5), ('Російська мова', 'Гришина Ольга Костянтинівна', '7B' 3); INSERT 0 2 school=# SELECT * FROM evaluations; item | full_name | class | evaluation --------------+------------------------------+--- ----+------------ Російська мова | Гришина Ольга Костянтинівна | 5A | 5 Російська мова | Гришина Ольга Костянтинівна | 7B | 3 (2 rows)

Видалення таблиць

До речі, видалити таблицю, на яку посилається інша таблиця, ви не зможете:

school=# DROP table pupils; ERROR: неможна зменшити table pupils тому що інші об'єкти залежать від нього. CASCADE натиснути на depending objects too.

Тому видалимо наші таблиці у такому порядку:

school=# DROP table evaluations; DROP TABLE school=# DROP table pupils; DROP TABLE

Або ми могли видалити каскадно таблицю pupils разом з зовнішнім ключем у таблиці evaluations:

school=# CREATE TABLE pupils (full_name, age integer, class varchar(3), PRIMARY KEY (full_name, class) ); CREATE TABLE school=# CREATE TABLE evaluations (item text, full_name text, class varchar(3), evaluation integer, FOREIGN KEY (full_name, class) REFERENCES pupils ON DELETE CASCADE ); school=# DROP TABLE pupils CASCADE; NOTICE: скасування каскадів до заборони evaluations_full_name_class_fkey on table evaluations DROP TABLE school=# \d List of relations Schema | Name | Тип | Owner --------+-------------+-------+---------- public | evaluations | table | postgres (1 row) school=# \d evaluations Table "public.evaluations" Column | Тип | Collation | Nullable | Default ------------+----------------------+-----------+- ---------+--------- item | Text | | | full_name | Text | | | class | character varying(3) | | | evaluation | integer | | |

Як видно з прикладу, після каскадного видалення у нас разом із таблицею pupils вдався зовнішній ключ у таблиці evaluations.

Створення зв'язку у вже існуючих таблицях

Вище я постійно створював первинний та зовнішній ключі під час створення таблиці. Але їх можна створювати і для таблиць.

Спочатку видалимо таблицю, що залишилася:

school=# DROP table evaluations; DROP TABLE

І зробимо таблиці без ключів:

school=# CREATE TABLE pupils (full_name text, age integer, class varchar(3) ); CREATE TABLE school=# CREATE TABLE evaluations (item text, full_name text, class varchar(3), evaluation integer ); CREATE TABLE

Тепер створимо первинний ключ у таблиці pupils:

school=# ALTER TABLE pupils ADD PRIMARY KEY (full_name, class); ALTER TABLE

І створимо зовнішній ключ у таблиці evaluations:

school=# ALTER TABLE evaluations ADD FOREIGN KEY (full_name, class) REFERENCES pupils ON DELETE CASCADE; ALTER TABLE

Подивимося, що в нас вийшло:

school=# \d pupils Table "public.pupils" Column | Тип | Collation | Nullable | Default -----------+----------------------+-----------+-- --------+--------- full_name | Text | | not null | age | integer | | | class | character varying(3) | | not null | Indexes: "pupils_pkey" PRIMARY KEY, btree (full_name, class) Referenced by: TABLE "evaluations" CONSTRAINT "evaluations_full_name_class_fkey" FOREIGN KEY (full_name, class) public.evaluations" Column | Тип | Collation | Nullable | Default ------------+----------------------+-----------+- ---------+--------- item | Text | | | full_name | Text | | | class | character varying(3) | | | evaluation | integer | | | Foreign-key constraints: "evaluations_full_name_class_fkey" FOREIGN KEY (full_name, class) REFERENCES pupils(full_name, class) ON DELETE CASCADE

Підсумок

У цій статті я розповів про первинний та зовнішній ключ SQL. А також продемонстрував, як можна створити зв'язані між собою таблиці та як створити зв'язок між вже існуючими таблицями. Ви дізналися, які обмеження накладає первинний ключ та які завдання він вирішує. До того ж, які вимоги пред'являються до нього. Разом з тим, я показав вам як працювати зі складовим первинним ключем.

Додатково про первинний та зовнішній ключ SQL можна почитати тут.

Схожі статті

  • Антибрик для корів Як зробити своїми руками Як правильно сплутати корову щоб можна було подоїти
  • Чи можна самому зробити електроепіляцію
  • Чи можна зробити поляризацію на окуляри
  • Що можна зробити з картриджами
  • Який можна зробити манікюр 11 років
  • Що можна зробити з повітряно пухирчастої плівки
  • Що можна зробити якщо скрипить підлогу
  • Які вироби можна зробити з тирси
  • Недавні статті

  • Як бродить зернова брага
  • Що робити якщо не засмагаєш на сонці чому засмага погано лягає на шкіру або перестає прилипати
  • Як швидко зняти гель лак без апарату
  • Як робиться Каті голови
  • Яка гребінець краще для об'єму
  • Чим роблять м'яку покрівлю
  • Чи можна залишати крем для обличчя на ніч
  • Де знаходиться датчик селектора
  • географія нашої діяльності
    вулиця Драгоманова, 27
    вул. Курчатова 1Б
    вул. Міцкевича 130
    вул. Лабунського, 1
    вул. Макарова-Пржевальського
    вул. Толстого 10
    вул. Грушевського 28
    вул. Перший промінь (Черняхівського)
    напишіть нам

    сообщение успешно отправлено
    x