我有一张名为user-friend
的表UID and FID.
我有另一个名为user-friend-type
的表,它的UID和FID为Foreign key
CASCADE
,表ID, UID, FID
形成主键
问题是如果我发表声明
delete from User-friend where UID=1 and FID=2
。它还删除了User-Friend-type
中的所有UID = 1,这对我来说非常奇怪。我错过了什么吗?
这里是SHOW创建用户友好型
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`),
KEY `ufd_users_fk1_idx` (`userId`),
KEY `ufd_usersfk2_idx` (`friendId`)
)
ALTER TABLE `userfrnd_source`
ADD CONSTRAINT `userfrnd_source_ibfk_2` FOREIGN KEY (`friendId`) REFERENCES `user_friend_detail` (`friendId`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `userfrnd_source_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user_friend_detail` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `user_friend_detail`
--
ALTER TABLE `user_friend_detail`
ADD CONSTRAINT `ufd_usersfk1` FOREIGN KEY (`userId`) REFERENCES `users` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `ufd_usersfk2` FOREIGN KEY (`friendId`) REFERENCES `users` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE;
引擎为InnoDB
答案 0 :(得分:0)
感谢您添加DDL,现在可以更清楚地看到发生了什么。
您以非常规的方式定义外键。
“detail”表通常是子表,具有外键的表,并且它引用将成为父表的“type”表。所以你似乎有这些外键倒退 编辑:这原来是我的困惑,因为“细节”通常与子表相关联。
此外,FK应仅引用父表中的PRIMARY KEY或非null UNIQUE KEY中的列。相反,您为每个UID和FID都有一个单独的FK,引用父表中的非唯一二级索引。 InnoDB非常不寻常,因为它允许您定义引用非唯一索引的外键,但这对于SQL来说是非标准的,它可能会导致非常混乱的结果。
此外,每个表都有自己的自动增量ID。这很好,但这意味着子表将没有正确的id值来引用其父表。要解决此问题,您可以为引用的外键定义UNIQUE KEY,而不使用自动增量列。
并确保使用多列外键来匹配它引用的多列唯一键,不要制作两个单列外键,因为它的行为会有所不同。
所以我建议使用以下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;