Mysql 一对多,一桌

Mysql 一对多,一桌,mysql,Mysql,我正在尝试使用一个表创建一对多关系。 这可能吗 create table user(id int primary key auto_increment not null, created_by int default null

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

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的用户时,自动创建的_的值会像我预期的那样更改为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)

我怎样才能解决这个问题?在此更新之后,我希望更改创建的列

键不是用来更改的,它们是用来“识别”的。因此,id为2的用户在逻辑上是id为1的不同用户。当您创建一个唯一的用户时,它的主键在该用户的生命周期内应该是相同的

所以这确实是一个设计问题。您需要询问为什么要更改特定用户的id。可能您需要的是一个固定的标识键和另一个标识符(该标识符不是键,仅存在于用户表中),您可以对其进行更改

[更新更多信息] 这里有一个关于关系数据库设计基础知识的资源(网上有很多)

相关章节为“表、唯一性和键”

Fabian Pascal在他的书《SQL和关系基础》中指出 决策应基于最低限度原则(选择 所需列最少)、稳定性(选择一个很少使用的键 更改)和简单性/熟悉性(选择一个既简单又熟悉的键 并为用户所熟悉)

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

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

另请参见:


另请注意:

假设我们有电子邮件地址而不是id。用户希望更改其电子邮件,并且也是表的主键,如上面的示例所示。是的,这是糟糕的数据库设计,因此没有自动方式来级联这样的更改,因为您不应该这样做。我将更新我的答案,以提供一个带有说明的外部资源。@mecio:)将电子邮件地址作为主键是一个错误的概念,需要实现--一个错误的数据库设计。嘿,我知道这是错误的数据库设计。。。但我试图实现这一点是出于教育目的。@mecio:)为教育目的实现错误的数据库设计毫无意义。你真的想走错方向吗?你在哪里需要这样一个概念只是好奇,我根本不需要它。我只是好奇。Tim Gee将论坛帖子与确切答案链接在一起(这是一种防止无限循环的简单机制),请务必阅读。