【问题标题】:Deleting duplicate records in join table删除连接表中的重复记录
【发布时间】:2011-02-13 21:35:21
【问题描述】:

我在用户和角色之间有一个 HABTM 关联。

用户可以是管理员 (role_id = 1) 或角色用户 (role_id = 2)。

在连接表中,roles_users,我有一些冗余记录。例如:

我想删除1:1、2:4等重复记录。

两个问题:

  1. 执行删除 dups 的 sql 脚本的最佳位置在哪里——迁移?脚本?

  2. 删除 dups 的 sql 查询是什么?

【问题讨论】:

    标签: mysql ruby-on-rails has-and-belongs-to-many duplicate-removal


    【解决方案1】:
    CREATE TABLE roles_users2 LIKE roles_users; -- this ensures indexes are preserved
    INSERT INTO roles_users2 SELECT DISTINCT * FROM roles_users; 
    DROP TABLE roles_users;
    RENAME TABLE roles_users2 TO roles_users;
    

    为了将来,防止重复行

    ALTER TABLE roles_users ADD UNIQUE INDEX (role_id, user_id);
    

    或者,您可以通过ALTER TABLE IGNORE 一步完成所有操作:

    ALTER IGNORE TABLE roles_users ADD UNIQUE INDEX (role_id, user_id);

    IGNORE 是标准 SQL 的 MySQL 扩展。如果新表中的唯一键有重复项或启用严格模式时出现警告,它会控制 ALTER TABLE 的工作方式。如果未指定 IGNORE,则如果发生重复键错误,则副本将中止并回滚。如果指定了 IGNORE,则只有第一行用于在唯一键上具有重复项的行。其他冲突的行被删除。不正确的值将被截断为最接近的匹配可接受值。

    【讨论】:

    • 这是 ALTER IGNORE TABLE 而不是 ALTER TABLE IGNORE。但是 IGNORE 并非一直有效,最好通过创建一个临时表来使用@John Douthat 第一个建议。
    • @Jadenko88 感谢您的关注!现在已经修复了
    【解决方案2】:

    最简单的是将数据复制到新表中,减去重复项:

    CREATE TABLE roles_users2 AS
    SELECT DISTINCT * FROM roles_users
    

    然后您可以选择以下选项之一:

    • 删除旧表,将新表重命名为旧名称并添加索引。
    • 截断旧表并将roles_users2 中的行重新插入roles_users。

    【讨论】:

    • 截断旧表将保持约束和外键引用不变。当然,如果它首先有合理的限制,就不会有重复。 (耸肩)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-07
    • 2019-11-25
    • 1970-01-01
    • 2016-09-17
    相关资源
    最近更新 更多