Может ли внешний ключ ссылаться на первичный ключ в той же таблице?
Я просто думаю, что ответ ложный, потому что внешний ключ не обладает свойством uniqueness
.
Но некоторые люди говорили, что это может быть в случае самостоятельного присоединения к столу. Я новичок в SQL
. Если это правда, пожалуйста, объясните, как и почему?
Employee table
| e_id | e_name | e_sala | d_id |
|---- |------- |----- |--------|
| 1 | Tom | 50K | A |
| 2 | Billy | 15K | A |
| 3 | Bucky | 15K | B |
department table
| d_id | d_name |
|---- |------- |
| A | XXX |
| B | YYY |
Теперь d_id - это внешний ключ, так как он может быть первичным ключом. И объяснить что-то о join
Каково его использование?
Ответы
Ответ 1
Я думаю, что вопрос немного сбивает с толку.
Если вы имеете в виду "может ли внешний ключ" ссылаться "на первичный ключ в той же таблице?", То ответ будет твердым "да", как ответили некоторые. Например, в таблице сотрудников строка для сотрудника может иметь столбец для хранения номера сотрудника менеджера, где менеджер также является сотрудником и, следовательно, будет иметь строку в таблице, как строка любого другого сотрудника.
Если вы имеете в виду "может ли столбец (или набор столбцов) быть первичным ключом, а также внешним ключом в той же таблице?", Ответ, на мой взгляд, - нет; это кажется бессмысленным. Однако следующее определение успешно выполняется в SQL Server!
create table t1(c1 int not null primary key foreign key references t1(c1))
Но я думаю, что бессмысленно иметь такое ограничение, если кто-то не придумает практический пример.
AmanS, в вашем примере d_id ни при каких условиях не может быть первичным ключом в таблице Employee. Таблица может иметь только один первичный ключ. Я надеюсь, что это очистит ваши сомнения. d_id является/может быть первичным ключом только в таблице отделов.
Ответ 2
Конечно, почему нет? Допустим, у вас есть таблица Person
с id
, name
, age
и parent_id
, где parent_id
- это внешний ключ к той же таблице. Вам не нужно было бы нормализовать таблицу Person
для Parent
и Child
таблиц, это было бы излишним.
Person
| id | name | age | parent_id |
|----|-------|-----|-----------|
| 1 | Tom | 50 | null |
| 2 | Billy | 15 | 1 |
Что-то вроде этого.
Я предполагаю, что для обеспечения согласованности должно быть хотя бы parent_id
нулевое значение для parent_id
. Один "альфа мужской" ряд.
РЕДАКТИРОВАТЬ: Как показывают комментарии, Сэм нашел вескую причину не делать этого. Кажется, что в MySQL, когда вы пытаетесь внести изменения в первичный ключ, даже если вы укажете CASCADE ON UPDATE
он не будет правильно редактировать. Хотя первичные ключи (как правило) запрещены для редактирования в производстве, тем не менее, это ограничение, которое нельзя игнорировать. Таким образом, я изменяю свой ответ на: - вам, вероятно, следует избегать этой практики, если вы не обладаете достаточно жестким контролем над производственной системой (и не можете гарантировать, что никто не реализует элемент управления, редактирующий PK). Я не проверял это вне MySQL.
Ответ 3
Например: n уровень подкатегории для категорий. Идентификатор первичного ключа таблицы ниже ссылается на внешний ключ sub_category_id
![enter image description here]()
Ответ 4
Хорошим примером использования идентификаторов других строк в той же таблице, что и внешние ключи, являются вложенные списки.
Удаление строки с дочерними элементами (т.е. Строк, которые ссылаются на идентификатор родителя), у которых также есть дочерние элементы (т.е. Ссылки на идентификаторы дочерних элементов), приведет к удалению каскада строк.
Это сэкономит много боли (и много кода того, что делать с сиротами - то есть строк, которые ссылаются на несуществующие идентификаторы).
Ответ 5
Это может быть хорошим примером объяснения
CREATE TABLE employees (
id INTEGER NOT NULL PRIMARY KEY,
managerId INTEGER REFERENCES employees(id),
name VARCHAR(30) NOT NULL
);
INSERT INTO employees(id, managerId, name) VALUES(1, NULL, 'John');
INSERT INTO employees(id, managerId, name) VALUES(2, 1, 'Mike');
- Объяснение: - В этом примере. Джон - менеджер Майка. Майк никому не управляет. - Майк - единственный сотрудник, который никому не управляет.