mysql索引(七)唯一索引
Mysql索引大概有五种类型:
普通索引(INDEX):最基本的索引,没有任何限制
唯一索引(UNIQUE):与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
主键索引(PRIMARY):它 是一种特殊的唯一索引,不允许有空值。
全文索引(FULLTEXT ):可用于 MyISAM 表,mysql5.6之后也可用于innodb表, 用于在一篇文章中,检索文本信息的, 针对较大的数据,生成全文索引很耗时和空间。
联合(组合)索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。
这里我们来看下唯一索引。
之前我们看了主键索引,他是一种特殊的唯一索引,二者的区别是,主键索引不能有空值,但是唯一索引可以有空值。
一:基本使用
1:唯一索引可以是单列,也可以是多列,下面我们来看下创建语句:
# 创建单列唯一索引alter table sc add unique (name);
# 创建多列唯一索引alter table sc add unique key `name_score` (`name`,`score`);
2:删除唯一索引语句:
alter table sc drop index name
;
在这里插入代码片
二:唯一索引作用
1:最大的所用就是确保写入数据库的数据是唯一值。
单列唯一值基本上就是主键。
常用的一般都是多列的唯一索引,比如:当前商品,一个用户只能购买一件。我们将用户id及商品id列设置成唯一索引。那么就可以避免一个用户出现重复购买的情况。
示例:
创建数据表:
MariaDB [test]> CREATE TABLE t(-> c1 CHAR(1) not null,-> c2 CHAR(1) not null,-> c3 CHAR(1) not null,-> c4 CHAR(1) not null,-> c5 CHAR(1) not null-> )ENGINE myisam CHARSET UTF8;
Query OK, 0 rows affected (0.09 sec)
添加几条数据:
MariaDB [test]> insert into t VALUES('1','1','1','1','1'),('2','2','2','2','2'),('3','3','3','3','3'),('4','4','4','4','4'),('5','5','5','5','5');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
创建唯一索引:
MariaDB [test]> alter table t add unique key `name_score` (`c2`,`c3`);
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
写入重复数据失败:
MariaDB [test]> insert into t (c1,c2,c3,c4,c5) values ('1','1','1','1','1');
ERROR 1062 (23000): Duplicate entry '1-1' for key 'name_score'
2:提高查询速度
使用index索引时,经常导致慢查询,耗时2秒左右,遇忙时更有达到5秒的
改用unique之后,查询耗时在0.0003秒 基本可以忽略不计
三:唯一索引和主键索引的具体区别
1:唯一性约束所在的列允许空值,但是主键约束所在的列不允许空值。
2:可以把唯一性约束放在一个或者多个列上,这些列或列的组合必须有唯一的。但是,唯一性约束所在的列并不是表的主键列。
3:唯一性约束强制在指定的列上创建一个唯一性索引。在默认情况下,创建唯一性的非聚簇索引,但是,也可以指定所创建的索引是聚簇索引。
4:建立主键的目的是让外键来引用.
5: 一个表最多只有一个主键,但可以有很多唯一键
四:存在唯一键冲突时,避免策略
1:使用insert ignore语句
insert ignore会忽略数据库中已经存在的数据(根据主键或者唯一索引判断),如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据.
MariaDB [test]> insert ignore into t (c1,c2,c3,c4,c5) values ('1','1','1','1','2');
Query OK, 0 rows affected, 1 warning (0.00 sec)MariaDB [test]> select * from t;
+----+----+----+----+----+
| c1 | c2 | c3 | c4 | c5 |
+----+----+----+----+----+
| 1 | 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 | 5 |
+----+----+----+----+----+
5 rows in set (0.00 sec)
Sql执行成功,但是我们查询表的数据,发现并没有写入成功。是因为唯一索引已经存在。跳过了这条写入的命令。
2:使用replace into语句
replace into 首先尝试插入数据到表中。 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据,否则,直接插入新数据。
使用replace into,你必须具有delete和insert权限
示例:
MariaDB [test]> replace into t (c1,c2,c3,c4,c5) values ('1','1','1','1','2');
Query OK, 2 rows affected (0.00 sec)
# 先执行删除,再执行写入MariaDB [test]> select * from t;
+----+----+----+----+----+
| c1 | c2 | c3 | c4 | c5 |
+----+----+----+----+----+
| 1 | 1 | 1 | 1 | 2 |
| 2 | 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 | 5 |
+----+----+----+----+----+
5 rows in set (0.00 sec)
3:使用insert on duplicate key update语句
如果在insert into 语句末尾指定了on duplicate key update,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则在出现重复值的行执行UPDATE;如果不会导致重复的问题,则插入新行,跟普通的insert into一样。
使用insert into,你必须具有insert和update权限
如果有新记录被插入,则受影响行的值显示1;如果原有的记录被更新,则受影响行的值显示2;如果记录被更新前后值是一样的,则受影响行数的值显示0
示例:
MariaDB [test]> insert into t (c1,c2,c3,c4,c5) values ('1','1','1','1','2') on duplicate key update c2 = 5;
Query OK, 2 rows affected (0.00 sec)MariaDB [test]> select * from t;
+----+----+----+----+----+
| c1 | c2 | c3 | c4 | c5 |
+----+----+----+----+----+
| 1 | 5 | 1 | 1 | 2 |
| 2 | 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 | 5 |
+----+----+----+----+----+
5 rows in set (0.00 sec)
这里需要注意一下:
insert … on duplicate key 在执行时,innodb引擎会先判断插入的行是否产生重复key错误,
如果存在,在对该现有的行加上S(共享锁)锁,如果返回该行数据给mysql,然后mysql执行完duplicate后的update操作,
然后对该记录加上X(排他锁),最后进行update写入。
如果有两个事务并发的执行同样的语句,
那么就会产生death lock(死锁)
因此在使用的时候尽量避免:
尽量对存在多个唯一键的table使用该语句
在有可能有并发事务执行的insert 的内容一样情况下不使用该语句
4:总结
这三种方法都能避免主键或者唯一索引重复导致的插入失败问题。
insert ignore能忽略重复数据,只插入不重复的数据。
replace into和insert … on duplicate key update,都是替换原有的重复数据,区别在于replace into是删除原有的行后,在插入新行,如有自增id,这个会造成自增id的改变;insert … on duplicate key update在遇到重复行时,会直接更新原有的行,具体更新哪些字段怎么更新,取决于update后的语句。
有好的建议,请在下方输入你的评论。
欢迎访问个人博客
https://guanchao.site
欢迎访问小程序:
mysql索引(七)唯一索引相关推荐
- php普通索引和唯一索引,mysql下普通索引和唯一索引的效率对比
昨天有位同事说,他的网页查询过程中发现普通索引和唯一索引的效率是有差别的,普通索引比唯一索引快 今天在我的虚拟机中布置了环境,测试抓图如下: 抓的这几个都是第一次执行的,刷了几次后,取平均值,效率大致 ...
- mysql 普通索引和唯一索引_MySQL 普通索引和唯一索引的区别
该文为< MySQL 实战 45 讲>的学习笔记,感谢查看,如有错误,欢迎指正 一.查询和更新上的区别 这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响.建议尽量选择普通索引 ...
- php普通索引和唯一索引,MySQL中普通索引和唯一索引的区别详解
本篇文章介绍了MySQL中普通索引和唯一索引的区别,讲解很详细,希望对学习MySQL的朋友有帮助! 需要注意的是: redo log中的数据,可能还没有 flush 到磁盘,磁盘中的 Page 1 和 ...
- mysql 唯一索引 性能_普通索引和唯一索引的区别、性能差异,以及其他索引简介...
唯一索引和普通索引使用的结构都是B-tree,执行时间复杂度都是O(log n). 1.普通索引 普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度.因此,应该只为那些最 ...
- MySQL中的索引(唯一索引篇)
MySQL中的索引(唯一索引篇) 唯一索引与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值. 一.如何添加唯一索引 直接创建唯一索引 Create unique index 索引名 on ...
- MySQL普通索引与唯一索引__mysql中唯一索引和普通索引的用途及区别
MySQL普通索引与唯一索引 索引作用: 提高查询效率,一般加在经常查询或者排序的字段上. 普通索引: 允许字段值重复 唯一索引: 保证数据记录唯一性 如何选择: 查询过程: 对普通索引来说,找到满足 ...
- MySQL 普通索引和唯一索引的区别详解
1 概念区分 普通索引和唯一索引 普通索引可重复,唯一索引和主键一样不能重复. 唯一索引可作为数据的一个合法验证手段,例如学生表的身份证号码字段,我们人为规定该字段不得重复,那么就使用唯一索引.(一般 ...
- mysql 创建唯一索引_Mysql普通索引和唯一索引的选择分析
假设一个用户管理系统,每个人注册都有一个唯一的手机号,而且业务代码已经保证了不会写入两个重复的手机号.如果用户管理系统需要按照手机号查姓名,就会执行类似这样的 SQL 语句: select name ...
- MySQL的普通索引和唯一索引到底什么区别?
1 概念区分 普通索引 V.S 唯一索引 普通索引可重复,唯一索引和主键一样不能重复. 唯一索引可作为数据的一个合法验证手段,例如学生表的身份证号码字段,人为规定该字段不得重复,那么就使用唯一索引.( ...
- MySQL中的聚簇索引、非聚簇索引、联合索引和唯一索引
一.索引类型 索引根据底层实现可分为B-Tree索引和哈希索引,大部分时候我们使用的都是B-Tree索引,因为它良好的性能和特性更适合于构建高并发系统. 根据索引的存储方式来划分,索引可以分为聚簇索引 ...
最新文章
- Linux CenOS7下安装ActivetMQ
- PHP抽象类abstract关键字
- Android4.1 新功能 新特性(转)
- C/C++查找一定范围内的素数(筛法)
- unity3d 鼠标延各个方向拖拽物体
- 【编译原理】如何编写BNF?
- 四剑客查找字符_Shell四剑客Grep
- CPU虚拟化的常见技术
- 1.2、Mybatis二级缓存测试
- linux文件复制和移动
- 徐家骏:我在华为工作十年的感悟 (转)
- SAP SLT数据同步配置
- python测试之道进阶_深入学习AB测试(一)-AB Testing With Python[项目实战]
- 汇川H5U模拟量输入模拟量转换 FC S_ITR
- OCA,OCP,OCM傻傻分不清?
- anemometer mysql 500_Anemometer将Mysql慢查询日志可视化
- p4est 2.3.2 安装
- linux群晖文件路径,如何访问本地网络中 Synology NAS 上的文件 (NFS)
- 第二章 大数据如此重要,引无数英雄竞折腰
- 【思科源码实例】企业网络搭建项目,带文档和PKT源文件.局域网网络作业.