目录

1. 主键定义... 5

2. 主键设计原则... 5

2.1 确保主键的无意义性... 5

2.2 采用整型主键... 5

2.3 减少主键的变动... 5

2.4 避免重复使用主键... 6

2.5 主键字段定义区分... 6

3. 主键方案... 6

3.1 自增ID.. 6

3.2 UUID.. 7

3.3 ID物理主键+UUID逻辑主键... 7

4. 总结... 8

1. 主键定义

表中经常有一个列或多列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。

2. 主键设计原则

总原则:根据数据库表的具体使用范围来决定采用不同的表主键定义。

2.1 确保主键的无意义性

在开发过程中,有意义的字段例如“用户登录信息表”将“登录名”(英文名)作为主键,“订单表”中将“订单编号”作为主键,如此设计主键一般都是没什么问题,因为将这些主键基本不具有“意义更改”的可能性。

但是,也有一些例外的情况,例如“订单表”需要支持需求“订单可以作废,并重新生成订单,而且订单号要保持原订单号一致”,那将“订单编号”作为主键就满足不了要求了。

因此在使用具有实际意义的字段作为主键时,需要考虑是否存在这种可能性。

要用代理主键,不要使用业务主键。任何一张表,强烈建议不要使用有业务含义的字段充当主键。我们通常都是在表中单独添加一个整型的编号充当主键字段。

2.2 采用整型主键

主键通常都是整数,不建议使用字符串当主键。(如果主键是用于集群式服务,可以采用字符串类型)

2.3 减少主键的变动

       主键的值通常都不允许修改,除非本记录被删除。

2.4 避免重复使用主键

       主键的值通常不重用,意味着记录被删除后,该主键值不再使用。

2.5 主键字段定义区分

主键不要直接定义成【id】,而要加上前缀,定义成【表名id】或者【表名_id】

 

3. 主键方案

3.1 自增ID

优点:

n  数据库自动编号,速度快,而且是增量增长,聚集型主键按顺序存放,对于检索非常有利。

n  数字型,占用空间小,易排序,在程序中传递方便。

缺点:

n  当系统与其他系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突。在多个数据库间进行数据的复制时(SQL Server的数据分发、订阅机制允许我们进行库间的数据复制操作),自动增长式字段可能造成数据合并时的主键冲突及表关联关系的丢失。

n  如果其他系统主键不是数字型,会导致修改主键数据类型,导致其他相关表的修改。

n  在数据缓冲模式下,很难预先填写主键与外键的值。

n  自增量的值都是需要在系统中维护一个全局的数据值,每次插入数据时即对此次值进行增量取值。当在产生唯一标识的并发环境中,每次的增量取值都必须为此全局值加锁解锁以保证增量的唯一性。造成并发瓶颈,降低查询性能。每创建一条记录都需要对表加一次锁,在高并发环境下开销较大。

3.2 UUID

UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。在UUID的算法中,可能会用到诸如网卡MAC地址,IP,主机名,进程ID等信息以保证其独立性。

优点:

n  全局唯一性、安全性、可移植性。

n  能够保证独立性,程序可以在不同的数据库间迁移,效果不受影响。

n  保证生成的ID不仅是表独立的,而且是库独立的,在你切分数据库的时候尤为重要。

缺点:

n  InnoDB为聚集主键类型的引擎,数据会按照主键进行排序,由于UUID的无序性,InnoDB会产生巨大的IO压力。InnoDB主键索引和数据存储位置相关(簇类索引),uuid 主键可能会引起数据位置频繁变动,严重影响性能。

n  作为主键,UUID长度过长,主键索引KeyLength长度过大,而影响能够基于内存的索引记录数量,进而影响基于内存的索引命中率,而基于硬盘进行索引查询性能很差。严重影响数据库服务器整体的性能表现。

3.3 ID物理主键+UUID逻辑主键

InnoDB不适合使用UUID做物理主键,可以把它作为逻辑主键,物理主键依然使用自增ID。

主键仍然用auto_increment_int来做,而另加一个uuid做唯一索引,表外键关联什么的,还 用uuid来做,也就是说auto_increment_int只是一个形式上的主键,而uuid才是事实上的主键,这样,一方面int主键不会浪费太多空间,另一方面,还可以继续使用uuid。

优点:

n  InnoDB会对主键进行物理排序,这对auto_increment_int类型有好处,因为后一次插入的主键位置总是在最后。但是对uuid来说则有缺点,因为uuid是杂乱无章的,每次插入的主键位置是不确定的,可能在开头,也可能在中间,在进行主键物理排序的时候,势必会造成大量的 IO操作影响效率。

缺点:

n  同自增ID的缺点:全局值加锁解锁以保证增量的唯一性带来的性能问题。

4. 总结

本文主要针对MySQL数据库中的InnoDB存储引擎的主键设计原则进行调研,挑选了几种主流的主键方案进行优缺点的分析和对比,并最终建议选择自增ID作为物理主键,同时使用UUID作为逻辑主键的方案。

如果一些特殊的表,比如说日志表,其不需要维护,可以采用数据库自动增长ID的方式。这种方式性能好,产生也很方便。但是维护很麻烦。

MySQL数据库主键设计原则的更多相关文章

  1. 关于MySql数据库主键及索引的区别

    一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...

  2. Mysql数据库主键,外键,索引概述

    主键: 主键是数据表的唯一索引,比如学生表里有学号和姓名,姓名可能有重名的,但学号确是唯一的,你要从学生表中搜索一条纪录如查找一个人,就只能根据学号去查找,这才能找出唯一的一个,这就是主键;如:id ...

  3. Statement和PreparedStatement的特点 MySQL数据库分页 存取大对象 批处理 获取数据库主键值

    1 Statement和PreparedStatement的特点   a)对于创建和删除表或数据库,我们可以使用executeUpdate(),该方法返回0,表示未影向表中任何记录   b)对于创建和 ...

  4. SQL 数据库主键 ,外键

    主键 数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过它可强制表的实体完整性.当创建或更改表时可通过定义 PRIMARY KEY约束来创建主键.一个 ...

  5. 数据库主键到底是用自增长(INT)好还是UUID好

    其实针对使用自增长还是UUID,大家讨论最多的就是速度和存储空间,这里我加入了安全性和分布式,具体对比如下: 使用自增长做主键的优点:1.很小的数据存储空间2.性能最好3.容易记忆使用自增长做主键的缺 ...

  6. c#生成唯一编号方法记录,可用数据库主键 唯一+有序

    数据库主键目前主要有两种: a.自增数值型 优:占用空间小,插入快,有序对索引友好,易懂 缺:多数据库迁移会有重复键值问题,有可能爆表 b.GUID 优:多数据库唯一 缺:占用空间大,无序对索引不友好 ...

  7. 使用Hashids来保护你的数据库主键

    为什么要保护数据库主键? 数据库主键一般是有序自增主键,极易被爬虫抓取数据,作为应用开发者,这是不应该的,你辛辛苦苦收集的数据转眼之间被其他人给抓取了,是不是很大的损失? Hashids的介绍 gen ...

  8. 数据库主键跟外键+修改mysql的密码

    update myspl.user set password=PASSWORD(设置的密码)  where user='root'; 如果修改错误:先执行use mysple;再重复上面的代码. 一. ...

  9. MySQL中innodb表主键设计原则

    主键设计的原则:1. 一定要显式定义主键2. 采用与业务无关的单独列3. 采用自增列4. 数据类型采用int,并尽可能小,能用tinyint就不用int,能用int就不用bigint5. 将主键放在表 ...

随机推荐

  1. mysqldb模块的简单用法

    # - *- coding:utf-8-*-import urllib2import reimport MySQLdbimport sysreload(sys)sys.setdefaultencodi ...

  2. POJ2762 UV

    题意:n个山洞,对于每两个山洞s,e,都满足s可以到达e或者e可以到达s,则输出Yes,否则输出No. ---------------------------------------- 第一个缩点的题 ...

  3. css3的2D转换

    CSS3的2D转换用transform来实现 1.rotate()   /*通过 rotate() 方法,元素顺时针旋转给定的角度.允许负值,元素将逆时针旋转.*/ 2.scal()   /*通过 s ...

  4. [原创]PCB知识补充

    近期又要使用Altium进行PCB板的绘制,算起来从大学课上第一次接触Protel99SE到现在已经算是半个熟练工了.不过现在想来还是能回忆起第一次使用的情景,对着一幅简单的原理图使用着自动连线的功能 ...

  5. Codeforces Round #383 _python作死系列

    A. Arpa's hard exam and Mehrdad's naive cheat 题意求1378的n次方的最后一位,懒的写循环节 瞎快速幂 py3 int和LL 合并为int了 def q_ ...

  6. 第三十八章 springboot+docker(maven)

    回顾上一章的整个部署过程: 使用"mvn install"进行打包jar 将jar移动到与Dockerfile文件相同的文件夹下 编写Dockerfile文件 使用"do ...

  7. 企业项目如何打包成.ipa文件

    首先准备好企业的项目,真机和申请好的正式证书,关于企业证书的申请此处不再写,可以参考网上相关的教程,本人并未参与证书申请,所以此处不敢乱写. 1.找到正式证书与描述文件,双击打开(需要密码,这个要问申 ...

  8. Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...

  9. 柬埔寨手机上网资费套餐(3G/4G上网)

    柬埔寨三大运营商 Cellcard   官网套餐详情http://www.cellcard.com.kh/cellcard-internet Metfone  官网套餐详情http://www.met ...

  10. 一个关于AM335X比较全面的笔记博客

    http://www.eefocus.com/marianna/blog/cate_18142_0.html