indentity的取舍

首先阐述我的观点,任何技术都是为应用服务,没有最好的技术只有适当场景下最恰当的技术。但我还是更倾向于在大部分场景下使用业务主键取代indentity主键的形式。

首先列出indentity的概念:
identity是数据列的一种属性,具有这种属性的列,其值将由系统来控制,采用一种自动增长的机制给其赋值。在一个具有这种列的表中,其值肯定是唯一的,所以该列多用来做主键。而主键是一个表的唯一标识,它可以是某一个列,也可以有多个列组合而成,但主键列可不一定是具有identity属性的。

然后列出使用indentity的优缺点


缺点:

1.indentity字段的值无法修改,在导入时必须开启indentity_insert,强制导入indentity字段值,否则个表关系无法保障

2.因为indentity字段的值是数据插入后由数据库自动生成的,在事务处理时可能出现需要indentity字段但无法得到的问题。比如基本表-明细表模式中,基本表Order主键为indentity的order_id,明细表主键为product_id和order_id,假设一个用户故事为:追加一个订单及订单中的产品,如过设计师将此用户故事设计在同一事务中,则会出现无法得到order_id的问题。这种情况只能将用户故事拆分,作为两个功能点进行设计:新增订单和新增订单产品

3.当系统由多个数据库组成(总公司-分公司形式),进行数据合并时会出现问题,但可以通过设计对其进行回避,对于合并复制问题,MS给出3种方案: 

    1.Automatic   Identity   Range   Handling。 

    2.Manual   Identity   Range   Handling。即NOT   FOR   REPLICATION 

    3.Using   Other   Columns   as   Primary   Keys。

4.单纯自增数字,不能准确表达业务概念

5.因为是自增数字,在删除操作后会出现断数现象,但此现象如不考虑业务,对系统影响不大

6.这种情况可能比较极端了,向不同厂商的数据库迁移时可能会出现问题


优点:
1.indentity字段由数据库控制,从某一方面减轻了编程难度(另一方面也会对编程造成影响,见缺点2)

可能对indentity控的读者会反驳一些性能问题,其实indentity或者说主键本身都和性能没多大关系,都是逻辑概念,但在SQL Server中主键和索引又牵扯上了关系,默认情况下主键作为 聚集索引存在,所以性能问题出现了。
让我们从几个典型的问题入手来好好辨一辨吧:

  1. 假设一张表上已经存在一个唯一性的聚集索引,是否还有必要在该表上创建一个主键约束呢?

  2. 如果需要主键约束,是否要先删除之前创建过的唯一性聚集索引,再新建主键约束呢?

  3. 针对相同的字段,通过主键约束自动生成的唯一性聚集索引的性能会比手工直接创建的唯一性聚集索引更好吗?


答案如下:


  1. 这个问题的答案已经是老生常谈了:尽管为表建主键可以称为一种最佳实践,但是如果你并不关心主键所带来的好处的话,建议还是不要盲目地创建。主键的好处或者说作用究竟是什么呢?首先,需要明确一点,主键是一种约束,而约束实际上是一种逻辑的概念。主键的存在一般起到如下两个作用:

  (a) 实体完整性。换句话说,要保证表内数据的唯一性,避免重复。

  (b) 引用完整性。典型地是应用于“主键—外键”对上。

  既然主键是一种逻辑的概念,它本身是不会造成任何性能上的影响的。但是我们为何不能盲目创建呢?这是因为在SQL Server中,新增主键的操作会伴随一个唯一性索引的生成(默认情况下是聚集索引)来保证实体完整性。因此,新增主键可以说会间接地影响性能,这是由索引造成的。回到这个问题上,从性能的角度考虑,如果表上当前存在的唯一性聚集索引已经是较优的选择(满足了重要查询的需求),就没有必要再通过新建主键来替换它,性能不会因为多了一个主键的约束而有所提升。

  2. 这个问题在上一个当中已经有所涉及。这里有一个重要的知识点:同一张表上最多只能有一个聚集索引。因此,我们有两种选择:

  (a) 保留原来的聚集索引,新建一个带有非聚集索引的主键(需要显式指定NONCLUSTERED)。

  (b) 删除原来的聚集索引,然后再新建一个带有聚集索引的主键(默认即可)。

  3. 从性能的角度考虑,回答是否定的。所以在动手以前,应该仔细斟酌好主键所带的索引究竟需要聚集的还是非聚集的,因为聚集索引是十分宝贵的,需要做好充分地评估。如果任由主键默认聚集索引的话,可能并不一定是聚集索引的最佳选择,今后可能还需要重新调整聚集索引和非聚集索引的选择。

  总而言之,主键是一个逻辑上的概念,主要提供数据在实体完整性和引用完整性上的保障。性能因素是由主键自带的索引造成的,谨记在创建主键时要想好主键字段究竟选择聚集的还是非聚集的,如果不关心主键所带来的好处的话,还是选择不加为好。希望本文能够帮助你更好地理解主键存在的意义及其间接存在的性能问题。

如果不想舍弃indentity主键或者在优化已存在indentity主键的数据库设计,则可以考虑业务主键做为聚集索引,identity做非聚集索引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值