自引用外键-mysql未设置为null
索引:自引用外键-mysql未设置为null,mysql,Mysql,索引: Keyname Type Unique Packed Column Cardinality Collation Null parent_id BTREE No No parent_id 1 A YES 表:(评论) 关系视图: Column Foreign key constraint (INNODB) parent_id 'test_site'.'comments'.'
Keyname Type Unique Packed Column Cardinality Collation Null
parent_id BTREE No No parent_id 1 A YES
表:(评论)
关系视图:
Column Foreign key constraint (INNODB)
parent_id 'test_site'.'comments'.'id' ON DELETE CASCADE ON UPDATE NO ACTION
是否可以将父\u id设置为空。我已尝试将默认值设置为“0”并插入值“0”,但出现以下错误
错误:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update
a child row: a foreign key constraint fails (`test_site`.`comments`,
CONSTRAINT `comments_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `comments`
(`id`) ON DELETE CASCADE ON UPDATE NO ACTION)
非常感谢您在这方面提供的任何帮助。是的,这是可能的,尽管您只需绕过外键约束一次即可插入默认值的虚拟记录。以下是我的工作流程: 以下是表的创建:
root@localhost:playground > create table comments(id int auto_increment primary key, parent_id int not null default 0, constraint fk_parent_id foreign key (parent_id) references comments(id) on delete cascade on update cascade)engine=innodb;
Query OK, 0 rows affected (0.01 sec)
root@localhost:playground > show create table comments\G
*************************** 1. row ***************************
Table: comments
Create Table: CREATE TABLE `comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `fk_parent_id` (`parent_id`),
CONSTRAINT `fk_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `comments` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
现在绕过外键并插入虚拟记录
root@localhost:playground > set session foreign_key_checks=0;
Query OK, 0 rows affected (0.00 sec)
root@localhost:playground > insert into comments (id) values (null); Query OK, 1 row affected (0.00 sec)
root@localhost:playground > set session foreign_key_checks=1;
Query OK, 0 rows affected (0.00 sec)
root@localhost:playground > select * from comments;
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | 0 |
+----+-----------+
1 row in set (0.00 sec)
root@localhost:playground > update comments set id = 0 where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
root@localhost:playground > select * from comments;
+----+-----------+
| id | parent_id |
+----+-----------+
| 0 | 0 |
+----+-----------+
1 row in set (0.00 sec)
为了使事物整洁,我重置了自动增量(这不是必需的):
从现在起,外键约束工作正常,列不再可为null,并具有默认值:
root@localhost:playground > insert into comments (id) values (null);
Query OK, 1 row affected (0.00 sec)
root@localhost:playground > select * from comments;
+----+-----------+
| id | parent_id |
+----+-----------+
| 0 | 0 |
| 1 | 0 |
+----+-----------+
2 rows in set (0.00 sec)
这是因为它需要引用一个真正的ID,或者只是null。因为您已经通过数据库的外观在数据库中建立了关系。如果我插入了一个默认行并将其用作引用ID,这会起作用吗?可能会,但为什么不摆脱数据库上的约束并确保应用程序覆盖逻辑呢?可以,我只是想知道这是否可能,我将让应用程序完成这项工作。谢谢。@David可能是因为忽略或忽略应用层的实现约束太容易了,并且有效地将约束从数据模型中移除。
root@localhost:playground > alter table comments auto_increment=0;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
root@localhost:playground > insert into comments (id) values (null);
Query OK, 1 row affected (0.00 sec)
root@localhost:playground > select * from comments;
+----+-----------+
| id | parent_id |
+----+-----------+
| 0 | 0 |
| 1 | 0 |
+----+-----------+
2 rows in set (0.00 sec)