`
xuyongping
  • 浏览: 119642 次
  • 性别: Icon_minigender_1
  • 来自: 部落格
社区版块
存档分类
最新评论

数据库主键设计原则

SQL 
阅读更多
或许大家都设计过数据库,也为表定义过主键,今天我想阐述的是,应该如何正确的设计一个主键,在以往的一些资料中,都没有提及到主键设计的原则.我为此总结了一下:


1.是否要采用GUID作为主键

用GUID作主键有它的优势与不足.优势是GUID具有唯一性,在任何情况下,可以产生全球唯一的值.这是GUID最大的优势,也方便数据导入,比如要求从另一个系统中把数据导入进来,那么,不用担心,导入时,会导致主键冲突.不足是GUID值太复杂.不易记忆,因为有时,难免我们会用记录的方式,来进行记录判断.而且数据太长,影响数据库效率.GUID的产生不是以一定的次序产生,对于按主键物理排序的数据库来说,如果在记录的前部插入一条记录,可能会导致后面N次方的数据条数后移.这将导致数据插入效率.因此GUID的采用应该要慎重.


2.是否要采用自动递增的方式

对于以前谈到的主键,要求唯一性,因此大家都用自动递增的方式.这样的方式是非常不可取的.可能是为了方便插入记录时,不必去人为创建主键值.以为这样会方便,其实不是的.带来的麻烦要远远胜于这种所谓的"方便".第一:数据导入不方便,经常会有从另一系统导入数据进来,自动递增的主键,将不允许原表中的ID被导入进来.这会导致主键丢失.第二:对于象订单这样的有主外键的表来说,如果订单的"主档表"主键是自动生成的.那么在保存一个订单时,会要求对主档表与明细表同进行事务保存,而此时,先要生成一条订单,然后取出这个订单自动生成的主键,然后再把此作为明细表的一个外键,进行明细的保存.这过程中,将变以复杂而且不可行.事务如何处理.订单主档表插入记录后,要是明细保存时遇到错误,主档表记录还要进行删除.烦.插入成功以后,还要取出产生的最大值.这将是一个严重的浪费.记录多的话会影响速度,而且会存在并行插入.导致获取的记录可能是不正确的. 因此在以上的严重问题下,请不要采用自动递增方式.


3.是否要采用int型作为主键

以前大家都采用int型,都是出来主键都是数字导致的.其实我们也明白.并不是只是数字的东西就是数字型的.比如电话号码等.因此对于主键,采用int型的优势是速度快,插入,查询时都可能会比其他的方式快.但我这种快的效果也未必有多明显,比如以varchar(15)为例,物理主键排序的数据,会自动以主键进行物理数据排序.因此,就算是字符型的数据,在插入时也会插入到相应的物理位置上,也就是说,在插入时可能会影响一些速度.但在以后的查询中,速度影响不会太明显.而我要说的,不采用int型作为主键,不是说,里面不存数据.我还是建议大家在主键中存放数字,这样的排序比较要比夹杂字母的排序来的快,之所以要采用字符型,也是为以后的数据导入作准备,有一天,会要求从其他表导入数据时,可以在导入数据的主键上加一个特定字母来避免与原主键冲突.比如在导入数据的主键前加一个"N"字母.这也就不用担心,要求导入数据表中的主键是数字型还是字符型了.


4.是否采用编号来定义主键

这个问题是老生常谈了.主键设计有个原则,就是主键不应具有任何实际意义.这条其实是非常重要,有人就是觉得编号本身是唯一的,可以作为主键用,但可能会为以后带来麻烦.因为带有实际意义的字段,还是存在被修改的可能性.而对于主键最大的忌讳就是修改主键,这可能会导致非常严重的不可估计的后果.比如学生编号,平时以为永远不会修改,但修改的可能还是会存在.

还有一种,表面上是唯一的,但实际上应该是允许重复的.我举个例子,订单吧,订单编号应该是唯一吧.是的.可是会存在这样的情况,一张原来的订单是因为某个原因,要求订单作废.那好给订单的状态标识为"cancel".然后允许再次录入同样编号的订单.因此.对于这样的情况下在,虽然有效的订单编号只有一个,但在数据库角度会允许编号重复.所以不管如何,还是建议大家为表都建一个没有任何意义的主键,如ID.

因此,总结一下,我在设计主键,会采用字符型的.不采用自动递增,在新增记录时,系统生成主键值.一般为全数字进行存入,至于主键值的生成规则,可以按需求进行规则定义.如果没有特殊的要求,只是为了保持唯一,可以定义一个字段存放一个数值.在生成时,自动加一.然后再存回去.这也比从一个表中寻找最大值要来的快吧.










目前一个比较好的主键是采用GUID,当然我是推荐主键还是字符型的,但值由GUID生成,GUID是可以自动生成,也可以程序生成,而且键值不可能重复,可以解决系统集成问题,几个系统的GUID值导到一起时,也不会发生重复,就算有“o”老数据也可以区分,而且效率很高,在.NET里可以直接使用System.Guid.NewGuid()进行生成,在SQL里也可以使用 NewID()生成。

  优点是:

  同 IDENTITY 列相比,uniqueidentifier 列可以通过 NewID() 函数提前得知新增加的行 ID,为应用程序的后续处理提供了很大方便。

  便于数据库移植,其它数据库中并不一定具有 IDENTITY 列,而 Guid 列可以作为字符型列转换到其它数据库中,同时将应用程序中产生的 GUID 值存入数据库,它不会对原有数据带来影响。

  便于数据库初始化,如果应用程序要加载一些初始数据, IDENTITY 列的处理方式就比较麻烦,而 uniqueidentifier 列则无需任何处理,直接用 T-SQL 加载即可。

  便于对某些对象或常量进行永久标识,如类的 ClassID,对象的实例标识,UDDI 中的联系人、服务接口、tModel标识定义等。

  缺点是:

  GUID 值较长,不容易记忆和输入,而且这个值是随机、无顺序的。

  GUID 的值有 16 个字节,与其它那些诸如 4 字节的整数相比要相对大一些。这意味着如果在数据库中使用 uniqueidentifier 键,可能会带来两方面的消极影响:存储空间增大;索引时间较慢。

  我也不是推荐GUID最好,其实在不同的情况,我们都可以采用上面的某一种方式,思考了一些利与弊,也方便大家在进行设计时参考。这些也只是我的一点思考而已,而且可能我知识面限制,会有一些误论在里面,希望大家有什么想法欢迎讨论。
分享到:
评论
2 楼 skill_job 2013-04-14  
“主键设计有个原则,就是主键不应具有任何实际意义.”

奇怪了,这个问题一直有争论,不知道你说的这个原则是谁规定的?
1 楼 happyxuzheng 2010-09-05  
我个人觉得选择数据类型为字符串的主键并且主键存入的是由数字进行组合的为佳,因为就像你提到的数据移植问题,灵活性和适用性会更好点。

相关推荐

    数据库主键设计原则 设计数据库主健

    数据库主键设计原则:我在设计主键,会采用字符型的.不采用自动递增,在新增记录时,系统生成主键值.一般为全数字进行存入,至于主键值的生成规则,可以按需求进行规则定义.如果没有特殊的要求,只是为了保持唯一...

    数据库主键设计原则.txt

    数据库主键设计原则 或许大家都设计过数据库,也为表定义过主键,今天我想阐述的是,应该如何正确的设计一个主键,在以往的一些资料中,都没有提及到主键设计的原则. 我为此总结了一下: 1.是否要采用GUID作为主键 用GUID...

    数据库中表的主键设计原则收藏.doc

    数据库中表的主键设计原则收藏

    数据库主键和外键设计的原则.doc

    数据库主键和外键设计的原则

    数据库设计原则.docx

    数据库设计原则全文共5页,当前为第1页。数据库设计原则全文共5页,当前为第1页。1. 原始单据与实体之间的关系 数据库设计原则全文共5页,当前为第1页。 数据库设计原则全文共5页,当前为第1页。 可以是一对一、一对...

    数据库设计规范模板.pdf

    目 次 1 范围 2 引用文件 3 术语、定义和缩略语 3.1 术语 3.2 缩略语 4 总体要求 4.1 数据库设计总体要求 4.2 数据库编程总体要求 5 数据库设计要求 5.1 数据库字符集选择 5.2 数据库表空间设计原则 5.3 数据库分区...

    数据库设计原则(1).pdf

    数据库设计原则 数据库设计原则 1. 原始单据与实体之间的关系 可以是⼀对⼀、⼀对多、多对多的关系。在⼀般情况下,它们是⼀对⼀的关系:即⼀张原始单据对应且只对应⼀个实体。 在特殊情况下,它们可能是⼀对多或多...

    政务平台数据库设计.doc

    数据库设计 省级政务平台数据库设计 数据库设计原则 (1)标准化 严格按照相关技术标准完成数据库的设计,包括国土资源部颁发的相应数据库建库规 范标准、国家已经发布的许多基础的行业分类、代码标准,以及在信息化...

    美食数据库的设计.docx

    本系统是按照需求分析、概念模型设计、逻辑结构设计、数据库的实施和维护的流程完成数据库设计,力求满足该设计原则。 数据库表设计 数据库的设计通常是以一个已经存在的数据库管理系统为基础的,常用的数据库管理...

    数据库设计思路.doc

    数据库的设计原则 遵循数据库设计的三个范式的要求,可以允许有少量的数据冗余。 一即对属性的原子性约束,要求属性具有原子性,不可再分解。 二即对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性。 三即对...

    数据库物理设计.pdf

    年 ⽉ ⽇ ⼩时 分 秒 周 其他: 如何选择主键: 1、区分业务主键和数据库主键: 业务主键:标⽰业务数据,进⾏表与表之间的关联。 数据库主键:优化数据存储。(Innodb会⽣成6个字节的隐含主键) 2、根据数据库的...

    《Access2016数据库教程》第2章数据库的设计与创建.pptx

    5 确定数据库需要建立的表和各表包含的字段及主键 确定表之间的联系 优化设计 应用规范化理论对表设计进行检查,以减少冗余。 在数据库中创建表及其他相关的对象 《Access2016数据库教程》第2章数据库的设计与创建...

    浅谈数据库设计方法.doc

    浅谈数据库主键设计的原则[J].电脑知识与技术,2011,22(36):12- 16. [2]熊慧芳.数据库主键的设计方法探讨[J].无线互联科技, 2013,32(07):54- 57. [3]张立伟,唐伟.浅谈ABAP程序的优化[J].科技致富向导, ...

    学生成绩管理系统数据库设计.doc

    学生成绩管理系统数据库设计 [提要] 一个好的数据库,不但可以提高数据查询效率,而且还可以保证数据的完整性和一致性 。所以,数据库在信息管理系统中有着非常重要的作用。本文介绍如何使用SQL Server 2005完成学生...

    数据库设计说明书模板

    数据库设计说明书 版本:V1.0 文 档 编 号 保 密 等 级 作 者 最后修改日期 审 核 人 最后审批日期 批 准 人 最后批准日期 修订记录 日期 版本 修订说明 修订人 目 ...

    1数据库大作业.doc

    1 1.2数据库设计原则 2 1.3数据库需求分析 3 1.4数据库概念结构设计 4 1.4.1图书管理涉及的实体 4 1.4.2用 E-R 图来表示图书管理的概念模型 4 1.5数据库逻辑设计 4 1.6创建数据库脚本 5 2数据库数据维护与操作 6 2.1...

    数据库设计规范V.docx

    本规范的适用IT范围包括数据库对象的命名规范、设计原则、SQL语句的设计和使用、SQL语句的性能优化建议、其他与性能有关的设计原则以及设计工具的选择。 命名规范 通用规范 不同的数据库产品对对象的命名有不同的...

    数据库设计思想.docx

    =================================================================================== 防止数据库设计打补丁的方法是"三少原则" (1) 一个数据库中表的个数越少越好。只有表的个数少了,才能说明系统的E--R图少而...

    数据库技术规范.docx

    =或操作符子句使用 8 不要对索引字段进行运算 8 不要对索引字段进行格式转换 8 不要对索引字段使用函数 9 不要对索引字段进行多字段连接 9 Like的使用 9 10 设计 10 数据库逻辑设计的规范化 10 合理的冗余 10 主键的...

    Oracle数据库设计规范建议.doc

    4 数据库对象设计原则 4.1 表的设计 4.1.1 主、外键 4.1.1.1 每个表,都必须要有主键。主键是每行数据的唯一标识,保证主键不可随意更新修改, 在不知道是否需要主键的时候,请加上主键,它会为你的程序以及将来...

Global site tag (gtag.js) - Google Analytics