【问题标题】:MySQL delete FROM multiple tables where key can be found in different columns in the same tableMySQL delete FROM multiple tables where key can be found in different columns in同一张表
【发布时间】:2014-03-26 16:30:18
【问题描述】:

我有多个表格保存有关用户和内容的信息。

Table users: 
id     name
 5     foo
33     abc


Table imgs:
id     uid    img_name
1       5        bar
8      33        xy


Table user_permissions: 
id     uid    permission_id
1      5         3
2      3         3


Table liked_content: 
id     contente_id    content_holder_id     likedby_id
1           8                33                   5
2           1                 5                  56

如果一个用户被删除,我想删除所有表中与他的用户 ID 相关的所有行。如果我每张表只添加一列,这很好用。

DELETE users,
       imgs,
       user-permissions,
       liked_content
FROM users,
     imgs,
     user-permissions,
     liked_content
WHERE imgs.uid = users.id AND
      user_permissions.uid = users.id AND
      liked_content.content_holder_id = users.id AND
      users.id  = 5

在可以找到 id 的 WHERE 子句 (likedby_id/liked_content-table) 中添加第二行将不起作用。

...
WHERE imgs.uid = users.id AND
      user_permissions.uid = users.id AND
      liked_content.content_holder_id = users.id AND
      liked_content.likedby_id = users.id AND
      users.id  = 5

向已列出的表的查询添加第二列的正确方法是什么?

【问题讨论】:

    标签: mysql multiple-columns sql-delete multiple-tables


    【解决方案1】:

    根据您的数据,用户 ID 可以在 like_content 表中作为 content_holder_id likeby_id。不一定两者兼而有之。 Where 子句应更改为:

    ...
      WHERE imgs.uid = users.id AND
      user_permissions.uid = users.id AND
      (liked_content.content_holder_id = users.id OR
      liked_content.likedby_id = users.id) AND
      users.id  = 5
    

    如果您将外键约束与级联删除规则一起使用,则不必手动执行此操作。

    【讨论】:

    • 完美!我在没有括号的 bud 之前尝试了 OR,但它不起作用。
    【解决方案2】:

    您自己实现的是级联删除。它通常内置在数据库引擎中。查看这个相关问题:MySQL foreign key constraints, cascade delete 如果您一心想自己做,我建议您在一个事务中使用多个删除语句,从子级到父级遍历您的模式:

    DELETE 
    FROM liked_content
    WHERE content_holder_id = 5;
    
    DELETE 
    FROM imgs
    WHERE uid = 5;
    
    DELETE 
    FROM user-permissions
    WHERE uid = 5;
    
    DELETE 
    FROM users
    WHERE id = 5;
    

    【讨论】:

    • 谢谢。 @chameera-solution 为我工作。也许使用外键约束和级联删除将是我无法实现它的正确方法。
    【解决方案3】:

    正如其他人所说,技术上正确的方法是设置级联删除。

    如果我负责数据库,我不会愿意这样做,因为您会发现尝试操作表非常痛苦,尤其是在您尝试创建示例数据时。

    我会选择 KISS 方法...

    分别引用用户 ID 对每个从属表执行 DELETE,然后删除主记录。

    如果你做外键和级联的事情,你不会喜欢它对你的内容表所做的,因为它与主用户表有两个关系。

    这意味着,例如,如果您尝试删除 holder_id 5 的内容行,您首先必须通过将 likeby_id 设置为 NULL 将这些行与其关联的 likeby_id 主记录断开连接,否则级联将删除 likeby_id 主记录记录。但是,它也不允许您将 likeby_id 设为 NULL,因为这样做会使您实际执行级联所需的外键关系无效。

    帮自己一个忙 - 简单点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      • 2020-10-18
      • 1970-01-01
      • 2012-12-11
      • 2022-12-01
      相关资源
      最近更新 更多