目录

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. Linux启动/停止/重启Mysql数据库的方法——转载

    Mysql启动.停止.重启常用命令 a.启动方式1.使用 service 启动:[root@localhost /]# service mysqld start (5.0版本是mysqld)[root ...

  2. EAS linux挂载数据盘

    查看数据盘名称 fdisk -l 假设没有挂载的数据盘为/dev/xvdb 格式化数据盘 mkfs.ext3 /dev/xvdb 添加自动挂载 mkdir /data echo '/dev/xvdb ...

  3. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ad Hoc Distributed Queries'。

    今天单位一ASP.NET网站,里面有个功能是导出数据,发现一导出就报错,报错内容是:SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT ...

  4. css样式表 格式与布局

    1 样式表  内联样式表  内嵌样式表  外部样式表 2 选择器 标签选择器 <style type="text\css" class 选择器  以.开头 ID选择器 以#开 ...

  5. poj 2060 Taxi Cab Scheme (二分匹配)

    Taxi Cab Scheme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5710   Accepted: 2393 D ...

  6. jquery 遍历 数组1

    使用了jquery有段时间了,整理下jquery中的遍历问题. 1.jquery 遍历对象 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Tr ...

  7. Android(Xamarin)之旅(二)

    新的一年,新的开始,2016,我要做什么,大家要做什么,啦啦啦. OK,上篇已经介绍了几个简单的控件,这次,我们继续说说控件.但是可能有人认为这有什么难的,问题不在这里,而在于,如果你注意了每一个空间 ...

  8. iOS IPv6兼容支持和IPv6审核被拒收集整理

    最近遇到一个大坑:IPv6审核被拒问题,于是广寻解决方案,先把一些可以用资料文档收集起来备用.也希望同行能用得着. 官方文档说明:Supporting IPv6 DNS64/NAT64 Network ...

  9. Robot Framework-DatabaseLibrary数据库(MySql)

    Robot Framework-Mac版本安装 Robot Framework-Windows版本安装 Robot Framework-工具简介及入门使用 Robot Framework-Databa ...

  10. Windows 8.1 应用再出发 - 几种新增控件(1)

    Windows 8.1 新增的一些控件,分别是:AppBar.CommandBar.DatePicker.TimePicker.Flyout.MenuFlyout.SettingsFlyout.Hub ...