Чому таблиця використовує свій первинний ключ як зовнішній ключ до себе


21

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

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

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

Чи є якась причина, щоб це було зроблено?

Стіл приєднався до себе

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


6
Можливо, через кек, яким користувався дизайнер, є моя теорія
Мартін Сміт

Відповіді:


28

Як ви сказали. FOREIGN KEYОбмеження посилань на ту ж таблицю , як правило , для ієрархічної структури , і було б використовувати ще один стовпець для посилання на первинний ключ. Хороший приклад - таблиця працівників:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

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

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

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);

1
Наведення обмеження на ManagerId, що стосується ідентифікатора EmployeeId, у цьому випадку може бути корисним, якби Менеджер був "розділений". Це не дозволить видалити рядок, якщо встановити такий спосіб. Не кажучи, що я це зробив би так, але це могло б мати певну користь, якщо ваша заява покладається на працівників, які мають керівників.
zgr024

6

Я щойно знайшов такий закордонний ключ у власному db, і його, мабуть, сам створив. Я думаю, що це сталося випадково. Якщо я натискаю на "Новий зовнішній ключ" у контекстному меню таблиці з первинним ключем (в Management Studio, SQL 2014 Express), це вже автоматично створює такий зовнішній ключ із посиланням на себе. Дивись нижче:

введіть тут опис зображення

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

Отже, для мене такий Зовнішній ключ не має сенсу і його можна видалити.


Можливо, що ви хотіли створити FK, і в процесі ви зрозумієте, що інша таблиця ще не встановила свій ПК, тому ви скасуєте, перейдіть до іншої таблиці, а потім чомусь забудете продовжувати процес FK. Там у вас є ваш рекурсивний ФК.
Андрій

4

Можливо, дизайнер хотів відключити використання TRUNCATE TABLE?

TRUNCATE TABLEне може бути використаний у таблиці з обмеженням зовнішнього ключа до іншої таблиці, хоча він може бути використаний, якщо є самореференційні зовнішні ключі. З документації для TRUNCATE TABLE (Transact-SQL) :

Екстракт BOL

DELETEЗаява без WHEREзастереження має подібний ефект до TRUNCATE TABLE(видалення всіх рядків в таблиці) , але DELETEоператор запускає ВИДАЛИТИ тригери, які можуть бути причиною , щоб дозволити , DELETEале не TRUNCATE TABLE.

Я би зробив це за допомогою дозволів ( DELETEвимагає дозволу на видалення, TRUNCATE TABLEвимагає дозволу змінити таблицю), але, можливо, є якась причина, що дизайнер не зміг цього зробити?

Примітка: Хоча те, що зробив дизайнер, насправді не виключає використання TRUNCATE TABLE, я все ще припускаю, що це був їхній намір.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.