`
lylyb
  • 浏览: 90456 次
  • 性别: Icon_minigender_1
  • 来自: 烟台
社区版块
存档分类
最新评论

数据库主键设计(转)

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

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

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

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

      第二:自动编号主键
      这种方法也是很多朋友在使用的,就是新建一个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最好,其实在不同的情况,我们都可以采用上面的某一种方式,思考了一些利与弊,也方便大家在进行设计时参考。这些也只是我的一点思考而已,而且可能我知识面限制,会有一些误论在里面,希望大家有什么想法欢迎讨论。
分享到:
评论

相关推荐

    数据库主键的五种设计方法

    数据库主键设计的五种方法 数据库主键设计是数据库设计中一个非常重要的环节,好的主键设计可以提高数据库的性能和可扩展性。本文将介绍五种常见的主键设计方法,每种方法都有其优点和缺陷。 第一种:编号作主键 ...

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

    ### 数据库主键设计原则详解 #### 一、引言 在数据库设计中,主键的设计至关重要,它不仅关系到数据的唯一性,还影响着数据检索效率以及系统的整体性能。本文将根据提供的描述和部分内文,深入探讨数据库主键设计...

    数据库主键设计之思考

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

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

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

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

    "数据库中表的主键设计原则收藏" 在设计数据库表时,主键的设计是非常重要的一步。一个好的主键设计可以提高数据库的性能和可维护性,而一个糟糕的主键设计可能会带来一系列的问题。本文将讨论数据库中表的主键设计...

    MySQL数据库主键重复原因分析及处理.pdf

    MySQL数据库主键重复原因分析及处理.pdf MySQL数据库主键是数据库管理系统中的一种...MySQL数据库主键是关系型数据库设计的核心概念,它可以保证数据的唯一性和完整性。但是,主键重复的问题也需要引起注意和解决。

    数据库主键设计原则.txt

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

    数据库主键生成资料资源

    同时,主键设计还应考虑到未来可能的业务变更,以确保系统的灵活性和稳定性。 在进行数据库设计时,不仅要关注主键的生成,还要注意主键与其他字段的关系,比如避免使用外键作为主键,防止级联删除带来的风险;同时...

    分布式数据库唯一主键设计

    "分布式数据库唯一主键设计"涉及到如何在多节点、多表环境中创建并管理这种全局唯一的标识符。本文将深入探讨这一主题,旨在帮助读者理解如何在分布式环境中有效地设计和实现唯一主键。 一、主键的概念与重要性 ...

    数据库主键生成GUID

    数据库主键生成GUID 在数据库设计中,选择合适的主键类型是非常重要的。GUID(Global Unique Identifier,全局唯一标识符)是一种常用的主键类型,它可以提供唯一的标识符,用于标识数据库中的每一条记录。 GUID的...

    小议数据库主键选取策略

    我们在建立数据库的时候,需要为每张表指定一个主键,所谓主键是能够标识...  常见的数据库主键选取方式有:  自动增长字段  手动增长字段  UniqueIdentifier  “COMB(Combine)”类型  一、自动增长型字段

    后台数据库设计 后台数据库设计 后台数据库设计

    后台数据库设计知识点总结 后台数据库设计是指在学生信息管理系统中设计和实现一个后台数据库的过程。该数据库的主要目的是为了存储和管理学生的信息,包括学生编号、姓名、籍贯、入学日期、出生日期、性别、备注...

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

    《网吧管理系统数据库课程设计》是一份详尽的文档,涵盖了从需求分析到系统设计的全过程。这份设计报告主要关注如何构建一个高效、安全的网吧管理系统数据库,以满足网吧日常运营的需求。 1. 需求分析是设计的第一...

    数据库课程设计指导教程 包括各步骤的详细解释说明

    3. 逻辑设计:将E-R图转换为关系模型,确定表结构、字段类型、主键和外键等。此阶段还需考虑数据的规范化,如第一范式(1NF)、第二范式(2NF)和第三范式(3NF),以减少数据冗余和提高数据一致性。 4. 物理设计:...

    数据库课程设计 运动会管理系统.rar

    数据库课程设计是IT教育中的一个重要环节,它旨在让学生实践如何运用数据库理论知识来解决实际问题。在这个案例中,我们关注的是一个运动会管理系统的数据库设计。这个系统可能涉及到运动员信息管理、比赛项目安排、...

    数据库表设计工具

    - 主键和外键:主键用于唯一标识表中的每条记录,外键则建立了不同表之间的关系,支持数据库的完整性。 - 索引设计:通过添加索引,可以提高数据查询的性能,特别是对经常查询的字段。 - 规范化:遵循一定的规范...

    数据库详细设计

    数据表的设计包括字段设计、主键设计、索引设计和关系设计等方面。 在数据表设计中,我们需要确定数据表的结构、字段类型、主键、索引和关系等。 数据库性能优化 数据库性能优化是指对数据库的查询优化、索引优化...

    数据库索引设计和优化

    数据库索引设计与优化是数据库管理系统中至关重要的一个环节,它直接影响到数据查询的效率、存储空间的使用以及系统的整体性能。在这个主题中,我们将深入探讨数据库索引的基础概念、设计原则、优化策略以及实际应用...

    .数据库设计_数据库详细设计.doc

    这份文档《数据库设计_数据库详细设计.doc》显然聚焦于数据库的详细设计阶段,这一阶段是数据库生命周期中的关键步骤,主要包括概念设计、逻辑设计和物理设计。 1. **概念设计**:在这一阶段,设计者会根据业务需求...

    大型数据库课程设计火车站票务管理系统.pdf

    在本系统中,我们需要对火车站票务管理系统的数据库完整性进行设计,了解系统的主键及唯一性索引、参照完整性设计、Check约束、Default约束和触发器设计等方面的内容。 在主键及唯一性索引设计中,我们需要了解系统...

Global site tag (gtag.js) - Google Analytics