有一张桌子的一对多

时间:2011-12-17 16:33:06

标签: mysql

我正在尝试使用一个表创建一对多关系。 这可能吗?

create table user(id int primary key auto_increment not null,                                                                                                                      
created_by int default null                                                                                                                                                        
)ENGINE=INNODB;                                                                                                                                                                    

alter table user add foreign key (created_by) references user(id) ON DELETE SET NULL ON UPDATE CASCADE;                                                                            

insert into user (id) VALUES(1);                                                                                                                                                   
insert into user (id, created_by) VALUES (2,1);   

现在当我删除id = 1的用户时,created_by的值会自动变为NULL。

但是当我更改id为1的用户的id时,我收到此错误

mysql> update user set id=2 where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`jrt`.`user`, CONSTRAINT `user_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)

我该如何解决这个问题?更新此更新我希望列created_by是级联更改。

1 个答案:

答案 0 :(得分:2)

密钥并不意味着要改变,它们意味着“识别”。因此,具有id 2的用户在逻辑上是具有id的用户的不同用户。在创建唯一用户的那一刻,它的主键在该用户的生命周期中应该是相同的。

所以这真的是一个设计问题。您需要质疑为什么要更改特定用户的ID。它可能是你想要的是一个固定的识别密钥和另一个标识符(它不是密钥,只存在于用户表上),你可以改变它。

[更新了更多信息] 这是关于关系数据库设计基础的资源(有许多可在线获得)。 http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx

相关部分是“表格,唯一性和关键字”。

  

Fabian Pascal在他的着作SQL and Relational Basics中指出了这一点   决定应该基于最小的原则(选择   最少的列),稳定性(选择一个很少的关键   改变),简单/熟悉(选择一个既简单的键   用户熟悉。)

就个人而言,我会更进一步稳定;尝试选择永不改变的密钥。例如,“电子邮件”对用户来说是一个糟糕的关键选择,因为用户可以更改他们的电子邮件。如果您选择一个密钥,例如内部生成的数字或者人事系统中的唯一标识符,那么您不必担心它会更改并将此更改迁移到其他表。

注意:可能存在需要更改主键的“一次性”的情况。最好使用一些手动SQL语句(删除第一个用户并使用不同的密钥创建相同的第二个用户)。它不应该是数据库设计的一部分,而级联更新的自动化性质意味着它。

还请参见: When to use "ON UPDATE CASCADE"

另请注意: http://forums.mysql.com/read.php?136,391782,391782