Mysql 外键SQL查询不工作
我有一个名为Mysql 外键SQL查询不工作,mysql,sql,foreign-keys,Mysql,Sql,Foreign Keys,我有一个名为user-friend的表,其中包含UID和FID。 我有另一个名为用户朋友类型的表,它有UID和FID作为外键和级联,在该表中ID、UID、FID构成主键 问题是如果我发表声明 从UID=1和FID=2的用户好友中删除。它还删除了用户朋友类型中的所有UID=1,这对我来说非常奇怪。我错过什么了吗 下面是显示创建用户好友类型 CREATE TABLE IF NOT EXISTS `userfrnd_source` ( `id` int(16) NOT NULL AUTO_INCR
user-friend
的表,其中包含UID和FID。
我有另一个名为用户朋友类型
的表,它有UID和FID作为外键
和级联
,在该表中ID、UID、FID构成主键
问题是如果我发表声明
从UID=1和FID=2的用户好友中删除
。它还删除了用户朋友类型
中的所有UID=1,这对我来说非常奇怪。我错过什么了吗
下面是显示创建用户好友类型
CREATE TABLE IF NOT EXISTS `userfrnd_source` (
`id` int(16) NOT NULL AUTO_INCREMENT,
`userId` int(16) NOT NULL,
`friendId` int(16) NOT NULL,
`source_import_Id` int(16) NOT NULL,
`sourceType` varchar(56) NOT NULL,
PRIMARY KEY (`id`,`userId`,`friendId`),
KEY `friendId` (`friendId`),
KEY `source_import_Id` (`source_import_Id`),
KEY `ufsource_ufdfk_idx` (`userId`,`friendId`)
)
显示为用户好友创建(父级)
引擎是InnoDB
感谢添加DDL,现在可以更清楚地看到发生了什么
您正在以非传统的方式定义外键
“detail”表通常是包含外键的子表,它引用的是作为父表的“type”表。因此,您似乎将这些外键向后放置。编辑:这是我的困惑,因为“细节”通常与子表关联 此外,FK应仅引用父表中主键或非空唯一键中的列。相反,UID和FID都有一个单独的FK,引用父表中非唯一的二级索引。InnoDB非常不寻常,因为它允许您定义引用非唯一索引的外键,但这对于SQL来说是不标准的,并且可能会导致非常混乱的结果 此外,每个表都有自己的自动增量id。这很好,但这意味着子表没有正确的id值来引用其父表。要解决此问题,可以为要引用的外键定义一个唯一键,而不使用“自动递增”列 并且确保使用多列外键来匹配它引用的多列唯一键,不要创建两个单列外键,因为这将表现出不同的行为 因此,我建议使用以下DDL:
CREATE TABLE IF NOT EXISTS `userfrnd_source` (
`id` int(16) NOT NULL AUTO_INCREMENT,
`userId` int(16) NOT NULL,
`friendId` int(16) NOT NULL,
`source_import_Id` int(16) NOT NULL,
`sourceType` varchar(56) NOT NULL,
PRIMARY KEY (`id`,`userId`,`friendId`),
KEY `friendId` (`friendId`),
KEY `source_import_Id` (`source_import_Id`),
KEY `ufsource_ufdfk_idx` (`userId`,`friendId`)
);
CREATE TABLE IF NOT EXISTS `user_friend_detail` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`userId` int(16) NOT NULL,
`friendId` int(16) NOT NULL,
PRIMARY KEY (`id`,`userId`,`friendId`),
UNIQUE KEY `ufd_users_fk1_idx` (`userId`, `friendId`),
KEY `ufd_usersfk2_idx` (`friendId`)
);
-- change to a single FK constraint, with two columns
ALTER TABLE `userfrnd_source`
ADD CONSTRAINT `userfrnd_source_ibfk_2` FOREIGN KEY (`userId`,`friendId`)
REFERENCES `user_friend_detail` (`userId`,`friendId`)
ON DELETE CASCADE ON UPDATE CASCADE;
这两个表的
SHOW CREATE TABLE
是什么样子的?请仔细阅读文档:,在DELETE CASCADE上找到的说明及其工作原理。@ExplosionPills的建议+1。很难想象你所谈论的所有专栏和引用。它很容易使用SHOW CREATE TABLE`User friend`
以及其他表,然后编辑您的问题并粘贴输出。@ExplosionPills添加了table@BillKarwin为表格添加了多行,其中userId和friendId的值都相同?是的,多行,并且对于给定的userId/friendId值对,在user\u friend\u detail
中是否有多行?或者这是唯一的吗?那是唯一的,这就是为什么我说,User\u friend\u detail是父表,另一个是子表好的,那么可能引用的方向没有问题。我被你关于来源和细节的说法吓坏了。我已经编辑了上面推荐的DDL。
CREATE TABLE IF NOT EXISTS `userfrnd_source` (
`id` int(16) NOT NULL AUTO_INCREMENT,
`userId` int(16) NOT NULL,
`friendId` int(16) NOT NULL,
`source_import_Id` int(16) NOT NULL,
`sourceType` varchar(56) NOT NULL,
PRIMARY KEY (`id`,`userId`,`friendId`),
KEY `friendId` (`friendId`),
KEY `source_import_Id` (`source_import_Id`),
KEY `ufsource_ufdfk_idx` (`userId`,`friendId`)
);
CREATE TABLE IF NOT EXISTS `user_friend_detail` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`userId` int(16) NOT NULL,
`friendId` int(16) NOT NULL,
PRIMARY KEY (`id`,`userId`,`friendId`),
UNIQUE KEY `ufd_users_fk1_idx` (`userId`, `friendId`),
KEY `ufd_usersfk2_idx` (`friendId`)
);
-- change to a single FK constraint, with two columns
ALTER TABLE `userfrnd_source`
ADD CONSTRAINT `userfrnd_source_ibfk_2` FOREIGN KEY (`userId`,`friendId`)
REFERENCES `user_friend_detail` (`userId`,`friendId`)
ON DELETE CASCADE ON UPDATE CASCADE;