`
java-mans
  • 浏览: 11710539 次
文章分类
社区版块
存档分类
最新评论

主键的选择

 
阅读更多

Recently we are going on the School System(教务系统)。Our group is in charge of the Basic Information part.设计和操作数据库,is almost our whole work.

设计数据库阶段,首先,分析需要建哪些表,每张表设计哪些字段;再设计主键和外键,修改和完善数据库。

When I came to the Primary Key, something puzzled me:有些主键,比如xx记录表,主键是int自增类型;而有些,我们选择用编号来作为主键(比如楼号,学号)。然后问题来了,用编号作为主键,当该条信息修改时,以前的记录就被冲掉了,可是我想在数据库保留存在过的所有记录。Well,may be I go wrong.

但是,忽略这两种选择方式,他们都是主键。那么什么是主键,它存在的意义在哪里,它又是做什么的呢?

主键,“主关键字(primary key)是表中的一个或多个字段,它的值用于惟一地标识表中的某一条记录”。

作用:(1)唯一区分每条记录的字段;(2)本记录的修改与删除;(3)用于其它表的外键关联。当我们没有主键时,这些操作会变的非常麻烦。

在我的意识中,每张表都应该有它的主键,主键的存在代表着表结构的完整性。

那么,怎样选择主键??读到一篇文章,提到主键的选择:

(1)编号

采用实际业务中的唯一字段的“编号”作为主键设计,这在小型的项目中是推荐这样做的,因为这可以使项目比较简单化,但在使用中却可能带来一些麻烦。比如上面提到的修改数据时,只能保存现有数据,而不能保存历史数据。还有,要进行“编号修改”时,可能要涉及到很多相关联的其他表,“后果很严重”,当然我们尽量避免。(2)自动增长

就是新建一个ID字段,自动增长。自动增长型字段允许我们在向数据库添加数据时,不考虑主键的取值,记录插入后,数据库系统会自动为其分配一个值,确保绝对不会出现重复。使用SQL Server数据库,我们还可以在记录插入后使用@@IDENTITY全局变量获取系统分配的主键键值。

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

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

(3)Max加一

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

(4)自制加一

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

但同样存在一个问题:在与其他系统集成时,脱离了系统中的生成方法后,很麻烦保证自制表中的最大值与导入后的保持一致,而且数字型都存在上面讲到的“o”老数据的导入问题。因此在“自制加一”中可以把主键设为字符型的。字符型的自制加一我倒是蛮推荐的,应该字符型主键可以应付很多我们意想不到的情况。

(5)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 键,可能会带来两方面的消极影响:存储空间增大;索引时间较慢。

分享到:
评论

相关推荐

    主键的选择1

    综上所述,主键选择需考虑数据量、全局唯一性、分区策略和性能等因素。自增主键适用于单实例的小型系统,而UUID更适合全局唯一的需求。在设计大规模系统时,应结合哈希和分区策略,优化数据分布,避免热点问题,确保...

    数据主键和外键的错误总结

    5. **主键选择不当**:有时候,主键的选择可能会影响到查询的效率。例如,选择一个经常更新的字段作为主键,可能会导致频繁的表重组,从而影响性能。 - **解决方法**:选择一个不太变化或者根本不会变化的字段作为...

    主键和外键.doc

    - **自动增长字段**:最常用的主键选择方式之一,简单易用,适用于大多数场景。 - **手动增长字段**:适用于需要特定顺序或编号的情况,但需要注意避免冲突。 - **GUID/UUID**:全球唯一标识符,适用于分布式系统或...

    数据库,索引,主键,约束,sql

    在数据库设计中,良好的主键选择有助于优化查询性能和数据管理。 约束则用来定义和维护数据的完整性规则。这些规则可以是实体完整性(如主键约束),确保数据不为空;参照完整性(如外键约束),保证引用的外键值...

    行业-67 基于主键的索引是如何设计的,以及如何根据主键索引查询?l.rar

    四、主键选择的注意事项 1. 避免大字段:主键应尽可能小,以减小索引的存储开销和查询时的CPU计算量。避免使用如JSON、XML等大字段作为主键。 2. 稳定性:主键的值一旦确定,不应轻易改变,否则会导致依赖于主键的...

    Mysql面试题主键自增

    3. 主键选择:不是所有情况都适合用自增作为主键,如地理坐标、时间戳等可能不适合,因为它们可能无法保证唯一性。 4. 数据迁移:在数据库迁移或复制时,需谨慎处理自增主键,以避免重复或丢失序列。 五、相关面试...

    聚簇索引与主键的选择

    MyISAM引擎中三、聚簇索引的优劣与主键选择的关系 一、什么是聚簇索引? 首先,聚簇索引不是一种单独的索引类型,其实是数据的存储方式。聚簇索引将数据存储与索引放在了一起,找到了索引也就找到了数据。 在MySql...

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

    数据库主键设计的五种方法 数据库主键设计是数据库设计中一个非常重要的环节,好的主键设计可以提高数据库的性能和可扩展性。...在选择主键设计方法时,我们需要考虑项目的实际情况和需求,选择最适合的方法。

    Hibernate主键生成方式

    5. **Native方式**:`<generator class="native"/>` 这是Hibernate提供的一个便捷策略,它会根据底层数据库的类型自动选择合适的主键生成方式。例如,对于Oracle会选择Sequence,对于MySQL则选择Identity。这种方式...

    持久化类主键生成策略+例子

    在Java的持久化框架中,如JPA(Java Persistence API)和Hibernate,主键生成策略是数据模型设计的重要部分。主键通常是表中唯一标识记录的一列或一组列,用于确保数据的完整性和唯一性。本篇文章将深入探讨JPA的4种...

    数据库主键生成资料资源

    5. 效率:为了快速查找和访问,主键通常被设置为索引,因此选择合适的数据类型和设计可以提高查询性能。 数据库主键的生成方式多种多样,常见的包括: 1. 自动递增:在许多数据库系统中,如MySQL的`AUTO_INCREMENT...

    数据库主键设计之思考

    数据库主键设计之思考 在数据库设计中,主键的设计是非常重要的。主键的存在代表着表结构的完整性,...主键的设计是非常重要的,我们需要根据实际情况选择合适的主键设计方法,以确保我们的数据库设计更加完整和合理。

    oracle表主键和外键的区别

    在设计数据库时,主键和外键的选择应考虑性能、数据的完整性和应用需求。选择适当的键类型和结构对于优化查询性能、简化数据管理和确保数据一致性至关重要。因此,主键和外键的设计是数据库设计中的关键环节,需要在...

    多媒体数据库实验3

    【多媒体数据库实验3】主要涉及了数据库设计的基本概念和理论,包括ER模型、数据库范式、主键选择、外键识别以及实体完整性和参照完整性的理解。以下是详细的知识点解析: 1. **ER模型**:实验中使用了ER图(实体-...

    Hibernate主键生成策略

    ### Hibernate 主键生成策略详解 #### 一、概述 Hibernate 是一款开源的对象关系映射 (ORM) 框架,它允许开发人员将 Java 对象映射到数据库表中...合理地选择和配置主键生成策略能够有效提升应用程序的性能和稳定性。

    Hibernate中主键生成策略

    在Java的持久化框架...理解并正确选择主键生成策略对于优化数据库性能、保证数据的唯一性和完整性以及适应不同的数据库环境都至关重要。在实际开发中,应根据项目需求和所使用的数据库类型来选择最合适的策略。

    hibernate复合主键配置和使用

    2. 复合主键的属性应尽可能选择不会更改的字段,以避免后续操作的复杂性。 3. 在使用复合主键时,要注意避免在多对一或一对多关系中直接使用复合主键作为外键,这可能导致映射问题。 总结,Hibernate对复合主键的...

    使用ODI处理没有主键的表全攻略

    【使用ODI处理没有主键...总结,处理没有主键的表需要根据实际情况选择合适的策略,通常结合业务逻辑和数据特性进行调整。在ODI中,虽然缺乏主键会带来挑战,但通过创新的处理方式,仍然可以实现高效、准确的数据集成。

    关于主键的添加、更换、删除的总结

    有时候可能需要更改表中的主键,比如最初选择的字段不够合适或者业务需求发生了变化。更换主键通常包括两个步骤:先删除旧的主键约束,再添加新的主键约束。 ##### 示例代码: ```sql -- 删除名为 PK_ 的主键约束 ...

Global site tag (gtag.js) - Google Analytics