MySQL:自引用不为null,auto_increment,外键?

时间:2013-11-27 15:56:53

标签: mysql

在MySQL(在任何版本中)是否可以声明并使用具有引用同一表的AUTO_INCREMENT主键的自引用(而非空)外键列的表?

基本上,我想创建下表,其中的行代表树木森林。我希望层次结构中的根节点由行的parent_id指示等于id(而不是允许parent_id中的NULL来指示根)。< / p>

e.g。

CREATE TABLE forest (
    id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    parent_id BIGINT NOT NULL,
        CONSTRAINT fk_forest_parent_id FOREIGN KEY(parent_id) REFERENCES forest(id),
    name VARCHAR(20) NOT NULL UNIQUE
);

创建此表有效(5.0.44sp1-enterprise-gpl-nt-log MySQL Enterprise Server(GPL))。但是,似乎不可能使用LAST_INSERT_ID()来插入parent_id根节点(这并不奇怪)。以下内容不起作用:

INSERT INTO forest(parent_id, name) VALUES (LAST_INSERT_ID(), "root 1");

以下工作正常,但不再使用自动增量:

INSERT INTO forest(id, parent_id, name) VALUES (1234, 1234, "root 1");

有没有办法使用以这种方式定义的表,同时仍然依赖于自动生成的PK,同时还保留所有约束(NOT NULL和FOREIGN KEY)?

更新 - 可能的解决方案:

START TRANSACTION;
SET FOREIGN_KEY_CHECKS = 0;
INSERT INTO forest(parent_id, name) VALUES (0, "root X");
UPDATE forest SET parent_id = LAST_INSERT_ID() WHERE id = LAST_INSERT_ID();
SET FOREIGN_KEY_CHECKS = 1; /* This seems to be important. */
COMMIT;

1 个答案:

答案 0 :(得分:2)

id完成之前,无法知道行的INSERT是什么,因此在没有LAST_INSERT_ID()的情况下调用INSERT不会任何东西。相反,您需要两个单独的语句(可以作为存储过程中的事务或者您拥有的事务运行)。

INSERT INTO forest(name) VALUES ("root 1");
UPDATE forest SET parent_id = LAST_INSERT_ID() WHERE id = LAST_INSERT_ID();
但是,我不认为根节点将自己引用为父节点是有意义的。只是说。