位置: 编程技术 - 正文

小议sqlserver数据库主键选取策略(sql server数据库使用)

编辑:rootadmin
因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。当然,其它字段可以辅助我们在执行这些操作时消除共享冲突,不过就不在这里讨论了。主键除了上述作用外,常常与外键构成参照完整性约束,防止出现数据不一致。所以数据库在设计时,主键起到了很重要的作用。 常见的数据库主键选取方式有: 自动增长字段 手动增长字段 UniqueIdentifier “COMB(Combine)”类型 一、自动增长型字段 很多数据库设计者喜欢使用自动增长型字段,因为它使用简单。自动增长型字段允许我们在向数据库添加数据时,不考虑主键的取值,记录插入后,数据库系统会自动为其分配一个值,确保绝对不会出现重复。如果使用SQL Server数据库的话,我们还可以在记录插入后使用@@IDENTITY全局变量获取系统分配的主键键值。 尽管自动增长型字段会省掉我们很多繁琐的工作,但使用它也存在潜在的问题,那就是在数据缓冲模式下,很难预先填写主键与外键的值。假设有两张表: Order(OrderID, OrderDate) OrderDetial(OrderID, LineNum, ProductID, Price) Order表中的OrderID是自动增长型的字段。现在需要我们录入一张订单,包括在Order表中插入一条记录以及在OrderDetail表中插入若干条记录。因为Order表中的OrderID是自动增长型的字段,那么我们在记录正式插入到数据库之前无法事先得知它的取值,只有在更新后才能知道数据库为它分配的是什么值。这会造成以下矛盾发生: 首先,为了能在OrderDetail的OrderID字段中添入正确的值,必须先更新Order表以获取到系统为其分配的OrderID值,然后再用这个OrderID填充OrderDetail表。最后更新OderDetail表。但是,为了确保数据的一致性,Order与 OrderDetail在更新时必须在事务保护下同时进行,即确保两表同时更行成功。显然它们是相互矛盾的。(此处表述有错误。吕震宇 -6-) 【补充-6-】--------------------------------------------- 听棠.NET指出:主档放在事务中提交时,通过@@IDENTITY 就可以取到生成值的,因此可以传给明细当外键用,而且在事务发生错误回滚时,主档记录也会被回滚取消的。 吕震宇补充:使用自动增长字段会增加网络的roundTrip。尽管可以使用@@IDENTITY取得主键的值,但在更新过程中,不得不增加一次数据往返(以C/S结构为例): 1、客户端发送开始事务命令 2、客户端提交主表更新 3、服务器返回@@IDENTITY 4、客户端根据返回的主键更新从表缓冲 5、客户端将从表提交服务器更新 6、客户端提交事务 在这里多了一次往返就会增加了事务处理的时间。降低并发性能。 如果不用自动增长型字段,将是以下情景: 1、客户端发送开始事务命令 2、客户端提交主表更新 3、客户端提交从表更新 4、客户端提交事务 因此我不赞成使用自动增长型字段作为主键与外键链接的纽带。 ------------------------------------------------ 除此之外,当我们需要在多个数据库间进行数据的复制时(SQL Server的数据分发、订阅机制允许我们进行库间的数据复制操作),自动增长型字段可能造成数据合并时的主键冲突。设想一个数据库中的Order表向另一个库中的Order表复制数据库时,OrderID到底该不该自动增长呢? ADO.NET允许我们在DataSet中将某一个字段设置为自动增长型字段,但千万记住,这个自动增长字段仅仅是个占位符而已,当数据库进行更新时,数据库生成的值会自动取代ADO.NET分配的值。所以为了防止用户产生误解,建议大家将ADO.NET中的自动增长初始值以及增量都设置成-1。此外,在ADO.NET中,我们可以为两张表建立DataRelation,这样存在级联关系的两张表更新时,一张表更新后另外一张表对应键的值也会自动发生变化,这会大大减少了我们对存在级联关系的两表间更新时自动增长型字段带来的麻烦。 二、手动增长型字段 既然自动增长型字段会带来如此的麻烦,我们不妨考虑使用手动增长型的字段,也就是说主键的值需要自己维护,通常情况下需要建立一张单独的表存储当前主键键值。还用上面的例子来说,这次我们新建一张表叫IntKey,包含两个字段,KeyName以及KeyValue。就像一个HashTable,给一个KeyName,就可以知道目前的KeyValue是什么,然后手工实现键值数据递增。在SQL Server中可以编写这样一个存储过程,让取键值的过程自动进行。代码如下: 这样,通过调用存储过程,我们可以获得最新键值,确保不会出现重复。若将OrderID字段设置为手动增长型字段,我们的程序可以由以下几步来实现:首先调用存储过程,获得一个OrderID,然后使用这个OrderID填充Order表与OrderDetail表,最后在事务保护下对两表进行更新。 使用手动增长型字段作为主键在进行数据库间数据复制时,可以确保数据合并过程中不会出现键值冲突,只要我们为不同的数据库分配不同的主键取值段就行了。但是,使用手动增长型字段会增加网络的RoundTrip,我们必须通过增加一次数据库访问来获取当前主键键值,这会增加网络和数据库的负载,当处于一个低速或断开的网络环境中时,这种做法会有很大的弊端。同时,手工维护主键还要考虑并发冲突等种种因素,这更会增加系统的复杂程度。 三、使用UniqueIdentifier SQL Server为我们提供了UniqueIdentifier数据类型,并提供了一个生成函数NEWID( ),使用NEWID( )可以生成一个唯一的UniqueIdentifier。UniqueIdentifier在数据库中占用个字节,出现重复的概率非常小,以至于可以认为是0。我们经常从注册表中看到类似 {F0EB--4F2E-AAB5-E8AEDEE0CEC5} 的东西实际上就是一个UniqueIdentifier,Windows用它来做COM组件以及接口的标识,防止出现重复。在.NET里管 UniqueIdentifier称之为GUID(Global Unique Identifier)。在C#中可以使用如下命令生成一个GUID: Guid u = System.Guid.NewGuid(); 对于上面提到的Order与OrderDetail的程序,如果选用UniqueIdentifier作为主键的话,我们完全可以避免上面提到的增加网络RoundTrip的问题。通过程序直接生成GUID填充主键,不用考虑是否会出现重复。 UniqueIdentifier字段也存在严重的缺陷:首先,它的长度是字节,是整数的4倍长,会占用大量存储空间。更为严重的是,UniqueIdentifier的生成毫无规律可言,要想在上面建立索引(绝大多数数据库在主键上都有索引)是一个非常耗时的操作。有人做过实验,插入同样的数据量,使用UniqueIdentifier型数据做主键要比使用Integer型数据慢,所以,出于效率考虑,尽可能避免使用 UniqueIdentifier型数据库作为主键键值。 四、使用“COMB(Combine)”类型 既然上面三种主键类型选取策略都存在各自的缺点,那么到底有没有好的办法加以解决呢?答案是肯定的。通过使用COMB类型(数据库中没有COMB类型,它是Jimmy Nilsson在他的“The Cost of GUIDs as Primary Keys”一文中设计出来的),可以在三者之间找到一个很好的平衡点。 COMB数据类型的基本设计思路是这样的:既然UniqueIdentifier数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么我们能不能通过组合的方式,保留UniqueIdentifier的前个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与UniqueIdentifier组合起来,在保留UniqueIdentifier的唯一性的同时增加了有序性,以此来提高索引效率。也许有人会担心UniqueIdentifier减少到字节会造成数据出现重复,其实不用担心,后6字节的时间精度可以达到1/秒,两个COMB类型数据完全相同的可能性是在这1/秒内生成的两个GUID前个字节完全相同,这几乎是不可能的!在SQL Server中用SQL命令将这一思路实现出来便是: 经过测试,使用COMB做主键比使用INT做主键,在检索、插入、更新、删除等操作上仍然显慢,但比Unidentifier类型要快上一些。关于测试数据可以参考我年7月日的随笔。 除了使用存储过程实现COMB数据外,我们也可以使用C#生成COMB数据,这样所有主键生成工作可以在客户端完成。C#代码如下: 结语 数据库主键在数据库中占有重要地位。主键的选取策略决定了系统是否高效、易用。本文比较了四种主键选取策略的优缺点,并提供了相应的代码解决方案,希望对大家有所帮助。

推荐整理分享小议sqlserver数据库主键选取策略(sql server数据库使用),希望有所帮助,仅作参考,欢迎阅读内容。

小议sqlserver数据库主键选取策略(sql server数据库使用)

文章相关热门搜索词:sql server 数据库介绍,sql server数据,sql server数据,sqlserverce,sqlserver数据库,sqlserver数据库,sqlserver数据库,sqlserver,内容如对您有帮助,希望把文章链接给更多的朋友!

sqlserver自动增长列引起的问题解决方法 有两个结构完全相同的表,由其中一个表插入另一个表中指定条件的数据,报如下错误:仅当使用了列列表并且IDENTITY_INSERT为ON时,才能为表'*'中的标识

sqlserver 存储过程动态参数调用实现代码 只是做笔记,没什么!!--创建测试表CREATETABLE[dbo].[Student]([ID][int]IDENTITY(1,1)NOTNULLPRIMARYKEY,[Name][nvarchar]()NOTNULLDEFAULT(''),[Age][int]NOTNULLDEFAULT(0),[Sex][bit]NOTNUL

通过分析SQL语句的执行计划优化SQL 如何干预执行计划--使用hints提示基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明

标签: sql server数据库使用

本文链接地址:https://www.jiuchutong.com/biancheng/348865.html 转载请保留说明!

上一篇:SQL语句 一个简单的字符串分割函数(如果一个sql语句中包括两个名字)

下一篇:sqlserver自动增长列引起的问题解决方法(sql自动增长是什么意思)

  • 运输发票税率6%和3%区别在哪
  • 2023年印花税如何计算
  • 增值税进项税额加计抵减政策
  • 附加税税负
  • 公司研发人员定义
  • 企业给员工的福利取消了可以劳动仲裁么
  • 会计继续教育还需要学吗
  • 制造业的税率是多少啊
  • 最新企业准则
  • 一般纳税人购入商品取得普通发票
  • 陈列费税率多少
  • 融资发票是什么
  • 年终红包怎么入账
  • 资产负债表货币资金与现金流量表的关系
  • 土地租金一次付清的会计处理怎么做?
  • 缴纳残疾人就业保险金会计分录
  • 安全生产费纳税调整政策
  • 外贸 内销
  • 广告发布税收编码
  • 去税务局税种认定需要带什么资料
  • 纳税人必须熟知什么
  • 预缴企业所得税研发费用加计扣除
  • 长期股权投资账面价值和公允价值不一致
  • 电话充值卡如何变现
  • 装修费用如何做分录
  • 物流服务费税率是多少
  • 公司对外租赁
  • 收到个人款开公司发票
  • 公司开业厂商的宣传文案
  • 当前页面的脚本发生错误代码0没有注册类
  • php 字符串 数组
  • 劳务派遣增值税差额征税
  • 收入和支出怎么合计
  • 无形资产本月增加本月摊销如何设置函数
  • 同步和异步的关系
  • yii框架手册
  • 漏记收入 罚款
  • 人工智能机器人保姆什么时候实现
  • 个体户发票没有开户行和账号行吗
  • 营业外支出贷方在利润表怎么体现
  • 残保金工资总额包括什么
  • js执行上下文的概念
  • mysql有几种基本数据类型
  • 应收票据贴现的影响因素
  • 软件企业该怎么发展起来
  • 不征税收入怎么做会计分录
  • 公司代房东缴纳个税怎么处理
  • 资本公积怎么计提
  • 去年企业所得税多计提怎么调整
  • 机动车发票红冲多了税盘被锁
  • 转账给个人账户
  • 记错科目怎么调整
  • 办公室购买电脑属于什么费用
  • 应交税费减免税额在借方还是贷方
  • 本期缴纳上期应纳税额怎么填
  • 带折扣的发票如何开具
  • 一次性收入怎么计税
  • 破产重组还需要还钱吗
  • 关联方交易舞弊手段
  • mysql kill -9
  • Mysql使用or如何优化
  • 一个绝招 组合的成语
  • win8 photoshop
  • win2003系统安装
  • 微软官方操作系统叫什么
  • mac所有窗口最小化
  • Skype.exe - Skype是什么进程 有什么用
  • koeidsnd.dll
  • linux常用命令useradd
  • 解决安装后软件icon一圈白边问题
  • es6新增的数据结构
  • nodejs实战教程
  • opengl glbegin
  • 衬线字体和无衬线字体各自的用途
  • nodejs基础教程
  • JavaScipt中Function()函数的使用教程
  • 小规模纳税人租金收入增值税税率
  • 浙江国地税申报网
  • 广西自然人税收管理系统扣缴客户端手机版
  • 南昌契税政策
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设