位置: 编程技术 - 正文

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

  • 一次性医用外科口罩哪个牌子好
  • 弥补亏损用税前还是税前
  • 附加税税率是多还是少
  • 增值税附加税税率是多少
  • 买原材料怎么记账
  • 以摊余成本计量的金融资产交易费用
  • 支付短期借款利息的会计科目
  • 业务活动表本月数和本年累计数
  • 资产负债表所有者权益和利润表关系
  • 分公司的所得税怎么申报
  • 残疾人就业保障金申报时间
  • 小企业周转材料包括什么
  • 自行建造固定资产中的自营工程,在领用工程物资
  • 政府补贴中介合法吗
  • 购房补贴退契税3个月没到账
  • 在建工程账务处理流程
  • 如何确认增值税纳税义务发生时间
  • 进项转出滞纳金规定
  • 工程服务税收的分类
  • 未达起征点企业怎么处理
  • 增值税发票查验平台显示查无此票
  • 三联专用发票每一联分别给谁
  • 税务要求企业所得税预缴申报更正
  • 企业的其他业务收入有
  • 贷款本金余额具体是什么意思
  • 2021年购买车辆的进项税能抵扣吗
  • 公户转给股东的钱需要交个税吗
  • 个税所得期和所得税区别
  • 汇算清缴费用调增会计处理
  • 家具厂打磨工工作图片
  • 商贸企业零部件出口退税政策
  • 给客户买的礼品怎么报销
  • php实现的一致性是什么
  • linux检测
  • mcappins.exe - mcappins进程是什么文件 什么意思.
  • 月末结转本年利润怎么算
  • php模板引擎语法
  • 双重差分法(DID)
  • densenet网络结构详解
  • js栈堆的区别
  • 长期待摊费用属于非流动资产吗
  • 史上伟大电影
  • 关税对企业有什么影响
  • 进口增值税抵扣期限
  • 总公司中标后走账怎么办
  • 劳务派遣申报表附表一怎么填
  • access宏操作
  • 金蝶标准版怎么查应收应付款
  • 综合所得年度自行申报怎么操作
  • 个人劳务费免税额度 年度
  • 固定资产盘盈属于其他业务收入吗
  • 期末结转主营业务成本
  • 原材料用于在建工程要进项转出吗
  • 网上购物没有发票
  • 电影赠票怎么用
  • 等额本金还款计算公式
  • 企业项目贷款所需资料
  • sqlserver代理服务启动失败
  • win8怎么让我的电脑显示在桌面上
  • 服务器远程超出配置范围
  • ubuntu启动菜单 哪个键
  • 更新profile
  • win10系统资源
  • centos划分分区
  • 将windows的文件上传到ubuntu
  • win10周年更新版是什么意思
  • cad2007字体怎么调大小
  • linux使用rpm安装软件
  • windows8语言栏不见了
  • 新买的笔记本电脑需要做什么
  • linux系统如何安装软件包
  • perl里怎么对数组实现一次遍历
  • unity 加载界面
  • 简单的jquery插件实例
  • html键盘监听
  • python错误和异常处理
  • 如何查询自己电子邮件地址
  • a类棉b类棉c类的区别
  • 税控系统减免税报表里
  • 地税管理员是干什么的
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设