2013-12-17 2 views
1

У меня есть таблица под названием 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. он также удалил все UID = 1 от User-Friend-type, и это очень странно для меня. я что-то упускаю?Внешний ключ SQL-запрос не работает

здесь ШОУ Создать для пользователя-друга-типа

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`) 
) 

SHOW CREATE для пользователя-друга (Parent)

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

+3

Что 'SHOW CREATE TABLE' выглядеть для обеих таблиц? –

+2

Внимательно прочитайте документацию: http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html, найдите описание 'ON DELETE CASCADE' и как оно работает. – krokodilko

+0

+1 к предложению от @ExplosionPills. Трудно представить, что вы говорите, со всеми столбцами и ссылками. Легко использовать 'SHOW CREATE TABLE \ User-friend \' ', а также для другой таблицы, а затем редактировать свой вопрос и вставлять результат. –

ответ

0

Спасибо за добавление DDL , теперь становится яснее видеть, что происходит.

Вы определяете внешние ключи нетрадиционным способом.

Таблица «подробно» обычно представляет собой дочернюю таблицу, другую с внешними ключами, и она ссылается на таблицу типа, которая будет родительской. Таким образом, вы, кажется, имеете эти внешние ключи назад.
Редактировать: Это, оказывается, мое замешательство, просто потому, что «деталь» часто ассоциируется с дочерними таблицами.

Кроме того, FK должны ссылаться только на столбцы в PRIMARY KEY или ненулевом UNIQUE KEY в родительской таблице. Вместо этого у вас есть отдельный FK для каждого из UID и FID, ссылаясь на неспецифические вторичные индексы в родительской таблице. InnoDB довольно необычен тем, что он позволяет вам определять внешние ключи, ссылающиеся на неидеальные индексы, но это нестандартно для SQL, и это может вызвать очень запутывающие результаты.

Кроме того, каждая из ваших таблиц имеет свой собственный идентификатор автоинкремента. Это хорошо, но это означает, что дочерняя таблица не будет иметь правильные значения id для ссылки на свою родительскую таблицу. Чтобы решить эту проблему, вы можете определить UNIQUE KEY для ссылки на внешний ключ без столбца auto-increment.

И не забудьте использовать несколько столбцов внешних ключей, чтобы соответствовать уникальному ключу с несколькими столбцами, которые он ссылается, не делайте двух внешних ключей с одним столбцом, потому что это будет вести себя по-другому.

Так что я бы рекомендовал следующее 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; 
+0

Я не могу сделать ее уникальной, так как может быть более 1 пары –

+0

Более одной строки с одинаковыми значениями для userId * и * friendId? –

+0

Да более одной строки –

Смежные вопросы