自引用外键 - MySQL未设置为null。

9

索引:

Keyname    Type   Unique  Packed  Column     Cardinality Collation  Null        
parent_id  BTREE  No      No      parent_id  1           A          YES 
表格:(评论)
Column      Type        Null    Default Extra
id          int(11)     No      None    AUTO_INCREMENT      
parent_id   int(11)     Yes     NULL

关系视图:

Column     Foreign key constraint (INNODB)
parent_id  'test_site'.'comments'.'id'  ON DELETE CASCADE   ON UPDATE  NO ACTION

有没有可能将parent_id设置为非NULL值。我尝试将默认值设置为“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)

任何对此的帮助将不胜感激,谢谢。

2
这是因为它需要引用一个真正的ID,或者只是null。从你的数据库关系设置来看,这是必须的。 - David
可能,但为什么不消除数据库上的约束条件,并确保应用程序覆盖逻辑呢? - David
可以这样做,我只是想知道是否可能,我会让应用程序完成这项工作。谢谢。 - Aaron
4
也许是因为在应用层忽略或忽视实施约束太容易了,这有效地使约束从数据模型中被移除。 - Darwin von Corax
只是为了满足我的好奇心,哪个插入语句失败了?这看起来非常类似于我几年前给我的认证课程设置的一个练习。 - Darwin von Corax
显示剩余2条评论
1个回答

1
是的,这是可能的,尽管您需要绕过一次外键约束来插入一个虚拟记录以获得默认值。以下是我的工作流程:
这是表格创建内容:
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)

为了使事情井然有序,我重置了auto_increment(这不是必要的):
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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接