Mysql 外键是否可以引用自己表的主键?

Mysql 外键是否可以引用自己表的主键?,mysql,database,relational-database,Mysql,Database,Relational Database,我正在为work创建一个MySQL员工数据库,我希望它存储员工的主管 假设我有一个名为“employee”的表,其中包含字段“id”、“first_name”、“last_name”和“supv_id”,其中“id”是主键,“supv_id”是一个外键,它引用了和employee id 目前,我将“supv_id”作为外键,指向一个单独的表“supervisor”。此表仅由“id”和“emplu id”组成,它们指向employee表。但是,如果有一种方法可以简单地将'employee'中的's

我正在为work创建一个MySQL员工数据库,我希望它存储员工的主管

假设我有一个名为“employee”的表,其中包含字段“id”、“first_name”、“last_name”和“supv_id”,其中“id”是主键,“supv_id”是一个外键,它引用了和employee id

目前,我将“supv_id”作为外键,指向一个单独的表“supervisor”。此表仅由“id”和“emplu id”组成,它们指向employee表。但是,如果有一种方法可以简单地将'employee'中的'supv_id'指向'employee.id',这将完全消除对我的'supervisor'表的需要。以下是一个例子:

+----+--------+-----------+---------+
| id | f_name | l_name    | supv_id |
+----+--------+-----------+---------+ 
|  1 | Han    | Solo      |    NULL | //Or 0?
|  2 | Luke   | Skywalker |       1 |
+----+--------+-----------+---------+
简而言之,我希望“supv_id”指向另一名员工。这有意义吗?我该怎么做呢

谢谢


编辑:固定表

是,将表连接到自身。以下是许多方法之一:

SELECT a.l_name AS employee, b.l_name AS supervisor 
  FROM employee AS a, employee AS b 
  WHERE a.supv_id = b.id             -- link tables
    AND a.id = 2                     -- get employee
返回:

employee  | supervisor
----------+-----------
Skywalker | Solo

您可以创建如下表:

CREATE TABLE laya2 (
    id INT NOT NULL PRIMARY KEY,
    f_name VARCHAR(20),
    l_name VARCHAR(20),
    supv_id INT,
    INDEX supv_id_idx (supv_id),
    FOREIGN KEY (supv_id)
        REFERENCES laya2(id) 
        ON DELETE SET NULL      -- example for an action
) ENGINE=INNODB;
我的示例将reference选项设置为SET NULL,因为我认为它是这里的逻辑选项。如果一个管理其他人的员工离开了,那么这些员工首先就没有了主管。另一种选择是让
不采取任何行动
,因为您可以轻松识别那些没有有效主管的员工,并为他们找到新的主管<删除级联上的code>在这里是错误的,因为这些员工不会同时离开

您可以插入具有

INSERT INTO laya2 VALUES
(1, 'Han', 'Solo', NULL),
(2, 'Luke', 'Skywalker', 1);
(两次成功插入),但不使用

INSERT INTO laya2 VALUES
(3, 'Anakin', 'Skywalker', 0);
此语句将失败,因为外键约束失败

删除Han Solo会将Luke Skywalker的supv_id更改为NULL,因为删除集NULL上有参考选项

DELETE FROM laya2 WHERE id = 1;    -- this will set the supv_id for Luke Skywalker to NULL

是的,您可以定义一个外键,该外键引用它自己表的主键

create table employee (id int(10),
                       f_name varchar(10),
                       l_name varchar(10),
                       supv_id int(10)) ENGINE=InnoDB;
alter table employee add primary key (id);
alter table employee add foreign key (supv_id) references employee (id);

没有主管的员工在
supv_id
列中必须有NULL。

外键可以引用mysql(或其他数据库中的模式)中任何数据库中任何用户表(包括其自身,包括复合键)中的任何唯一或主键。
NULL
是正确的值,如果没有匹配项。如果尝试插入零(0),则结果将是外键冲突,因为没有值为
0
的id。根据答案,这是描述关系数据库中层次结构的最简单解决方案,但是查询任意级别的节点会变得困难。您可能想看一看其他一些数据模型,并在提交此模型之前考虑如何访问数据。@symcbean您有点超出了我的理解!这对我来说还是很新鲜的。目前,我正在进行模型和设计,最终我还将创建一个便于查询的接口。它仍处于早期阶段,所以如果你有任何建议,我愿意接受。谢谢@VMai感谢您的确认:)好的,这很有意义,非常感谢!但是,我认为您的第二个选项“不采取行动”更好,因为我的员工属于不同的组,有不同的主管,因此我希望将他们分开,以便更容易更新,而不是将主管设置为
NULL
的混合员工组。谢谢:)谢谢,这很有用:)嗯,好像有问题。我像你说的那样试了一下,得到了正确的输出。然而,在将
a.supv_id=b.id
切换到
b.supv_id=a.id
时,输出显示汉·索洛的主管是卢克·天行者。如果Han Solo没有主管(即
supv_id=NULL
),这怎么可能?当您将其更改为
b.supv_id=a.id
时,您将“b”表更改为员工表,“a”表更改为主管表,因此您还需要更改“选择列”部分中的标签。