论 mysql 主键

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 什么是主键: 表中经常有一个列或列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。

什么是主键:

表中经常有一个列或列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能有一个 PRIMARY KEY 约束,而且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束确保唯一数据,所以经常用来定义标识列。  

作用:  


1)保证实体的完整性;   

2)加快数据库的操作速度   

3) 在表中添加新记录时,mysql会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。   

4) mysql自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。



主键的必要性:  


有些朋友可能不提倡数据库表必须要主键,但在我的思考中,觉得每个表都应该具有主键,不管是单主键还是双主键,主键的存在就代表着表结构的完整性,表的记录必须得有唯一区分的字段,主键主要是用于其他表的外键关联,本记录的修改与删除,当我们没有主键时,这些操作会变得非常麻烦。


主键的无意义性:  


我强调主键不应该具有实际的意义,这可能对于一些朋友来说不太认同,比如订单表吧,会有“订单编号”字段,而这个字段呢在业务实际中本身就是应该具有唯一性,具有唯一标识记录的功能,但我是不推荐采用订单编号字段作为主键的,因为具有实际意义的字段,具有“意义更改”的可能性,比如订单编号在刚开始的时候我们一切顺利,后来客户说“订单可以作废,并重新生成订单,而且订单号要保持原订单号一致”,这样原来的主键就面临危险了。因此,具有唯一性的实际字段也代表可以作为主键。因此,我推荐是新设一个字段专门用为主键,此主键本身在业务逻辑上不体现,不具有实际意义。而这种主键在一定程序增加了复杂度,所以要视实际系统的规模大小而定,对于小项目,以后扩展不会很大的话,也查允许用实际唯一的字段作主键的。



主键的选择  


①编号作主键  此方法就是采用实际业务中的唯一字段的“编号”作为主键设计,这在小型的项目中是推荐这样做的,因为这可以使项目比较简单化,但在使用中却可能带来一些麻烦,比如要进行“编号修改”时,可能要涉及到很多相关联的其他表,就像黎叔说的“后果很严重”;还有就是上面提到的“业务要求允许编号重复时”,我们再那么先知,都无法知道业务将会修改成什么?  

②自动编号主键  这种方法也是很多朋友在使用的,就是新建一个ID字段,自动增长,非常方便也满足主键的原则,优点是:数据库自动编号,速度快,而且是增量增长,聚集型主键按顺序存放,对于检索非常有利;数字型的,占用空间小,易排序,在程序中传递也方便;如果通过非系统增加记录(比如手动录入,或是用其他工具直接在表里插入新记录,或老系统数据导入)时,非常方便,不用担心主键重复问题。  缺点:其实缺点也就是来自其优点,就是因为自动增长,在手动要插入指定ID的记录时会显得麻烦,尤其是当系统与其他系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突(前提是老系统也是数字型的);如果其他系统主键不是数字型那就麻烦更大了,会导致修改主键数据类型了,这也会导致其他相关表的修改,后果同样很严重;就算其他系统也是数字型的,在导入时,为了区分新老数据,可能想在老数据主键前统一加一个“o”(old)来表示这是老数据,那么自动增长的数字型又面临一个挑战。  

③Max加一  由于自动编号存在那些问题,所以有些朋友就采用自己生成,同样是数字型的,只是把自动增长去掉了,采用在Insert时,读取Max值后加一,这种方法可以避免自动编号的问题,但也存在一个效率问题,如果记录非常大的话,那么Max()也会影响效率的;更严重的是并发性问题,如果同时有两人读到相同的Max后,加一后插入的ID值会重复,这已经是有经验教训的了。  

④自制加一  考虑Max加一的效率后,有人采用自制加一,也就是建一个特别的表,字段为:表名,当前序列值。这样在往表中插入值时,先从此表中找到相应表的最大值后加一,进行插入,有人可能发现,也可能会存在并发处理,这个并发处理,我们可以采用lock线程的方式来避免,在生成此值的时,先Lock,取到值以后,再unLock出来,这样不会有两人同时生成了。这比Max加一的速度要快多了。但同样存在一个问题:在与其他系统集成时,脱离了系统中的生成方法后,很麻烦保证自制表中的最大值与导入后的保持一致,而且数字型都存在上面讲到的“o”老数据的导入问题。因此在“自制加一”中可以把主键设为字符型的。字符型的自制加一我倒是蛮推荐的,应该字符型主键可以应付很多我们意想不到的情况。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
NoSQL 关系型数据库 MySQL
MySQL主键与索引
MySQL主键与索引
58 1
|
3月前
|
存储 SQL 关系型数据库
高效访问数据的关键:解析MySQL主键自增长的运作机制!
高效访问数据的关键:解析MySQL主键自增长的运作机制!
|
6月前
|
存储 SQL 关系型数据库
MySQL主键约束详解
MySQL是一个强大的关系型数据库管理系统,用于存储和管理大量数据。在数据库中,主键约束是一项非常重要的概念,它有助于确保数据的完整性和唯一性。本文将详细介绍MySQL主键约束,包括什么是主键、为什么需要主键、如何创建主键以及主键的最佳实践。
289 1
|
4月前
|
存储 关系型数据库 MySQL
【面试】Mysql主键索引普通索引索引和唯一索引的区别是什么?
【面试】Mysql主键索引普通索引索引和唯一索引的区别是什么?
316 0
【面试】Mysql主键索引普通索引索引和唯一索引的区别是什么?
|
4月前
|
关系型数据库 MySQL
MySQL中数据插入与主键冲突解决方案
MySQL中数据插入与主键冲突解决方案
185 0
|
5月前
|
存储 关系型数据库 MySQL
MySQL中库/表/字段/主键/用户操作示例与详解
MySQL中库/表/字段/主键/用户操作示例与详解
101 0
|
2月前
|
存储 关系型数据库 MySQL
用雪花 ID 和 UUID 做 MySQL 主键,可以吗?
用雪花 ID 和 UUID 做 MySQL 主键,可以吗?
31 0
用雪花 ID 和 UUID 做 MySQL 主键,可以吗?
|
6月前
|
XML Java 数据库连接
【MySQL用法】MyBatis 多对多 中间表插入数据,添加记录后获取主键ID
【MySQL用法】MyBatis 多对多 中间表插入数据,添加记录后获取主键ID
61 0
|
7月前
|
关系型数据库 MySQL
Mysql 主键冲突(ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY')
Mysql 主键冲突(ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY')
311 0
|
7月前
|
关系型数据库 MySQL 数据库
MySQL中如何设置 auto_increment 重新计数 主键id从1开始
几句话解决 auto_increment 重新计数?
147 0
MySQL中如何设置 auto_increment 重新计数 主键id从1开始