`
daniel_tu
  • 浏览: 182603 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

数据库主键设计之思考

阅读更多

在我们的数据库设计中,不可逃避的就是数据库表的主键,可能有很多朋友没有深入思考过,主键的设计对整个数据库的设计影响很大,因此我们不得不要重视起来。

主键的必要性 :

有些朋友可能不提倡数据库表必须要主键,但在我的思考中,觉得每个表都应该具有主键,不管是单主键还是双主键,主键的存在就代表着表结构的完整性,表的记录 必须得有唯一区分的字段,主键主要是用于其他表的外键关联,本记录的修改与删除,当我们没有主键时,这些操作会变的非常麻烦。

主键的无意义性

我 强调主键不应该具有实际的意义,这可能对于一些朋友来说不太认同,比如订单表吧,会有“订单编号”字段,而这个字段呢在业务实际中本身就是应该具有唯一 性,具有唯一标识记录的功能,但我是不推荐采用订单编号字段作为主键的,因为具有实际意义的字段,具有“意义更改”的可能性,比如订单编号在刚开始的时候 我们一切顺利,后来客户说“订单可以作废,并重新生成订单,而且订单号要保持原订单号一致”,这样原来的主键就面临危险了。因此,具有唯一性的实际字段也 代表可以作为主键。因此,我推荐是新设一个字段专门用为主键,此主键本身在业务逻辑上不体现,不具有实际意义。而这种主键在一定程序增加了复杂度,所以要 视实际系统的规模大小而定,对于小项目,以后扩展不会很大的话,也查允许用实际唯一的字段作主键的。

主键的选择

我们现在在思考一下,应该采用什么来作表的主键比较合理,申明一下,主键的设计没有一个定论,各人有各人的方法,哪怕同一个,在不同的项目中,也会采用不同的主键设计原则。

第一:编号作主键

此方法就是采用实际业务中的唯一字段的“编号”作为主键设计,这在小型的项目中是推荐这样做的,因为这可以使项目比较简单化,但在使用中却可能带来一些麻烦,比如要进行“编号修改”时,可能要涉及到很多相关联的其他表,就象黎叔说的“后果很严重” ; 还有就是上面提到的“业务要求允许编号重复时”,我们再那么先知,都无法知道业务将会修改成什么 ?

第二:自动编号主键

这种方法也是很多朋友在使用的,就是新建一个 ID 字段,自动增长,非常方便也满足主键的原则,优点是:数据库自动编号,速度快,而且是增量增长,聚集型主键按顺序存放,对于检索非常有利 ; 数字型的,占用空间小,易排序,在程序中传递也方便 ; 如果通过非系统增加记录(比如手动录入,或是用其他工具直接在表里插入新记录,或老系统数据导入)时,非常方便,不用担心主键重复问题。

缺点:其实缺点也就是来自其优点,就是因为自动增长,在手动要插入指定 ID 的记录时会显得麻烦,尤其是当系统与其他系统集成时,需要数据导入时,很难保证原系统的 ID 不发生主键冲突(前提是老系统也是数字型的) ; 如果其他系统主键不是数字型那就麻烦更大了,会导致修改主键数据类型了,这也会导致其他相关表的修改,后果同样很严重 ; 就算其他系统也是数字型的,在导入时,为了区分新老数据,可能想在老数据主键前统一加一个“ o ”(old)来表示这是老数据,那么自动增长的数字型又面临一个挑战。

第三: Max 加一

由于自动编号存在那些问题,所以有些朋友就采用自己生成,同样是数字型的,只是把自动增长去掉了,采用在 Insert 时,读取 Max 值后加一,这种方法可以避免自动编号的问题,但也存在一个效率问题,如果记录非常大的话,那么 Max() 也会影响效率的 ; 更严重的是并发性问题,如果同时有两人读到相同的 Max 后,加一后插入的 ID 值会重复,这已经是有经验教训的了。

第四:自制加一

考虑 Max 加一的效率后,有人采用自制加一,也就是建一个特别的表,字段为:表名,当前序列值。这样在往表中插入值时,先从此表中找到相应表的最大值后加一,进行插入,有人可能发现,也可能会存在并发处理,这个并发处理,我们可以采用 lock 线程的方式来避免,在生成此值的时,先 Lock ,取到值以后,再 unLock 出来,这样不会有两人同时生成了。这比 Max 加一的速度要快多了。但同样存在一个问题:在与其他系统集成时,脱离了系统中的生成方法后,很麻烦保证自制表中的最大值与导入后的保持一致,而且数字型都存在上面讲到的“ o ”老数据的导入问题。因此在“自制加一”中可以把主键设为字符型的。字符型的自制加一我倒是蛮推荐的,应该字符型主键可以应付很多我们意想不到的情况。

第五: GUID 主键

目前一个比较好的主键是采用 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 最好,其实在不同的情况,我们都可以采用上面的某一种方式,思考了一些利与弊,也方便大家在进行设计时参考。这些也只是我的一点思考而已,而且可能我知识面限制,会有一些误论在里面,希望大家有什么想法欢迎讨论。

 

                                                                                                                                               听棠

                                                                                                                                            2005-3-2

分享到:
评论

相关推荐

    ORCALe (如 描 述)

    数据库连接以及备份技巧.txt 数据库设计中的14个技巧.txt 数据库主键设计之思考.txt 用连接池提高Servlet访问数据库的效率.txt SQL21自学通.pdf oracle错误代码和信息速查手册.chm oraclewebserver中文手册.chm Java...

    数据库主键的设计和思考

    数据库主键设计是数据库设计中的核心部分,主键是用来唯一标识一条记录的字段,它确保了数据的唯一性和完整性。本文主要讨论了两种常见的主键设计策略:自增主键和GUID主键。 首先,自增主键是利用数据库系统提供的...

    数据库课程设计 数据库与信息管理综合设计

    ### 数据库课程设计知识点解析 #### 一、项目概述 本次综合设计的项目是“图书管理系统”,旨在通过实践加深学生对数据库系统原理的理解,并掌握信息管理系统的开发方法和步骤。项目涉及从需求分析到最终系统实现的...

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

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

    电子商务网站数据库结构设计

    4. **主键设计**:优先使用单主键,避免使用联合主键带来的复杂性。业务属性不宜作为主键,以防修改时引发连锁反应。主键字段应选用能满足需求的最短长度,提升操作速度。 5. **考虑数据操作**:设计时需思考数据的...

    大型数据库ORACLE数据库的优化设计思考.pdf

    应考虑适当的数据类型、字段长度、主键和外键设计,以减少数据冗余和提高数据一致性。索引是加速查询的关键,但过多或不合适的索引会增加写操作的开销。应根据查询模式创建并维护必要的索引,同时监控索引使用情况,...

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

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

    \数据库设计的案例分析

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

    数据库系统设计实验

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

    数据库课程设计 人事管理系统

    - **数据库表结构设计**:根据概念模型设计出具体的数据库表结构,包括字段定义、主键设置等。 - **性能优化**:通过对数据库查询语句的优化、合理设置索引等方式提升系统的运行效率。 #### 七、物理设计和实施 - ...

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

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

    数据库设计60个技巧.pdf

    ### 数据库设计60个技巧概览 #### 第一部分:设计数据库之前 1. **考察现有环境** - 在启动新的数据库项目时,不仅要深入了解业务需求,还应该全面审视现有的系统环境。通常情况下,企业已经有一些系统在运行,...

    数据库课程设计说明书

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

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

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

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

    7. **课程设计要求**:强调了独立思考和完成任务的重要性,禁止抄袭,上机准备的充分性,以及课程设计报告的格式和内容要求,如引言、概要设计、详细设计、调试运行和课程设计心得。 8. **设计环境**:报告中提到了...

    数据库课程设计详细文档

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

    学习Oracle数据库课程设计报告.pdf

    - 总体设计:设计数据库的架构,确定各表之间的关系,考虑数据完整性约束(如主键、外键、唯一性等)。 - 表设计:定义各个数据表的字段、数据类型、索引等,确保满足业务需求。 - 创建数据库:实际创建数据库对象,...

Global site tag (gtag.js) - Google Analytics