热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql唯一索引_mysql主键和唯一索引的区别

mysql唯一索引_mysql主键和唯一索引的区别Mysql索引大概有五种类型:普通索引(INDEX):最基本的索引,没有任何限制唯一索引(UNIQUE):与普通索引类似,不同

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中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
author-avatar
勋酥-osh海州吴氏
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有