【问题标题】:Fix DB duplicate entries (MySQL bug)修复数据库重复条目(MySQL 错误)
【发布时间】:2010-03-30 02:37:23
【问题描述】:

我使用的是 MySQL 4.1。一些表具有违反约束的重复条目。

当我尝试对行进行分组时,MySQL 不会将这些行识别为相似的。

例子:

表 A 有一个具有唯一属性的“名称”列。
该表包含一行名称为“Hach?”和一行具有相同名称但末尾有一个正方形而不是“?” (我无法在此文本字段中重现)
这 2 行上的“分组依据”返回 2 个单独的行

这会导致一些问题,包括我无法导出和重新导入数据库。在重新导入错误时提到插入失败,因为它违反了约束。

理论上我可以尝试导入,等待第一个错误,修复导入脚本和原始数据库,然后重复。实际上,这将需要很长时间。

有没有办法列出所有异常或强制数据库重新检查约束(并列出所有违反它们的值/行)?

如果有帮助,我可以提供 .MYD 文件。

【问题讨论】:

  • 如果两个名称不相等,则不违反重复约束。我不关注你这里。如果是损坏的数据,您应该更正它。
  • 当我导出和重新导入数据时它们是相等的。 “如果是损坏的数据,你应该更正它。”如何找到损坏的数据?我无法搜索正方形。
  • 如果我的描述不准确,我很抱歉,但问题真的很奇怪。

标签: mysql duplicates


【解决方案1】:

列出所有异常:

SELECT name, count(*) FROM TableA GROUP BY name HAVING count(*) > 1;

有几种方法可以解决删除副本的问题,您的路径将在很大程度上取决于您拥有的副本数量。

请参阅this SO question,了解如何从您的表格中删除这些内容。

这是我在那里提供的解决方案:

-- Setup for example
create table people (fname varchar(10), lname varchar(10));

insert into people values ('Bob', 'Newhart');
insert into people values ('Bob', 'Newhart');
insert into people values ('Bill', 'Cosby');
insert into people values ('Jim', 'Gaffigan');
insert into people values ('Jim', 'Gaffigan');
insert into people values ('Adam', 'Sandler');

-- Show table with duplicates
select * from people;

-- Create table with one version of each duplicate record
create table dups as 
    select distinct fname, lname, count(*) 
    from people group by fname, lname 
    having count(*) > 1;

-- Delete all matching duplicate records
delete people from people inner join dups 
on people.fname = dups.fname AND 
   people.lname = dups.lname;

-- Insert single record of each dup back into table
insert into people select fname, lname from dups;

-- Show Fixed table
select * from people;

【讨论】:

  • 第一个查询没有返回任何内容。 2张桌子有这个问题。对任何一个都不起作用。在一个副本中,我可以识别出一个不同的字符。然而,当它尝试插入时,MYSQL 发现它是同一个字符。我会更新我的描述。
  • 您是否检查过以确保您的列值中没有空格?我猜你有一个像 'Bob' 和一个像 'Bob' 这样的值。
【解决方案2】:

创建一个新表,选择所有行并按唯一键(在示例列名中)进行分组,然后插入到新表中。

【讨论】:

    【解决方案3】:

    要找出那个字符是什么,请执行以下查询:

    SELECT HEX(Name) FROM TableName WHERE Name LIKE 'Hach%'
    

    您将获得那个“正方形”的 ascii 代码。

    如果那个字符是'x',你可以像这样更新:(但是如果那个列是唯一的,你会遇到一些错误)

    UPDATE TableName SET Name=TRIM(TRAILING 'x' FROM Name);
    

    【讨论】:

    • 好的,谢谢。不幸的是,我有数百个这样的案例,其中只有一个以“Hach”开头。我如何找到它们?
    • 但是最后一个字符(“正方形”)是否相同?
    • 正方形并不总是最后一个字符,可能不止1个。它们似乎正在替换单词中的重音:语言是法语,很多单词都有重音。另一方面,有些重音符号并没有被“方格”取代。
    【解决方案4】:

    我假设这是一个 MySQL 4.1 随机错误。有些值只是在没有特殊原因的情况下自行更改,即使它们违反了某些 MySQL 约束。 MySQL 只是忽略了这些违规行为。

    为了解决我的问题,我将编写一个程序,尝试在同一个表中重新插入每一行数据(准确地说:另一个具有相同特征的表)并记录每个失败实例。

    我会暂时搁置该事件,以防有人遇到同样的问题而其他人找到更实际的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-23
      • 1970-01-01
      • 2021-09-01
      • 2014-05-04
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 2013-12-05
      相关资源
      最近更新 更多