有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据。因此一种思路是从源头开始杜绝,就不让插入重复数据,另一种就是直接过滤和删除重复数据了。
防止插入重复数据
可以在 MySQL 数据表中设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性。
让我们尝试一个实例:下表中无索引及主键,所以该表允许出现多条重复记录。
目前name和addr是可以重复的。例如:
往这张表中插入两条一模一样的数据。
结果如下,可以看到是有两条一模一样的数据:
下面用以下方法来处理,防止数据重复
1、设置双主键方式
ps:如果你设置了双主键,那么那个键的默认值不能为 NULL,可设置为 NOT NULL。如下所示:
现在按照上面一样插入两条数据试试看。
可以看到插入第二条时报错了,显示值重复了。
现在可以查下表中有多少条数据。可以看到数据也只剩下1条了。
现在就无法插入重复数据了
2、添加唯一索引
ps:如果我们设置了唯一索引,那么在插入重复数据时,SQL 语句将无法执行成功,并抛出错。
示例如下:
INSERT IGNORE INTO 与 INSERT INTO 区别
INSERT IGNORE INTO 与 INSERT INTO 的区别就是 INSERT IGNORE INTO 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。
以下实例使用了 INSERT IGNORE INTO,执行后不会出错,也不会向数据表中插入重复数据:
可以看到和上面的相比,就没有报错了。
INSERT IGNORE INTO 当插入数据时,在设置了记录的唯一性后,如果插入重复数据,将不返回错误,只以警告形式返回。而 REPLACE INTO 如果存在 primary 或 unique 相同的记录,则先删除掉。再插入新记录。
处理重复数据
1、过滤重复数据
在过滤前,先统计一下重复数据
以上查询语句将返回 person_tbl 表中重复的记录数。一般情况下,查询重复的值,请执行以下操作:
确定哪一列包含的值可能会重复。
在列选择列表使用COUNT(*)列出的那些列。
在GROUP BY子句中列出的列。
HAVING子句设置重复数大于1。
使用 DISTINCT 关键字来过滤重复数据。
使用 GROUP BY 来读取数据表中不重复的数据
删除重复数据
如果你想删除数据表中的重复数据,你可以使用以下的SQL语句:
1、根据person_info创建一个临时表,并使用group by过滤了重复数据。
2、删除之前的表
3、修改临时表的名字
4、查看表数据
当然也可以在数据表中添加 PRIMAY KEY(主键)这种简单的方法来删除表中的重复记录。方法如下:
我又插入了一些重复数据,结果如下:
添加主键
主键和唯一索引的区别
主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
唯一性索引列允许空值,而主键列不允许为空值。
主键列在创建时,已经默认为非空值 + 唯一索引了。
主键可以被其他表引用为外键,而唯一索引不能。
一个表最多只能创建一个主键,但可以创建多个唯一索引。
主键和唯一索引都可以有多列。
主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。
在 RBO 模式下,主键的执行计划优先级要高于唯一索引。两者可以提高查询的速度。
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
总体来说:主键相当于一本书的页码,索引相当于书的目录。
其实主键和索引都是键,不过主键是逻辑键,索引是物理键,意思就是主键不实际存在,而索引实际存在在数据库中,主键一般都要建,主要是用来避免一张表中有相同的记录,索引一般可以不建,但如果需要对该表进行查询操作,则最好建,这样可以加快检索的速度。
历史文章及资料
领取专属 10元无门槛券
私享最新 技术干货