Navicat 博客

2017 年 12 月 21 日,由 Robert Gravelle 撰写

DBA 最大的烦恼之一是处理重复数据。无论我们多么努力防范它,重复的东西总是能够找到进入表的方式。这是一个很大的问题,因为它可能影响应用程序视图(每个项目应该是唯一的),偏斜统计信息,并且在严重的情况下,会增加服务器的开销。

在这篇文章中,我们将学习如何识别 MySQL 中的重复数据,以及如何删除它们而不影响宝贵的有效数据。

重复类型

大多数重复记录是这两种不同类型的其中之一:重复含义和非唯一键。在这一篇文章,我们将处理重复含义的记录,而非唯一键将在下一篇文章处理。

当重复不是重复时

重复含义是最常见的重复类型。这情况是两个或多个字段的内容不一样,但它们的含义是一样的。你可以将其视为语义重复。

请看下面的表摘录:

movie_name media
---------------------------
ACADEMY DINOSAUR Theatre
ACE GOLDFINGER Television
ADAPTATION HOLES Theatre
AFFAIR PREJUDICE Theatre
AFRICAN EGG TV

在 media 列中,“Television”和“TV”条目具有相同的含义,但表达方式不同。此问题通常是由使用自由文本输入引起的,使用有限选项的下拉列表是更好的选择。

这种重复类型可能非常难以处理,因为你无法使用 SELECT DISTINCT 语句排除重复项。

有两种方法可以解决这个问题:

  • 使用 REPLACE() 选择数据,将不想要的值换成我们想要查看的值:
  • SELECT DISTINCT movie_name,
    REPLACE(media, "TV", "TELEVISION") as media,
    FROM films;

  • 更新实际的表数据。将所有“TV”更新为“TELEVISION”。这是更新语句:
  • UPDATE films
    SET media = REPLACE(media, "TV", "TELEVISION")
    WHERE media = "TV";

下面是我一个月前遇到的真实例子!

不知何故,我们的数据有一些不需要的卷曲撇号。请注意“O'BRIEN”和“O'BRIEN”条目:

first_name last_name
---------------------
PENELOPE GUINESS
CONAN O'BRIEN
ED CHASE
JENNIFER DAVIS
CONAN O'BRIEN

我们可以像上面那样处理这个问题:

  • 使用 REPLACE() 选择数据以使用常规单引号交换卷曲撇号,以便我们处理相同的字符:
  • SELECT DISTINCT first_name,
    REPLACE(last_name, "'", "'") as last_name,
    FROM actors
    WHERE REPLACE(last_name, "'", "'") like "O'BRIEN";

  • 更新实际的表数据。此语句将 last_name 列中的所有撇号更新为常规单引号:
  • UPDATE actors
    SET last_name = REPLACE(last_name, "'", "'")
    WHERE last_name like "%'%";

总结

无论是称作重复记录、相同数据、冗余数据,还是重复行,它们都是 DBA 生命中最大的祸根之一。然而,定期清除它们是至关重要的,以免生成错误的统计信息和使数据库用户感到困惑。

Navicat 文章
频道条目
分享
文章归档