常用 SQL Server 规范集锦

原文地址

常见的字段类型选择
  1.字符类型建议采用varchar/nvarchar数据类型
  2.金额货币建议采用money数据类型
  3.科学计数建议采用numeric数据类型
  4.自增长标识建议采用bigint数据类型 (数据量一大,用int类型就装不下,那以后改造就麻烦了)
  5.时间类型建议采用为datetime数据类型
  6.禁止使用text、ntext、image老的数据类型
  7.禁止使用xml数据类型、varchar(max)、nvarchar(max)
约束与索引
  每张表必须有主键
  1.每张表必须有主键,用于强制实体完整性
  2.单表只能有一个主键(不允许为空及重复数据)
  3.尽量使用单字段主键
  
  每张表必须有主键
  1.外键增加了表结构变更及数据迁移的复杂性
  2.外键对插入,更新的性能有影响,需要检查主外键约束
  3.数据完整性由程序控制
  
  每张表必须有主键
  1.新加的表,所有字段禁止NULL
  (新表示为什么不允许NULL?
  允许NULL值,会增加应用程序的复杂性。你必须得增加特定的逻辑代码,以防止出现各种意外的bug;
  三值逻辑,所有等号(“=”)的查询都必须增加isnull的判断;
  Null=Null、Null!=Null、not(Null=Null)、not(Null!=Null)都为unknown,不为true。)
  
  举例来说明一下:
这里写图片描述
  你想来找查找除了name等于aa的所有数据,然后你就不经意间用了SELECT * FROM NULLTEST WHERE NAME<>’aa’

  结果发现与预期不一样,事实上它只查出了name=bb而没有查找出name=NULL的数据记录

  那我们如何查找除了name等于aa的所有数据,只能用ISNULL函数了

  SELECT * FROM NULLTEST WHERE ISNULL(NAME,1)<>’aa’

  但是大家可能不知道ISNULL会引起很严重的性能瓶颈 ,所以很多时候最好是在应用层面限制用户的输入,确保用户输入有效的数据再进行查询。

  旧表新加字段,需要允许为NULL(避免全表数据更新 ,长期持锁导致阻塞)(这个主要是考虑之前表的改造问题)
  
  索引设计准则
  1.应该对 WHERE 子句中经常使用的列创建索引
  2.应该对经常用于连接表的列创建索引
  3.应该对 ORDER BY 子句中经常使用的列创建索引
  4.不应该对小型的表(仅使用几个页的表)创建索引,这是因为完全表扫描操作可能比使用索引执行的查询快
  5.单表索引数不超过6个
  6.不要给选择性低的字段建单列索引
  7.充分利用唯一约束
  8.索引包含的字段不超过5个(包括include列)
  
  不要给选择性低的字段创建单列索引
  1.SQL SERVER对索引字段的选择性有要求,如果选择性太低SQL SERVER会放弃使用
  2.不适合创建索引的字段:性别、0/1、TRUE/FALSE
  3.适合创建索引的字段:ORDERID、UID等
  
  充分利用唯一索引
  唯一索引给SQL Server提供了确保某一列绝对没有重复值的信息,当查询分析器通过唯一索引查找到一条记录则会立刻退出,不会继续查找索引。
  
  表索引数不超过6个(这个规则只是携程DBA经过试验之后制定的。。。)
  1.索引加快了查询速度,但是却会影响写入性能
  2.一个表的索引应该结合这个表相关的所有SQL综合创建,尽量合并
  3.组合索引的原则是,过滤性越好的字段越靠前
  4.索引过多不仅会增加编译时间,也会影响数据库选择最佳执行计划
  
  SQL查询
  1.禁止在数据库做复杂运算
  2.禁止使用SELECT *
  3.禁止在索引列上使用函数或计算
  4.禁止使用游标
  5.禁止使用触发器
  6.禁止在查询里指定索引
  7.变量/参数/关联字段类型必须与字段类型一致
  8.参数化查询
  9.限制JOIN个数
  10.限制SQL语句长度及IN子句个数
  11.尽量避免大事务操作
  12.关闭影响的行计数信息返回
  13.除非必要SELECT语句都必须加上NOLOCK
  14.使用UNION ALL替换UNION
  15.查询大量数据使用分页或TOP
  16.递归查询层级限制
  17.NOT EXISTS替代NOT IN
  18.临时表与表变量
  19.使用本地变量选择中庸执行计划
  20.尽量避免使用OR运算符
  21.增加事务异常处理机制
  22.输出列使用二段式命名格式
  
  禁止在数据库做复杂运算
  1.XML解析
  2.字符串相似性比较
  3.字符串搜索(Charindex)
  4.复杂运算在程序端完成
  
  禁止使用SELECT *
  1.减少内存消耗和网络带宽
  2.给查询优化器有机会从索引读取所需要的列
  3.表结构变化时容易引起查询出错
  
  禁止在索引列上使用函数或计算
  在where子句中,如果索引是函数的一部分,优化器将不再使用索引而使用全表扫描。
  假设在字段Col1上建有一个索引,则下列场景将无法使用到索引:
  ABS[Col1]=1
  [Col1]+1>9
  再举例说明一下:
  这里写图片描述
  像上面这样的查询,将无法用到O_OrderProcess表上的PrintTime索引,所以我们应用使用如下所示的查询SQL:
  这里写图片描述
  
  禁止在索引列上使用函数或计算
  假设在字段Col1上建有一个索引,则下列场景将可以使用到索引:
  [Col1]=3.14
  [Col1]>100
  [Col1] BETWEEN 0 AND 99
  [Col1] LIKE ‘abc%’
  [Col1] IN(2,3,5,7)
  
  LIKE查询的索引问题
  1.[Col1] like “abc%” –index seek 这个就用到了索引查询
  2.[Col1] like “%abc%” –index scan 而这个就并未用到索引查询
  3.[Col1] like “%abc” –index scan 这个也并未用到索引查询
  我想从上而三个例子中,大家应该明白,最好不要在LIKE条件前面用模糊匹配,否则就用不到索引查询。
  
  禁止使用游标
  关系数据库适合集合操作,也就是对由WHERE子句和选择列确定的结果集作集合操作,游标是提供的一个非集合操作的途径。一般情况下,游标实现的功能往往相当于客户端的一个循环实现的功能。

  游标是把结果集放在服务器内存,并通过循环一条一条处理记录,对数据库资源(特别是内存和锁资源)的消耗是非常大的。(再加上游标真心比较复杂,挺不好用的,尽量少用吧)。
  
  禁止使用触发器
  触发器对应用不透明(应用层面都不知道会什么时候触发触发器,发生也也不知道,感觉莫名……)。
  
  禁止在查询里指定索引
  With(index=XXX)( 在查询里我们指定索引一般都用With(index=XXX) )
  1.随着数据的变化查询语句指定的索引性能可能并不最佳
  2.索引对应用应是透明的,如指定的索引被删除将会导致查询报错,不利于排障
  3.新建的索引无法被应用立即使用,必须通过发布代码才能生效
  
  变量/参数/关联字段类型必须与字段类型一致(这是我之前不太关注的)
  避免类型转换额外消耗的CPU,引起的大表scan尤为严重.
  这里写图片描述
  这里写图片描述
  看了上面这两个图,我想我不用解释说明,大家都应该已经清楚了吧。

  如果数据库字段类型为VARCHAR,在应用里面最好类型指定为AnsiString并明确指定其长度

  如果数据库字段类型为CHAR,在应用里面最好类型指定为AnsiStringFixedLength并明确指定其长度

  如果数据库字段类型为NVARCHAR,在应用里面最好类型指定为String并明确指定其长度。
  
  参数化查询
  以下方式可以对查询SQL进行参数化:
  sp_executesql
  Prepared Queries
  Stored
  procedures

  用图来说明一下,哈哈。
  这里写图片描述
  这里写图片描述
  
  限制JOIN个数
  1.单个SQL语句的表JOIN个数不能超过5个
  2.过多的JOIN个数会导致查询分析器走错执行计划
  3.过多JOIN在编译执行计划时消耗很大
  
  限制IN子句中条件个数
  在 IN 子句中包括数量非常多的值(数以千计)可能会消耗资源并返回错误 8623 或 8632,要求IN子句中条件个数限制在100个以内。
  
  尽量避免大事务操作
  1.只在数据需要更新时开始事务,减少资源锁持有时间
  2.增加事务异常捕获预处理机制
  3.禁止使用数据库上的分布式事务
  用图来说明一下
  这里写图片描述
  这里写图片描述
  也就是说我们不应该在1000行数据都更新完成之后再commit tran,你想想你在更新这一千行数据的时候是不是独占资源导致其它事务无法处理。
  
  关闭影响的行计数信息返回
  在SQL语句中显示设置Set Nocount On,取消影响的行计数信息返回,减少网络流量
  除非必要SELECT语句都必须加上NOLOCK
  
  关闭影响的行计数信息返回
  指定允许脏读。不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设 置的排他锁不会阻碍当前事务读取锁定数据。允许脏读可能产生较多的并发操作,但其代价是读取以后会被其他事务回滚的数据修改。这可能会使您的事务出错,向用户显示从未提交过的数据,或者导致用户两次看到记录(或根本看不到记录)。
  
  使用UNION ALL替换UNION
  UNION会对SQL结果集去重排序,增加CPU、内存等消耗。
  
  查询大量数据使用分页或TOP
  合理限制记录返回数,避免IO、网络带宽出现瓶颈
  
  递归查询层次限制
  使用 MAXRECURSION 来防止不合理的递归 CTE 进入无限循环
  
  临时表与表变量
  这里写图片描述
  
  使用本地变量选择中庸执行计划
  在存储过程或查询中,访问了一张数据分布很不平均的表格,这样往往会让存储过程或查询使用了次优甚至于较差的执行计划上,造成High CPU及大量IO Read等问题,使用本地变量防止走错执行计划。

  采用本地变量的方式,SQL在编译的时候是不知道这个本地变量的值,这时候SQL会根据表格里数据的一般分布,“猜测”一个返回值。不管用户在调用存储过程或语句的时候代入的变量值是多少,生成的计划都是一样的。这样的计划一般会比较中庸一些,不一定是最优的计划,但一般也不会是最差的计划

  如果查询中本地变量使用了不等式运算符,查询分析器使用了一个简单的 30% 的算式来预估
  Estimated Rows =(Total Rows * 30)/100

  如果查询中本地变量使用了等式运算符,则查询分析器使用:精确度 * 表记录总数来预估
  Estimated Rows = Density * Total Rows
  
  尽量避免使用OR运算符
  对于OR运算符,通常会使用全表扫描,考虑分解成多个查询用UNION/UNION ALL来实现,这里要确认查询能走到索引并返回较少的结果集
  
  增加事务异常处理机制
  应用程序做好意外处理,及时做Rollback。
  设置连接属性 “set xact_abort on”
  
  输出列使用二段式命名格式
  二段式命名格式:表名.字段名

  有JOIN关系的TSQL,字段必须指明字段是属于哪个表的,否则未来表结构变更后,有可能发生Ambiguous column name的程序兼容错误

  架构设计
  1.读写分离
  2.schema解耦
  3.数据生命周期
  
  读写分离
  1.设计之初就考虑读写分离,哪怕读写同一个库,有利于快速扩容
  2.按照读特征把读分为实时读和可延迟读分别对应到写库和读库
  3.读写分离应该考虑在读不可用情况下自动切换到写端
  
  Schema解耦
  禁止跨库JOIN
  
  数据生命周期
  根据数据的使用频繁度,对大表定期分库归档
  主库/归档库物理分离
  
  日志类型的表应分区或分表
  对于大的表格要进行分区,分区操作将表和索引分在多个分区,通过分区切换能够快速实现新旧分区替换,加快数据清理速度,大幅减少IO资源消耗
  
  频繁写入的表,需要分区或分表
  自增长与Latch Lock

  闩锁是sql Server自己内部申请和控制,用户没有办法来干预,用来保证内存里面数据结构的一致性,锁级别是页级锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548640.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux服务器搭建----Web服务器(apache)

WWW的介绍 万维网&#xff08;亦作“Web”、“WWW”、“W3”&#xff0c;英文全称为“World Wide Web”&#xff09;&#xff0c;是一个由许多互相链接的超文本组成的系统&#xff0c;通过互联网访问。在这个系统中&#xff0c;每个有用的事物&#xff0c;称为一样“资源”&…

F5 配置手册 -F5 BIG-IP 10.1-1-激活

F5 配置手册 F5 BIG-IP 10.1-1-激活 统一沟通(中国)有限公司 2012-01-29 前言&#xff1a; F5---太贵! 不过你如果有命运看到这个文章,F5也就不值钱了。 因为:F5提供测试版的虚拟机,我们买不起,总应该玩得起吧! 但愿F5提供更多的机会,给别人机会,也是给自己机会。 参照: 你也可…

Beginning iCloud in iOS 5 Tutorial Part 2(转载)

原文地址&#xff1a;http://www.raywenderlich.com/6031/beginning-icloud-in-ios-5-tutorial-part-2 Setting Up the User Interface The Xcode project template we chose already set up an empty view controller for us. We will extend it by adding the current docume…

JQuery Datatables 服务端分页简单应用学习

背景介绍 最近在一个简单小项目中碰到需要一个前端数据表格控件&#xff0c;在看了网上的资料后最终选择了JQuery Datatables。Datatables功能及其强大&#xff0c;基本满足我的所有需求&#xff0c;在加上其插件Editor具有inline模式&#xff0c;很多需要直接修改数据的功能不…

Java API 设计清单

为什么80%的码农都做不了架构师&#xff1f;>>> 在设计Java API的时候总是有很多不同的规范和考量。与任何复杂的事物一样&#xff0c;这项工作往往就是在考验我们思考的缜密程度。就像飞行员起飞前的检查清单&#xff0c;这张清单将帮助软件设计者在设计Java API的…

利用FSMT进行文件服务器迁移及整合

当企业文件服务器&#xff08;DFS、共享文件夹等&#xff09;面临硬件更新、系统升级或文件服务器合并的情况时&#xff0c;往往会出现不确定的文件丢失、需要重新设置所有权限、无法将多个文件服务器集成到一台服务器上等问题&#xff0c;为了保证文件服务器的数据完整以及权限…

RHEL 6上KVM的安装配置及使用-将物理接口桥接到桥接器

作业环境服务器端操作系统&#xff1a;Red Hat Enterprise Linux Server release 6.0 (Santiago)KVM&#xff1a;qemu-kvm-0.12.1.2-2.113.el6.x86_64 客户端操作系统&#xff1a;Windows 7KVM管理工具&#xff1a;Xming 6.9 一、安装KVM及相关软件 1、KVM 需要有 CPU 的支持&a…

C#中IEnumerableT.Distinct()将指定实体类对象用Lambda表达式实现多条件去重

背景说明 在EF等ORM框架中需要以List实体类的方式对数据进行大量操作&#xff0c;其中免不了对一些数据进行去重复&#xff0c;而C#中IEnumerable.Distinct()便提供了这一功能。只是对刚开始接触的新人来说比价抽象难以接受&#xff0c;本文会对这一功能进行简要说明&#xff…

C#中利用Linq.Dynamic实现简单的动态表达式构建查询

背景介绍 在ADO.NET中我们可以根据用户输入的查询条件拼接出指定的SQL语句进行查询或者筛选出所需的数据&#xff0c;但是在ORM框架如EF中&#xff0c;我们一般用LINQ操作数据查询&#xff0c;LINQ是否可以像SQL一样拼接查询条件呢&#xff1f;答案是可以的。这一技术叫Linq.D…

C#中IEnumerableT.GroupBy()的简单使用

背景介绍 在实际项目中&#xff0c;对数据进行GroupBy肯定是常用需求之一&#xff0c;特别是采用EF等ORM框架后隔绝了用SQL语句直接操作数据&#xff0c;LINQ中的GroupBy肯定是要掌握的。 首先先对一个字段GroupBy&#xff0c;代码如下&#xff1a; static void Main(string[…

25 个精美的后台管理界面模板和布局

任何系统都会有一个管理后台&#xff0c;好看的管理后台看起来赏心悦目&#xff0c;管理的时候心情也舒畅&#xff0c;本文给大家推荐 25 个制作精美的后台管理界面的模板和布局&#xff0c;你值得拥有。 Free Admin Template Web App Theme Spring Time Free Admin Template F…

C#中IEnumerableT.Aggregate()的简单使用

背景介绍 IEnumerable<T>.Aggregate()在LINQ使用中好像很不起眼&#xff0c;但我个人认为这是十分实用并且强大的&#xff0c;支持自定义聚合操作&#xff0c;方法定义中的Func包含3个TSource参数&#xff0c;分别为下一个执行聚合的元素&#xff0c;当前聚合的元素&…

C#中IEnumerable.OfType()方法的简单使用

背景介绍 OfType的定义十分简单&#xff1a;IEnumerable.OfType(TResult)&#xff0c;如其定义&#xff0c;其中TRsult为所要过滤的类型。由于非泛型集合一律以Object类型存储对象&#xff0c;因此一个非泛型集合可能存储了各种类型&#xff0c;而OfType()方法可以轻松的对指定…

C#中IEnumerableT.Join()和IEnumerableT.GroupJoin()简单使用

背景介绍: 在无主外键关系的表中如果如果要关联就要用Join()和GroupJoin()方法了&#xff0c;我们先看Join()方法&#xff0c;代码如下&#xff1a; static void Main(string[] args) {List<SW_XSDD> sw_xsdd new List<SW_XSDD>(){new SW_XSDD { com_id "…

利用ASP.NET MVC 的默认类型绑定器---将Jquery datatables中的数据强类型绑定到实体类中

背景描述&#xff1a; 本文参考资料&#xff1a;https://blog.csdn.net/honantic/article/details/45913403 阅读了上述博文后对我产生了启发&#xff0c;在ASP.NET MVC 5中如何将大批量的数据比如说表格中的数据传到后台&#xff0c;是否可以像HTML辅助类一样强类型绑定实体…

JavaScript模态对话框类(拖拽时动画)

2010年写了一个模态对话框类&#xff0c;这次进行一些重构和扩充。拖拽时使其有动画效果。接口没变&#xff0c;如下 new ModelDialog({caption 标题 对话框标题(默认)template 主体内容 (默认)dialogCls 对话框className md-dialog(默认)headCls 头部classNa…

C#中其他简单LINQ查询表达式的简单使用介绍

本文主要记录下其他简单LINQ表达式&#xff0c;因为比较简单&#xff0c;记录下以后方便回忆&#xff0c;本文也会持续更新。 一些有用的LINQ扩展方法&#xff1a; LINQ表达式作用是否延迟查询Range生成指定范围内的整数的序列 Repeat生成包含一个重复值的序列 Skip跳过指定数…

支持上传文件的xhEditor for Typecho EX插件

2019独角兽企业重金招聘Python工程师标准>>> Typecho是一套超轻量的开源博客&#xff0c;界面简洁&#xff0c;功能紧凑&#xff0c;但是Typecho的文本编辑器实在是不好&#xff0c;需要自己写html代码&#xff0c;插图也不方便。试用了几个插件&#xff0c;发现Tin…

C#中IEnumerableT.Select()、SelectMany()的简单使用

本文主要用来记录、让自己有所了解和提升&#xff0c;以后遗忘时可以查看&#xff0c;关于SelectMany()&#xff0c;这篇文章写得不错&#xff0c;值得一看。 话不多说&#xff0c;先上代码看 Select() public class Person {public string Name { get; set; }public string G…