MySQL 唯一索引的使用

原创
2017/11/03 17:28
阅读数 5K

 

1、MySQL 唯一索引的使用

普通索引允许被索引的数据列包含重复的值。唯一索引则是不允许有重复的值,当然 null 除外,唯一索引不仅仅可以存储 null , 还可以存储多个 null。

如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。

这么做的好处:

1)简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率;

2)MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了,如果是,MySQL将拒绝插入那条新记录。

总之:唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。个人建议,数据关系应该不仅仅使用主键来标记记录的唯一性,而且也要使用逻辑主键来确定唯一性,也就是把逻辑主键建立唯一索引。

 

 

 

2、唯一索引用来更新

对于数据保存操作(新增或更新),我们一般使用先删除后插入,因为这样操作简单。但是其实这样也不简单,要是更新操作的时候只有逻辑主键没有物理主键,那么查询也需要分情况编写。但是如果你有逻辑主键且作为了唯一索引,那么就可以使用 MySQL 的 ON DUPLICATE KEY UPDATE

或者 REPLACE INTO

 

1)ON DUPLICATE KEY UPDATE

如果您指定了 ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个 UNIQUE 索引 或PRIMARY KEY中出现重复值,则执行 UPDATE。

 

A:单条插入

例如,如果列a被定义为Primary 或 UNIQUE,并且包含值1,则以下两个语句具有相同的效果:

mysql>INSERT INTO table (a,c) VALUES (1,3) ON DUPLICATE KEY UPDATE c=c+1;

mysql>UPDATE table SET c=c+1 WHERE a=1;

 

B:多条插入

批量插入时,可以使用如下语句进行重复则更新,没有则插入。

mysql>INSERT INTO table (a,c) VALUES (1,3),(2,4)

ON DUPLICATE KEY UPDATE c = VALUES(c);

 

 

2)REPLACE INTO

使用REPLACE插入一条记录时,通过判断 primary key 或 unique 索引 ,如果没有重复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值。

 

A:单条插入

例如,如果列a被定义为Primary 或 UNIQUE,并且包含值1,则以下两个语句具有相同的效果:

mysql>REPLACE INTO table (a,c) VALUES (1,3) ON DUPLICATE KEY UPDATE c=c+1;

mysql>UPDATE table SET c=c+1 WHERE a=1;

 

B:多条插入

批量插入时,可以使用如下语句进行重复则更新,没有则插入。

mysql>REPLACE INTO table (a,c) VALUES (1,3),(2,4)

 

总结,如果是需要字段关联更新那么使用 ON DUPLICATE KEY UPDATE,但是如果是已经知道更新的值了那么直接使用 REPLACE INTO 更简单。

 

 

 

3、真实案例:错题本重复生成问题

错题本有个字段 exam_base_id 建立了普通的索引,

然后我一直以为如果用索引字段作为条件进行删除那么这些数据肯定会被锁死,换句话说下一个操作语句过来肯定需要等待,这样理解本身没错,前提是必须要有对应的数据被锁,如果本身就没有数据那么,Mysql又如何锁住这些数据呢?

且看下面的执行记录(前提 select * from t_w where exam_base_id = 10 没有任何记录 )

t1

t2

delete from t_w where exam_id = 10

 

 

delete from t_w where exam_id = 10

insert into t_w select ... where exam_id = 10

 
 

insert into t_w select ... where exam_id = 10

commit

 
 

commit

select * from t_w 结果会发现有重复的记录,道理就是上面说的,无论事务1还是事务2,在通过exam_id删除数据时,因为没有记录被锁定,所以导致两个事务可以同时执行,为了解决重复数据问题,我觉得用唯一索引会比较好

总结:唯一索引不但可以调高查询效率而且可以保证数据的唯一性!!

 

参考:

http://lobert.iteye.com/blog/1604122

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部