Почему таблица использует свой первичный ключ как внешний ключ к себе


21

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

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

Поскольку первичный ключ уникален, в этой ситуации строка не сможет указывать только на себя? Кажется, это тавтологическая связь, так как если у меня уже есть строка, то у меня уже есть строка.

Есть ли причина, по которой это будет сделано?

Стол присоединился к себе

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


6
Вероятно, с помощью дурацкого использования дизайнера моя теория
Мартин Смит

Ответы:


28

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

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

Так что в этом случае внешний ключ от таблицы возвращается к себе. Все менеджеры также являются сотрудниками, так что на ManagerIdсамом деле EmployeeIdэто менеджер.

С другой стороны, если вы имеете в виду, что кто-то использовал EmployeeIdвнешний ключ в таблице Employee, то это, вероятно, ошибка . Я выполнил тест, и это возможно, но он не будет иметь никакого реального использования.

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, если Manger будет «отделен». Это не позволило бы удалить строку, если установлено таким образом. Не говоря уж о том, что я бы так поступил, но это могло бы принести пользу, если бы в вашем приложении работали менеджеры.
zgr024

6

Я только что нашел такой внешний ключ в своей собственной базе данных, и, должно быть, он сам создавал его. Я думаю, что это произошло случайно. Если я нажимаю «Новый внешний ключ» в контекстном меню таблицы с первичным ключом (в среде Management Studio, SQL 2014 Express), это уже автоматически создает такой внешний ключ, ссылающийся на себя. Увидеть ниже:

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

Если я тогда не пойму, что мне следует изменить это вместо того, чтобы добавить новое, оно останется там. Или, если я просто нажму кнопку [Закрыть], означающую, что это будет похоже на [Отмена], внешний ключ все равно будет создан после сохранения определения таблицы.

Так что для меня такой внешний ключ не имеет смысла и может быть удален.


Возможно, вы хотели создать FK, и в процессе вы понимаете, что другая таблица еще не установила свой PK, поэтому вы отменяете, переходите к другой таблице, а затем по какой-то причине вы забываете продолжить процесс FK. Там у вас есть свой рекурсивный FK.
Андрей

4

Возможно, дизайнер хотел отключить использование TRUNCATE TABLE?

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

BOL Extract

DELETEЗаявление без WHEREоговорки имеет подобный эффект к TRUNCATE TABLE(удаление всех строк в таблице) , но DELETEоператор запускает УДАЛИТЬ триггеры, которые могут быть причиной , чтобы позволить , DELETEно не TRUNCATE TABLE.

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

Примечание: хотя то, что сделал дизайнер, на самом деле не запрещает его использование TRUNCATE TABLE, я все еще предполагаю, что это было их намерением.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.