`

数据库主键的设计和思考

 
阅读更多

文:阿蜜果

日期:2011-10-16

版权所有,转载请注明出处

1、 何谓数据库主键

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

1.1 主键的作用

主键的主要作用如下:

1)保证实体的完整性;

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

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

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

1.2 主键的特点

1)唯一性一个表中只能有一个主键。如果在其他字段上建立主键,则原来的主键就会取消。

2)非空性:主键的值不可重复,也不可为空;

3)必要性:在有些数据库中,虽然主键不是必需的,但最好为每个表都设置一个主键,不管是单主键还是复合主键。它存在代表着表结构的完整性,表的记录必须得有唯一区分的字段,主键主要是用于其他表的外键关联,以及本记录的修改与删除;

4)无意义性:在开发过程中,读者可能会看到将一些表使用有意义的字段表示主键,例如“用户登录信息表”将“登录名”(英文名)作为主键,“订单表”中将“订单编号”作为主键,如此设计主键一般都是没什么问题,因为将这些主键基本不具有“意义更改”的可能性。但是,也有一些例外的情况,例如“订单表”需要支持需求“订单可以作废,并重新生成订单,而且订单号要保持原订单号一致”,那将“订单编号”作为主键就满足不了要求了。因此读者在使用具有实际意义的字段作为主键时,需要考虑是否存在这种可能性。

2、 主键的创建和更改

  在MySQL中,创建时指定某字段为主键的举例如下:

create table article (
id 
int(4primary key not null auto_increment,
name 
varchar(100not null,
author 
varchar(32not null,
publishTime 
datetime default NULL
);

  标示为主键的字段需要使用“primary key”标识。

若要删除某个表中之前的主键,并设置另外一个字段作为主键,参考语句如下:

ALTER TABLE 表名 DROP PRIMARY KEYADD PRIMARY KEY (新的主键字段);

主键可以在执行create table操作时,在字段的后面使用“primary key”指定,也可以不位于字段后面,例如如下语句:

 

create table ss_schedule
(
    schedulekey            
varchar(30not null,
    schedulename           
varchar(255),
    updatekey              
varchar(30),
    
primary key (schedulekey)
);

 3、 主键的选择以及优缺点比较

3.1 自增主键

       这种方式是使用数据库提供的自增数值型字段作为自增主键,它的优点是:

1)数据库自动编号,速度快,而且是增量增长,按顺序存放,对于检索非常有利;

2)数字型,占用空间小,易排序,在程序中传递也方便;

3)如果通过非系统增加记录时,可以不用指定该字段,不用担心主键重复问题。

其实它的缺点也就是来自其优点,缺点如下:

1)因为自动增长,在手动要插入指定ID的记录时会显得麻烦,尤其是当系统与其它系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突(前提是老系统也是数字型的)。特别是在新系统上线时,新旧系统并行存在,并且是异库异构的数据库的情况下,需要双向同步时,自增主键将是你的噩梦;

2)在系统集成或割接时,如果新旧系统主键不同是数字型就会导致修改主键数据类型,这也会导致其它有外键关联的表的修改,后果同样很严重;

3)若系统也是数字型的,在导入时,为了区分新老数据,可能想在老数据主键前统一加一个字符标识(例如“o”,old)来表示这是老数据,那么自动增长的数字型又面临一个挑战。

MySQLauto_increment)、SQL ServerIDENTITY)、InformixOracle(首先创建自增序列,接着为自增主键的表创建插入时的触发器,给自增主键ID赋值)等数据库都支持这种自增主键,这种主键在各种系统中应用广泛,但是如果考虑到有新旧系统并存等问题,为了避免不必要的麻烦,使用自增主键要三思。

3.2 max+1主键

由于增主键存在的缺点,所以有些开发人员就采用自己生成同样是数字型的的主键,但不是系统自动生成的。具体的方式是:在INSERT时,读取主键IDMax值后,加1,这种方法可以避免自动编号的问题,但是也存在各种缺点:

1)效率问题:如果记录非常大的话,那么Max()也会影响效率的;

2)并发性问题:如果同时有两人读到相同的Max后,加一后插入的ID值会重复。

基于这些明显的缺点,笔者不提倡使用此种方式。

3.3 自制+1主键

考虑max+1的效率后,有的开发人员采用自制加1,也就是建一个特别的表,字段为:表名、当前序列值。这样在往表中插入值时,先从此表中找到相应表的最大值后加一,进行插入,但也可能会存在并发处理,但是开发人员可以采用lock线程的方式来避免:在生成此值的时,先Lock,取到值以后,再unLock出来,这样不会有两人同时生成了。这比max+1的速度要快多了。

就算解决了并发的问题,但此种方式同样存在致命的缺点:

1)在与其他系统集成时,脱离了系统中的生成方法后,很麻烦保证自制表中的最大值与导入后的保持一致。

因为此种还需要创建新表,比较麻烦,因此笔者也不推荐此种方式。

3.4 具有实际意义的主键

         有些表可以使用具有实际意义的主键,但这种表为数不多,因为要保证该字段长久的具有行记录唯一的特点,如若有可能变成该表中的非唯一字段,那它就不适合将其变成主键。

         笔者建议有些表可以使用具有实际意义的主键,例如“用户信息表”的“用户登录名”字段基本都是唯一的,而且几乎不可能变成一个登录名对应两条记录,因此可以使用其作为主键。另外,例如“一号通用户信息表”中,“一号通号码”肯定是唯一的,因此也可作为主键。

3.5 GUID主键

目前一个比较好的主键是采用GUIDGlobally Unique Identifier,全球唯一标识符),GUID的特点如下:

(1)   在空间上和时间上具有唯一性,保证同一时间不同地方产生的数字不同;

(2)   世界上的任何两台计算机都不会生成重复的GUID值;

(3)   需要GUID的时候,可以完全由算法自动生成,不需要一个权威机构来管理;

(4)   GUID的长度固定,并且相对而言较短小,非常适合于排序、标识和存储。

可以将GUID主键定义为字符型,但值由GUID生成,GUID是可以自动生成,也可以程序生成,而且键值不可能重复,可以解决系统集成问题,几个系统的GUID值导到一起时,也不会发生重复,就算有“o”老数据也可以区分,而且效率很高。在SQL里也可以使用 NewID()生成。主要优点是:

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

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

缺点是:

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

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

基于上面的分析,使用GUID的利大于弊,笔者推荐可以采用此种方式。

3.6 自制唯一字符型主键

         为了系统集成等的方便,笔者建议将主键定义成字符型,可以使用GUID作为主键,也可以定义一个字符型的主键字段,但是它的值使用变成编程指定。该种方式的优点是:

1)在异库异构数据库的情况下,若旧系统这些表的主键ID是自增的(数值型),而新系统生成的主键是比较长的字符串型(例如15位),那样旧系统生成或之前的旧数据同步到新系统时,都不会冲突。

这种方式的缺点是:

(1)       需要程序能生成定长的唯一字符串,例如:当前时间+自动机号+进程ID+……;

(2)       由第三方系统生成或手动生成该主键时,处理比较麻烦。

3.7 总结

         在上面几种主键中,较为常用的是“3.1 自增主键”和“3.5 GUID主键”,当在有些特殊的表和某些特定情况中,也可以采用“3.4 具有实际意义的主键”和“3.6 自制唯一的字符型主键”。

4、 参考文档

1)《主键设计用什么字段类型比较好》:

http://www.th7.cn/Article/bc/de/200902/20090220080511.html

2)《主关键字_百度百科》:

http://baike.baidu.com/view/68068.htm

3)《GUID_百度百科》:

http://baike.baidu.com/view/185358.htm

分享到:
评论

相关推荐

    数据库主键设计之思考

    数据库主键设计之思考 在数据库设计中,主键的设计是非常重要的。主键的存在代表着表结构的完整性,表的记录必须得有唯一区分的字段,主键主要是用于其他表的外键关联,本记录的修改与删除。当我们没有主键时,这些...

    关于数据库设计中主键问题的思考

    数据库设计中的主键选择是一个关键环节,因为它直接影响到系统的稳定性和效率。主键的主要功能是唯一标识表中的每一行记录,确保数据的准确性和一致性。本文主要探讨了几种常见的主键选取策略及其优缺点。 首先,...

    数据库课程设计-EasyMall电子商城.doc

    数据库课程设计是计算机科学领域中一项重要的实践活动,旨在让学生深入理解和应用数据库理论知识。在这个案例中,学生们被要求设计一个名为EasyMall的电子商城系统,以加深对MySQL数据库、MyEclipse集成开发环境以及...

    \数据库设计的案例分析

    在数据库设计中,ER 模型是将实体、属性和关系转换为关系模型的关键步骤。本案例分析了一个教学管理系统的 ER 模型的设计和转换过程。 ER 模型设计 在教学管理系统中,我们可以识别出四个实体:学生、专业、学院和...

    数据库系统设计实验

    数据库系统设计实验是计算机科学与信息技术领域中一个重要的实践环节,它涵盖了理论知识与实际操作的结合,旨在帮助学生深入理解和掌握数据库管理系统的原理、设计方法以及应用技巧。在这个实验中,我们将探讨以下几...

    电商-数据库详细设计说明书

    通过《电商-数据库详细设计说明书V0.4.doc》,我们可以深入理解电商数据库设计背后的思考与规划,为电商平台的稳定运行和高效运营提供坚实的基础。这份文档的详尽程度和专业性,无疑对电商系统的开发与维护至关重要...

    数据库课程设计说明书

    数据库课程设计说明书旨在引导学生通过实际操作来理解数据库系统的设计与实现,这通常涉及数据库的概念模型设计、逻辑结构设计、物理结构设计以及数据库的管理和维护。在这个过程中,VB(Visual Basic)语言常被用于...

    数据库课程设计网吧管理系统.doc

    " "参考资 "《数据库系统概论》 " "料 "《数据库系统概论实验指导书》自编 " " "《数据库系统概论课程设计大纲》等自编 " "指导教 " " "师评语 "该生在数据库系统概论课程设计期间:上机时不迟到,不缺席,爱护设 ...

    2019数据库原理课程设计要求及课题 (1).doc

    3. 逻辑结构设计:此阶段将E-R图转换为关系模型,确定关系的名称、属性、主键和外键。这一过程涉及到关系模型的规范化,如确保满足第三范式(3NF)或更高范式,以减少数据冗余和提高数据一致性。 4. 物理结构设计:...

    数据库课程设计详细文档

    最后,学生需要提交一份详细的实训设计报告,包含需求分析、数据字典、E-R图、数据流图和SQL语句等内容,以全面展示其在整个设计过程中的思考和实现。 通过这样的课程设计,学生不仅能够熟悉数据库的基本操作,还能...

    数据库课程设计任务书(.pdf

    这要求学生独立完成,小组人数控制在1-2人,鼓励单人完成,以锻炼独立思考和解决问题的能力。二是提交课程设计报告,并进行系统的演示,展示设计成果。 在设计过程中,有几点基本要求。在数据库设计阶段,需要进行...

    数据库思考题整理(by学长)1

    数据库思考题整理(by学长)1涵盖了数据库系统的多个方面,包括三级模式结构、数据独立性、概念模型、关系数据库模式、SQL、视图、数据库安全性、数据库完整性和数据库规范化设计等多个方面,为学习和研究数据库系统...

    Oracle数据库课程设计报告(1).doc

    计 报 告 书 目 录 第1章 引言 3 第2章 概要设计 5 2.1系统需求分析 5 2.2系统结构设计 5 2.3系统功能模块 6 第3章 数据库分析 7 3.1 数据库总体设计 7 3.2 数据表设计 7 3.3 数据库的创建 8 3.4存储过程和触发器 ...

    数据库课程设计电力公司收费系统.pdf

    在进行数据库课程设计时,这一主题旨在提升学生对数据库理论和实践技能的理解与运用,培养他们的自主学习、独立思考和软件设计能力。 首先,设计的目标主要包括以下几个方面: 1. 学生需掌握数据库理论,并能将其...

    数据库管理设计

    【数据库管理设计】是《大型数据库实训》课程中的一个重要任务,其目的是让学生深入理解和掌握数据库的基本原理和设计方法。在这一课程中,学生需要通过实际操作来实现一个客房管理系统的数据库设计,以此来巩固和...

    OLMS-DBDD-1.0数据库设计说明1

    4.1 数据库逻辑设计会详细描述数据表结构、字段类型、主键和外键关系,以及业务规则。例如,可能会有用户表(user)、图书表(book)、借阅记录表(borrowing),并通过用户ID和图书ID来建立关联。 4.2 数据库物理设计则...

    学习情景2-数据库的设计.pptx

    学习情景2 数据库的设计 学习情景2-数据库的设计全文共124页,当前为第1页。 ER图的组成元素 ER模型是一种用图形表示数据及其联系的方法,ER模型通过ER图来表示。 ER图包括三个组成元素,分别是实体、联系和属性。 ...

    商品销售管理数据库系统设计.doc

    【商品销售管理数据库系统设计】 本项目旨在设计一个商品销售管理数据库系统,旨在提升企业对销售信息处理的效率,确保信息的快速、...这是一个将理论知识应用于实践的绝佳机会,有助于培养学生的独立思考和创新能力。

    网上图书系统数据库设计.zip

    这样的文档对于理解和维护数据库至关重要,因为它记录了设计过程的思考,有助于后期的代码审查和问题排查。 总的来说,这个压缩包提供了一个完整的网上图书系统数据库设计实例,从概念到物理,再到文档化,覆盖了...

Global site tag (gtag.js) - Google Analytics