对于一个表来说主键选用的好坏直接关系到对于该表的操作性能,因此主键选用的好坏很大程度上决定了表的相关性能。一般来说选用主键需要遵循以下规则:
- 数据类型用 INT(bigint)类型
-
Int类型在做比较运算时会获取更好的性能(cpu比较周期缩短)。
-
Int类型是顺序排列的这样在索引中逻辑上相邻的数据就分布在磁盘相邻的地方(大大减少IO次数)
- 要尽可能的避免使用字符串来做主键
-
主键长度尽可能短。如果选用bigint做主键由于bigint做主键只占8个字节所以比较节约空间,同时查询性能也很好。
-
字符串来做主键,myisam默认的情况下为字符串使用了压缩索引这使查找更加缓慢。
- 还要特别注意是随机字符串,如MD5(),UUID()。他们产生的每一个新值都会被保存在很大的空间范围(通常会占用32个字节),这会减慢inset 及一些select查询原因如下:
- 他们会减慢insert查询,因为插入的值会被随机放入索引页中,导致分页,随机磁盘访问及聚集存储引擎的聚集索引碎片。
- 他们会减慢查询速度,因为逻辑上相邻的行会分布在磁盘和内存中的各个地方。
- 随机值会导致缓存对所有类型的查询性能都很差,因为他们会使缓存依赖以工作的访问局部性失效,如果整个数据集都变的同样“热”的时候,那么把特定部分的数据缓存到内存中就没有任何优势了。并且如果工作集部能被装入内存中,缓存就会进行很多刷写的工作,并且会导致很多缓存未命中。
- 对于mysql来说存储不同的存储引擎对主键的影响也稍有不同。
-
Myisam 引擎支持和聚集索引(主要是B树索引),不支持聚集索引。
-
Innodb 引擎支持聚集索引,非聚集索引(主要是B树索引,hash索引)。
-
因此对于不支持聚集索引的myisam来说即使建立了主键也是不能为其建立聚集索引的,因此数据的物理排列顺序则是插入数据先后的顺序(myisam插入数据时是直接插入表的尾部的)。虽然数据是插入在表的尾部但是对于索引来说随机的主键值则是按一定的规则进行排列的。这样随机主键就容易导致索引频繁分页,进而出现索引碎片,最终导致insert慢select查询慢。
-
对于innodb来说我们可以为主键建立聚集索引,聚集索引存储记录是物理上连续存在的。因此insert时插入排序规则(uuid_short())的值做主键可以直接将该值追加到表的尾部,且索引没有发生分页。更重要的是对于聚集索引来说索引下面直接对应的就是数据因此按主键查找时效率会比myisam要高很多。(myisam索引下面对应的是指向数据的一个指针)
-
单纯对于myisam来说在选用主键类型时也是要避免使用字符串的。因为myisam上的字符串类型所建立的索引默认采用的是压缩处理后的格式,因此在查询时效率要稍慢一些。
UUID_SHORT() PK UUID()
UUID():用来生成唯一值 该值类型为string长度为32位且为无序的值(所谓无序的值是指每次生成的值没有规律可言或者说是随机的),这决定了他不能做主键
SELECT UUID(); fe534759-be25-11e4-ba95-4437e64f803e
UUID_SHORT():用来生成唯一值(理论上也是有限的但是由于出现出现重复的概率低到了极致或者说出现的概率最大为1/1000000000000000(以最低生成位数来算,实际生成位数一般都大于16)),跟UUID()相比UUID_SHORT()生成的是有序的整数,长度在16-21(或者更长)位之间,如果我们用bigint来存储处理后的UUID_SHORT()作为主键是完全符合主键的选取规则的。
SELECT uuid_short(); 23906203910275154
与uuid返回固定长度字符串不同, uuid_short的返回值是一个unsigned long long类型。MySQL启动后第一次执行的值是通过server_id << 56 + server_start_time << 24来初始化。server_start_time单位是秒。 之后每次执行都加1。
由于每次加1都会加全局mutex锁,因此多线程安全,可以当作sequence来用,只是初始值有点大。
Sequence
MySQL没有Oracle那样的sequence,在不是很精确的情况下,可以考虑上面提到的uuid_short。有一些不足:
1、初始值太大,无法重设
2、存在一个问题是每次重启后第一次执行的值不是重启前的那个值+1
3、而且如果重启在1s内完成,可能出现不单调递增(虽然这个可能性微乎其微)。
相关推荐
MySQL数据库主键重复原因分析及处理.pdf MySQL数据库主键是数据库管理系统中的一种重要概念,它是指在关系型数据库中,每个表的唯一标识符,用于唯一地标识表中的每一条记录。主键是数据库设计的核心概念,关系型...
在数据库设计中,主键和外键是关系型数据库中非常重要的概念,它们用于确保数据的完整性和一致性。本文将详细介绍如何在MySQL...在设计数据库表结构时,应根据具体业务逻辑和数据特性灵活选择主键和外键的类型及组合。
在Python3中操作MySQL数据库并插入一条数据,然后获取并返回这条数据的主键id是数据库编程中常见的需求。这一过程可以分为几个关键步骤:数据库连接、执行插入操作、获取主键id以及事务提交。下面详细说明每个步骤...
mysql修改自增主键初始值,简单易操作,数据库维护小技巧。
在MySQL数据库管理中,自增长主键是一种常见的设计模式,主要用于自动为每一行记录生成一个唯一的标识符。然而,这种自增长通常与整型数据类型(如INT)关联,而较少见于字符型数据(如CHAR)。本文将深入探讨如何在...
在Spring Boot项目中,整合MyBatis并利用MySQL实现主键UUID是一种常见的需求,尤其是在分布式系统中,为了保证数据的一致性和唯一性。UUID(Universally Unique Identifier)是一种全局唯一的标识符,它由128位数字...
MySQL8 自增主键变化 MySQL8 自增主键变化是 MySQL8 中的一项重要变化。从 MySQL5.7 到 MySQL8,系统表引擎发生了变化,全部换成了事务型的 InnoDB。这种变化使得 MySQL8 的系统表引擎都换成了 InnoDB。 MySQL8 中...
MySQL中的主键与唯一索引约束是数据库设计中至关重要的概念,它们确保数据的唯一性和完整性。主键是一种特殊的唯一索引,它定义了一个表的唯一标识,不允许有重复值且不能为空。唯一索引则允许有空值,但索引中的每...
在理解MySQL非主键自增长用法之前,首先需要明确主键和自增长的概念。 **主键(Primary Key)**:在数据库表中,主键是一种特殊类型的字段,它具有唯一性,且不允许有NULL值。主键用来唯一地标识表中的每一行数据,...
MySQL 雪花算法生成唯一整型ID主键的实现主要针对大数据环境下,需要大量生成全局唯一ID的需求。雪花算法是一种分布式ID生成策略,由Twitter开源,其设计目标是在分布式系统中生成具有全局唯一性、有序性和高并发性...
MySQL中的GUID(Globally Unique Identifier)主键生成方式是一种确保数据库中每一条记录具有唯一标识的方法,尤其在分布式系统中十分常见。本示例主要介绍如何通过Hibernate框架配置,来实现MySQL数据库中GUID主键...
在MySQL数据库系统中,主键自增是一种常见的数据表设计策略,它对于数据...了解并掌握这些关于MySQL主键自增的知识,将有助于在面试中表现出对数据库设计和管理的深入理解,也能在实际工作中更有效地管理和维护数据表。
### MySQL AUTO_INCREMENT 主键详解 在数据库设计与应用中,主键是确保数据表每一行记录唯一性的关键机制之一。而`AUTO_INCREMENT`属性则是在MySQL数据库系统中为某些整数类型的主键自动分配唯一值的功能。下面我们...
在这个场景中,我们关注的是如何使用Prometheus来统计MySQL自增主键的剩余可用百分比,以预防生产环境中可能出现的主键溢出问题。 MySQL自增主键是数据库表中一种常见的标识符,它会自动递增以确保每个记录的唯一性...
关系数据库依赖于主键,它是数据库物理模式的基石。主键在物理层面上只有两个用途: 惟一地标识一行。 作为一个可以被外键有效引用的对象。 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),...
表中的主键值很少更改,因此在选择主键是需要小心,要选择很少发生更改的地方。一个表的主键可以被另一个表的外键引用。 为了更好地理解主键,我们创建一个名为Student的表,它具有roll_number、name、batch、phone_...
在MySQL数据库中,主键和外键是关系型数据库设计中的关键概念,它们用于确保数据的一致性和完整性。本文将深入解析这两个概念以及它们之间的联系。 首先,让我们了解什么是主键。主键(Primary Key)是数据库表中一...