2017-04-19 12 views
1

我有3个表数据库没有链接:mysql的删除元素时,它具有与其他

  • 用户
  • Users_cards

users_cards有两列:

  • user_id(是Users.i的外键d)
  • card_id的(是Cards.id的外键)

userscards表有自己的id作为主键,和users_cards的两列是他们的外键,与级联删除选项,所以当我从cards中删除一张卡时,它也会从users_cards中删除,与users一样。

而且,我想,当我删除users_cards表中的一行,如果该卡没有更多的用户,这是,如果该行正是那个card_id出现在表中的唯一行,它必须被删除也从cards

达到此目的的最佳方法是什么?它可以“自动”完成,或者我必须检查每次从users_cards删除一行吗?

+0

AFTER触发器是你最好的朋友:) –

+0

我不认为你可以自动设置它。 –

回答

2

是否可以“自动”完成,或者我必须检查每个I 从users_cards这个删除一行的时间?

取决于您的意思。在users_cards每个DELETE查询后

DELIMITER $$ 

CREATE DEFINER=CURRENT_USER TRIGGER `name_of_this_trigger` 
AFTER DELETE ON `users_cards` FOR EACH ROW 
BEGIN 

    DELETE FROM `cards` WHERE `id` NOT IN (SELECT DISTINCT `card_id` FROM `users_cards`); 

END $$ 

DELIMITER ; 

如果你执行它的数据库,这将增加其运行和检查用户式卡的触发器,并删除它们没有任何额外的麻烦: 我会使用触发器表。 但是,如果users_cards已被级联事件删除,它将不会运行,因此无法删除任何可能无用户卡。 所以,你可以做两件事。什么都没有:无论如何,垃圾将在users_cards的下一个DELETE查询中清除。要么;

DELIMITER $$ 

CREATE DEFINER=CURRENT_USER TRIGGER `name_this_very_trigger` 
AFTER DELETE ON `users` FOR EACH ROW 
BEGIN 

    DELETE FROM `cards` WHERE `id` NOT IN (SELECT DISTINCT `card_id` FROM `users_cards`); 

END $$ 

DELIMITER ; 

FYI:您可以(由于级联从users DELETE发起删除现在没有users_cards任何潜在的卡)添加另一个触发,这在users表删除查询后运行,像这样:如果你注意到,在触发器声明后只有一条语句,所以你甚至不需要BEGIN ... END块,这意味着DELIMITER废话也是不必要的。

让我知道它是否有帮助!

ps:为了上帝的缘故, 请不要使用复数表名。您正在命名存储在表中的实体,而不是表本身。

+1

这是一个很好的,很好的解释!竖起大拇指!干杯!尽管如此,欢迎来到。 –

0

请尝试以下...

CASE (SELECT COUNT(*) 
     FROM users_cards 
     WHERE card_id = targetID) 
    WHEN 0 THEN 
     DELETE 
     FROM Cards 
     WHERE id = targetID; 
    WHEN 1 THEN 
     DELETE Cards, 
       users_cards 
     FROM cards 
     JOIN users_cards 
     WHERE Cards.id = users_cards.card_id 
      AND Cards.id = targetID; 
    ELSE 
     *** Delete a user_card *** 
END 

此语句将统计剩余users_cards其中card_id等于目标ID的条目数。

如果没有,则检测到Card没有相应的Users,然后删除它。

如果有,则删除对应于目标ID的Cardsusers_cards中的条目。

如果有多个,请使用您现有的DELETE声明。

如果您有任何问题或意见,请随时发布相应评论。

进一步阅读

Mysql - delete from multiple tables with one query(佩卡的回答)

https://dev.mysql.com/doc/refman/5.7/en/delete.html(对于单和多表DELETE语法)

https://dev.mysql.com/doc/refman/5.7/en/case.html(用于CASE

+0

更正信息发布 – toonice

+0

哦 - 更好。 – toonice

+0

发布了更新的版本。 – toonice

0

你必须设置在设计时间表上的属性应该在子表上执行什么操作主表被删除。

ON DELETE CASCADE也会从子表中删除相应的行。 ON UPDATE CASCADE也会更新子表中的引用键值对应的行。

CREATE TABLE categories (
id int unsigned not null primary key, 
name VARCHAR(255) default null 
)Engine=InnoDB; 

CREATE TABLE products (
id int unsigned not null primary key, 
name VARCHAR(255) default null 
)Engine=InnoDB; 

CREATE TABLE categories_products (
category_id int unsigned not null, 
product_id int unsigned not null, 
PRIMARY KEY (category_id, product_id), 
KEY pkey (product_id), 
FOREIGN KEY (category_id) REFERENCES categories (id) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
FOREIGN KEY (product_id) REFERENCES products (id) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE 
)Engine=InnoDB; 
+0

这不是我要求的,我知道'级联'是如何工作的 – xBlackout

相关问题