转:http://www.360doc.com/content/05/0920/18/1681_13536.shtml
数据库主键设计之思考
主键的必要性:
有些朋友可能不提倡数据库表必须要主键,但在我的思考中,觉得每个表都应该具有主键,不管是单主键还是双主键,主键的存在就代表着表结构的完整性,表的记录必须得有唯一区分的字段,主键主要是用于其他表的外键关联,本记录的修改与删除,当我们没有主键时,这些操作会变的非常麻烦。
主键的无意义性:
我强调主键不应该具有实际的意义,这可能对于一些朋友来说不太认同,比如订单表吧,会有“订单编号”字段,而这个字段呢在业务实际中本身就是应该具有唯一性,具有唯一标识记录的功能,但我是不推荐采用订单编号字段作为主键的,因为具有实际意义的字段,具有“意义更改”的可能性,比如订单编号在刚开始的时候我们一切顺利,后来客户说“订单可以作废,并重新生成订单,而且订单号要保持原订单号一致”,这样原来的主键就面临危险了。因此,具有唯一性的实际字段也代表可以作为主键。因此,我推荐是新设一个字段专门用为主键,此主键本身在业务逻辑上不体现,不具有实际意义。而这种主键在一定程序增加了复杂度,所以要视实际系统的规模大小而定,对于小项目,以后扩展不会很大的话,也查允许用实际唯一的字段作主键的。
主键的选择
我们现在在思考一下,应该采用什么来作表的主键比较合理,申明一下,主键的设计没有一个定论,各人有各人的方法,哪怕同一个,在不同的项目中,也会采用不同的主键设计原则。
第一:编号作主键
此方法就是采用实际业务中的唯一字段的“编号”作为主键设计,这在小型的项目中是推荐这样做的,因为这可以使项目比较简单化,但在使用中却可能带来一些麻烦,比如要进行“编号修改”时,可能要涉及到很多相关联的其他表,就象黎叔说的“后果很严重”;还有就是上面提到的“业务要求允许编号重复时”,我们再那么先知,都无法知道业务将会修改成什么?
第二:自动编号主键
这种方法也是很多朋友在使用的,就是新建一个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最好,其实在不同的情况,我们都可以采用上面的某一种方式,思考了一些利与弊,也方便大家在进行设计时参考。这些也只是我的一点思考而已,而且可能我知识面限制,会有一些误论在里面,希望大家有什么想法欢迎讨论。
相关推荐
一个好的主键设计可以提高数据库的性能和可维护性,而一个糟糕的主键设计可能会带来一系列的问题。本文将讨论数据库中表的主键设计原则,并总结出四点重要的设计原则。 首先,是否要采用 GUID 作为主键?GUID 具有...
### 数据完整性、主键和外键、数据类型 #### 数据完整性 数据完整性是数据库设计中的一个核心概念,指的是确保数据库中的数据保持一致性和准确性。在实际应用中,数据完整性能够帮助我们防止非法或错误的数据被...
在传统的数据库设计中,我们通常使用整型数据类型作为自增ID,通过设置AUTO_INCREMENT属性来自动递增主键值。但对于某些特定场景,例如需要主键包含日期信息或具有固定长度和格式时,CHAR类型则显得更为适用。为了...
MySQL 数据库中的列类型,也就是字段类型,是数据库设计中的关键元素,决定了数据的存储方式和处理方式。列类型分为三大类:数值类、字符串类和日期/时间类。 数值类数据列类型主要包括整型和浮点型。整型又分为 ...
MySQL字段类型是数据库设计的基础,它决定了数据存储的格式和方式。MySQL支持多种数据类型,主要分为数值型、字符型、日期和时间型以及NULL值。 1. 数值型: - 整数类型:包括TINYINT、SMALLINT、MEDIUMINT、INT和...
通过以上对主键和外键错误的总结,我们可以看到正确的使用主键和外键对于数据库设计的重要性。合理的主键和外键不仅可以提高数据管理的效率,还可以确保数据的一致性和完整性。因此,在设计数据库时,需要充分考虑到...
在探讨Hibernate中联合主键的使用时,我们首先需要理解什么是联合主键以及它在Hibernate框架中的实现方式。联合主键(Composite Primary Key),是指在数据库表中使用两个或多个字段共同作为主键来唯一标识每一行...
在EOS(Entity Operation System)开发过程中,联合主键(Composite Primary Key)是一个重要的概念,它在数据模型设计中起着至关重要的作用。联合主键是由两个或更多个字段组成的唯一标识符,用于确保数据库表中每...
3. **全表扫描**:对于某些类型的查询,如聚合函数(COUNT、SUM等)或者没有使用索引字段的WHERE子句,二级索引可能无法提供帮助,此时仍然需要全表扫描。 4. **索引选择性**:如果索引字段的值分布过于集中,索引...
3. **约束条件**:约束条件是对字段的附加规则,用以限制或验证字段中的数据。常见的约束有NOT NULL(不允许为空)、UNIQUE(唯一)、PRIMARY KEY(主键)、FOREIGN KEY(外键)等。虽然本节不关注约束条件,但它们...
同时,主键设计还应考虑到未来可能的业务变更,以确保系统的灵活性和稳定性。 在进行数据库设计时,不仅要关注主键的生成,还要注意主键与其他字段的关系,比如避免使用外键作为主键,防止级联删除带来的风险;同时...
在Oracle数据库中,自增主键是一种常见的主键设计方式,它能够确保每条记录的唯一性,并且在插入新记录时自动递增,简化了数据管理流程。本文将详细介绍如何在Oracle中设置自增主键。 #### 一、创建序列(Sequence...
这些信息包括表名、字段名、数据类型、字段长度、是否可为空以及主键等。掌握如何有效地获取这些信息对于进行数据库设计、维护和优化具有重要意义。 #### 1. 查询所有用户表 要获取当前用户所有的表信息,可以使用...
总之,创建Mdb字段是数据库设计和管理的基础操作,它涉及到对数据类型的理解、字段属性的配置以及可能的VBA编程,以实现自动化和高效的数据管理。在实际工作中,理解这些概念和技能对于任何处理Access数据库的人来说...
4. 当表结构存在大字段类型时,更新数据,查看目标端更新情况。 四、测试过程 在测试过程中,我们首先构建了完全相同的数据,并更新全部数据以及随机更新数据,然后查看目标端的更新情况。接着,我们构造了 ...
MySQL数据库主键的类型有两种:单字段主键和复合主键。单字段主键是指由一个字段组成的主键,而复合主键是指由多个字段组成的主键。 在MySQL数据库中,主键可以使用AUTO_INCREMENT机制来自动生成主键值。这可以...
2. 在被引用的表中创建字段,类型与主键表对应的主键字段相同。 3. 使用`FOREIGN KEY`关键字声明该字段为外键,并指定引用的主键表和字段。 4. 可以选择启用或禁用外键约束检查,根据数据库管理需求进行设置。 示例...
在数据库设计中,主键和外键是两个关键的概念,它们在确保数据的完整性和一致性方面发挥着重要作用。主键和外键都是Oracle等关系型数据库管理系统(RDBMS)中的重要概念。 **主键**是定义一个表中起主要作用的数据项...