Подтвердить что ты не робот

Может ли внешний ключ ссылаться на первичный ключ в той же таблице?

Я просто думаю, что ответ ложный, потому что внешний ключ не обладает свойством 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 Каково его использование?

4b9b3361

Ответ 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');

- Объяснение: - В этом примере. Джон - менеджер Майка. Майк никому не управляет. - Майк - единственный сотрудник, который никому не управляет.