原文:http://www.itpub.net/thread-1133732-1-1.html
一、背景从事软件行业这些年来,我在一些软件项目的数据库表设计中,使用了几种数据表主键方式:数据库自动增量方式,GUID方式,主键流水号方式。
这里对各种方式进行一个简单的比较和建议。
二、业务术语2.1.数据表字段自动增量方式数据表的主键字段,使用自动增量方式,由数据库维护其值。当用户插入记录到数据库表时,用户并不需要为自动增量字段指定一个值,数据库内部为自动为该字段赋予一个值。
数据库表的主键字段如果是自动增量,一般都是数字型(整数)。
2.2.GUID/UUID式的主键字段使用社会公开的算法,产生GUID/UUID一个全球唯一的字符串作为数据表字段。当用户插入记录到数据库表时,使用公开的算法产生一个GUID/UUID,并保存到数据库中。
2.3.主键流水号在常用的软件系统中,也常遇到使用一个数据库表来维护各个数据库表的主键值使用情。
在实际使用时,用户调用一定的接口,比如:传入数据库表名称,字段名称,软件系统的主键接口程序为用户返回一个主键流水号。
一般来说,主键流水号的数据类型是整数类型。
三、各种主键策略的比较
评价参数 | 自动增量方式 | GUID方式 | 流水号式 |
数据插入成本 | 最好 | 较差 | 较差 |
数据查询成本 | 较好 | 较差 | 较好 |
主键字段排序方便性 | 较好 | 较差 | 较好 |
系统数据迁移唯一性 | 较差 | 最好 | 较差 |
iBatis跨数据库方面 | 较差 | 最好 | 较好 |
hibernate跨数据库方面 | 较好 | 最好 | 较好 |
多系统数据交换方面 | 较差 | 最好 | 较好 |
l增加时间戳的GUID: 20081028172124640-0ad09547-1b14-4aab-b74d-39e7a42e39e0
l时间转换成为字符规则:
年月日时分秒毫秒+GUID
4.2.2.带数据来源的变种GUID/UUID在这里我们就前面的思路再发散下,其实我们可以在主键上在赋予一定的数据业务意义。
我们可以在前面的变种GUID的基础上,再增加一个数据源标识号。比如:
A001-20081028172124640-0ad09547-1b14-4aab-b74d-39e7a42e39e0
其中A001是表达了我们电话号码中的区号的作用。一看该号码就知道数据来自于哪里。
这种策略在一个系统在客户的多个分支机构中部署比较有用,如果到时候这些数据汇总在一起,数据不会重复,而且也知道数据来自于那个地方,方便进一步的数据处理和数据交换。
4.3.主键流水号使用主键流水号策略来给系统各个数据库表分配主键值,这种策略在一个软件公司建设行业产品时比较经常见到。
4.3.1.弊端:接口程序每次在用户申请主键时候,从主键流水表获得一个最新主键值给使用者。这样认为的为系统并发性方面设置了一个瓶颈。
4.3.2.带缓存的主键流水号针对前面的这种主键流水号策略,提出主键缓存来弥补并发性的不足。
主键接口程序为每个表的主键值做一个缓存,当用户来获取主键市,接口程序从缓存中分配一个主键给使用者,当指定数据表缓存的主键分配完或者要分配完时,主键接口程序从数据库重新获得一批主键缓存起来以备用户使用。
例子:
l主键接口程序SEQService,入口参数是数据表名称,字段名称,返回结果是一个整数。
l用户申请Book表的ID字段的主键
l主键接口程序SEQService使用懒汉加载模式,查询主键缓存去是否有该表的主键缓存数据;
l主键缓存区中没有Book表的ID字段的主键的缓存数据,主键接口程序从数据库中申请一批主键(假设为获取数量100,主键可用值为1001到1100开始),同时更新主键流水表的当前使用值。
l主键接口程序分配分配一个主键值(1001)给用户使用,更新主键缓存信息(当前可用主键值为1002,最大可用值为1100)。
这种带缓存的主键流水号策略,可以用于集群部署环境,同样有效。
这种缓存策略实际上可吧主键缓存看成是内存缓存,数据库是硬盘存储。
4.3.3.业务流水号!=主键流水号在实际业务中,可能面临公文流水号也是采用连续号码的情况,公文的流水号是采用:前缀+公文流水+后缀组成。
实际上这个公文流水号充当的是“务系统逻辑主键“,并不是物理主键,为了保证该号码的连续性,需要在上面缓存的主键流水号基础上做个变通,接口程序不再采用前面的写回策略(先访问主键缓存,不满足要求,访问数据库),而是采用写通的策略,接口策略直接访问主键流水表,然后分配一个主键给使用者。
4.3.4.变种的带步长的主键流水号带步长的主键是:系统分配给用户的主键值不是连续的,是有一定步长的。比如:系统主键开始值为1,补偿为10;拿第一个使用者拿到的主键值为1,第二个使用者拿到的是11。
l好处:
这种策略可用于系统在总部、多公司部署,同时满足数据交换和数据整合要求。
例如:
公司甲总部的主键策略是,使用数据库表的主键开始值为1000,主键步长是10;公司甲的上海分公司的主键开始值为1001主键步长是10;公司甲的东京分公司的主键开始值为1002键步长是10;公司甲的纽约分公司的主键开始值为1003键步长是10。
根据公司甲的要求,可以在任何时候把总部和各个分公司的数据进行合并,却能保证数据不会冲突。这就是主键流水表的开始值不一样补偿一样的功劳。
l不足:
如果系统在部署的时候,估计不足,步长设计过小,比如:上面例子中设计为10,当有第11个分公司冒出来需要部署系统时,这时候步长就不够用了。
变通的方式,可采用前面的变种GUID作为主键,或者一开始就把系统主键值的补偿设计大一点,比如:50或者100。
五、系统中的各种业务流水号业务流水号是属于业务模型中的内容,系统数据主键流水号是系统模型中的内容。这两者既相互独立,也有一定关系。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12180666/viewspace-1018941/ ,如需转载,请注明出处,否则将追究法律责任。