位置: 编程技术 - 正文

小议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自动增长是什么意思)

  • 个人应纳税所得额20万交多少税
  • 去年少交增值税的会计处理
  • 所得税汇算清缴时间期限
  • 残保金滞纳金可以税前扣除吗
  • 电子发票错误怎么重开
  • 固定资产后续支出可以计入哪些费用
  • 小规模销售免税农产品的分录
  • 嵌入式软件运行的主要流程是什么
  • 带薪缺勤会计处理
  • 农产品增值税进项税额核定扣除办法
  • 委外研发费用如何开票
  • 检测样品留样期限
  • 外地办事处能交当地社保吗
  • 管理费用月末怎么结账
  • 员工离职后收取客户钱款
  • 三证合一后企业还有什么证照
  • 土地成本费用包括什么
  • 单位缴交的社保和医保还要交其他费用吗
  • 节能控制模块
  • 加速折旧法主要包括哪些内容
  • 记账错误是什么意思
  • 外币汇兑差额债券投资计入什么科目?
  • 无偿捐赠增值税计算公式
  • 权益法初始入账价值和初始投资成本
  • 上年发生的费用,下年来得发票,会计分录
  • linux桌面设置界面在哪
  • 销售不动产分期收款怎么确认收入
  • 王者营地怎么转移到安卓系统
  • acer笔记本如何关闭键盘数字键
  • 显示器有必要买240hz吗
  • 蒙大拿州美景
  • echarts.
  • 纺织企业成本核算方案
  • php字符串定义
  • ts中如何定义一个数组
  • open开放的意思吗
  • last命令详解
  • 可供出售权益工具减值
  • 机械租赁税率是多少?
  • 外购商品转为自用固定资产,进项税
  • 帝国cms适合个人用吗
  • 公司的融资租赁有哪些
  • 代缴职工社保是啥意思
  • 资产负债表应收账款期末余额公式
  • 跨年发票账务处理怎么做
  • 销售旧固定资产开票编码
  • 购货方发生退货的会计分录
  • 租出的固定资产
  • 车辆按揭贷款需要什么
  • 支付货款订金入什么科目
  • 无形资产及其他资产包括哪些科目
  • 不得从销项税额中抵扣进项税的有哪些
  • 政府补贴递延收益的摊销时间
  • 销户还能申请抚养费吗?
  • 没有发票财务报表怎么做
  • 国税定额发票有什么用
  • 投资款计入哪个科目
  • linux的日志文件
  • 修改window
  • 设置自动清理缓存电脑
  • Ubuntu中Virtualbox虚拟机NAT方式无法上网解决方法
  • windows任务栏变色
  • xp系统插u盘没反应怎么解决
  • windows10已激活
  • win7为什么会出现小黄锁
  • 深入解析java编译器源码剖析与实例详解pdf百度云
  • linux使用ssh远程连接服务器
  • shell编程简单实例
  • react.development.js
  • Unity3d-四元数到矩阵的实现
  • python 中的列表
  • 开票软件连接服务器失败什么原因
  • 上海地方税务局发票查询
  • 江苏省常州市国事业单位国企招录测绘工程研究生公告
  • 电子税务局房产税原值怎么改
  • 广东省地方税务局电子办税服务厅
  • 南京税务局几点下班?
  • 契税为什么要补贴
  • 个人所得税税收完税证明哪里打印
  • 新四板企业哪里可以查询
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设