SQL Server2012 复习

数据库 专栏收录该内容
14 篇文章 0 订阅

企业级的商务网站使用

数据库组成

数据文件 日志文件

系统数据库

master model msdb tempdb

数据类型

CHARACTER(n) 字符/字符串。固定长度 n。
VARCHAR(n) 或CHARACTER VARYING(n) 字符/字符串。可变长度。最大长度 n。
BINARY(n) 二进制串。固定长度 n。
BOOLEAN 存储 TRUE 或 FALSE 值
VARBINARY(n) 或BINARY VARYING(n) 二进制串。可变长度。最大长度 n。
INTEGER§ 整数值(没有小数点)。精度 p。
SMALLINT 整数值(没有小数点)。精度 5。
INTEGER 整数值(没有小数点)。精度 10。
BIGINT 整数值(没有小数点)。精度 19。
DECIMAL(p,s) 精确数值,精度 p,小数点后位数 s。例如:decimal(5,2) 是一个小数点前有 3 位数,小数点后有 2 位数的数字。
NUMERIC(p,s) 精确数值,精度 p,小数点后位数 s。(与 DECIMAL 相同)
FLOAT§ 近似数值,尾数精度 p。一个采用以 10 为基数的指数计数法的浮点数。该类型的 size 参数由一个指定最小精度的单一数字组成。
REAL 近似数值,尾数精度 7。
FLOAT 近似数值,尾数精度 16。
DOUBLE PRECISION 近似数值,尾数精度 16。
DATE 存储年、月、日的值。
TIME 存储小时、分、秒的值。
TIMESTAMP 存储年、月、日、小时、分、秒的值。
INTERVAL 由一些整数字段组成,代表一段时间,取决于区间的类型。
ARRAY 元素的固定长度的有序集合
MULTISET 元素的可变长度的无序集合
XML 存储 XML 数据

Transact-SQL(重要)

1.Transact-SQL概述

与 Oracle 的 PL/SQL 性质相近,核心的查询语言

2 如何给标识符起名

分为常规标识符,分隔标识符

  1. 标识符首字符必须是a-z,A-Z,_,@,#
    以“@”符号开始的标识符表示局部变量或参数;
    以一个数字符号“#”开始的标识符表示临时表或过程;
    以双数字符号“##”开始的标识符表示全局临时对象;
  2. 标识符不能是Transact-SQL的保留字
  3. 不允许嵌入空格或其它特殊字符

数据库对象命名规则:由服务器名、数据库名、拥有者名和对象名4部分组成,其格式如下:
[[[server.][database].][owner_name].]obeject_name

实例的命名规则
默认实例:此实例由运行它的计算机的网络名称标识。
命名实例:计算机可以同时运行任意个SQL Server命名实例。实例通过计算机的网络名称加上实例名称以<计算机名称><实例名称>格式进行标识,机computer_name​\instance_name,但该实例名不能超过16个字符。

3 常量
  • 数字常量
  • 字符串常量:字符串常量+Unicode字符串
  • 日期和时间常量
  • 符号常量
4 变量
  • 全局变量
  • 局部变量
  • 批处理脚本
5 运算符和表达式
  • 算术

  • 比较

  • 逻辑

  • 连接

  • 按位运算符

  • 优先级
    在这里插入图片描述

  • 表达式定义及分类

6 Transact-SQL利器——通配符

在这里插入图片描述

7 Transact-SQL语言中的注释

单行注释:–
多行注释/**/

8 轻松掌握Transact-SQL(SQL增强版)语句
  • 数据定义语句DDL:create、drop(库:磁盘空间清除,表:定义,数据,索引,视图都会删除)、alter
    在这里插入图片描述

  • 数据操作语句DML:insert、update、delete(删除记录)、select

  • 数据控制语句DCL:grant、deny(拒绝权限)、revoke(收回权限)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 其他基本语句
    数据声明:declare(不提供值则默认初始化null)
    数据赋值:set
    数据输出:print

print @name+' '+convert(varchar(20),@age)
  • 流程控制语句(控制执行顺序)
    BEGIN…END语句(通常包含在其他控制流程中,如if else,让if与else之间可以包含多条语句,否则只能有一条)
    IF…ELSE语句
    CASE语句(case (expression) when then…else)
    在这里插入图片描述
    在这里插入图片描述

WHILE语句(continue和break跳出循环)
GOTO语句
在这里插入图片描述

WAITFOR语句(暂时停止执行,不能指定日期,时间长度不超过24h)
在这里插入图片描述

RETURN语句(默认系统存储过程返回0标识成功,非0失败)

  • 批处理语句
    批处理是从应用程序发送到SQL Server并得以执行的一条或多条T-SQL语句。使用批处理时,有下面一些注意事项。
    一个批处理中只要存在一处语法错误,整个批处理都无法通过编译。
    批处理中可以包含多个存储过程,但除第一个过程外,其他存储过程前面都必须使用EXECTUE关键字。
    某些特殊的SQL指令不能和别的SQL语句共存在一个批处理中,如CREATE TABLE和CREATE VIEW语句。这些语句只能独自存在于一个单独的存储过程中。
    所有的批处理使用GO作为结束的标志,当编译器读到GO的时候就把GO前面的所有语句当成一个批处理,然后打包成一个数据包发给服务器。
    GO本身不是T-SQL的组成部分,只是一个用于表示批处理结束的前端指令。
    CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE SCHEMA、CREATE TRIGGER和CREATE VIEW语句不能在批处理中与其他语句组合使用。批处理必须以 CREATE 语句开头,所有跟在该批处理后的其他语句将被解释为第一个 CREATE 语句定义的一部分。
    不能在删除一个对象之后,在同一批处理中再次引用这个对象。
    如果 EXECUTE 语句是批处理中的第一句,则不需要 EXECUTE 关键字。如果 EXECUTE 语句不是批处理中的第一条语句,则需要 EXECUTE 关键字。
    不能在定义一个CHECK约束之后,在同一个批处理中使用。
    不能在修改表的一个字段之后,立即在同一个批处理中引用这个字段。
    使用SET语句设置的某些选项值不能应用于同一个批处理中的查询。

函数

对数据参数值返回特定值

  • 其他函数
  1. identity()
    语法 列名 数据类型 约束 identity(m,n)
    m表示的是初始值,n表示的是每次自动增加的值
  • 字符串函数
    编码转换
    获取字符的ASCII码 ASCII()
    获取ASCII码对应的字符 Char
    获取字符的unicode编码 Unicode
    获取unicode编码对应的字符 nchar
    位置查找
    获取字符串第一次出现位置 PatIndex(select patindex(‘abb%’,‘abcaabbeeabb’))
    指定位置搜索字符串中的内容 CHARINDEX(str1,str,[start])
    获取字符串长度
    获取字符串长度 LEN
    获取字符串字节数 DATALENGTH
    截取字符串
    返回字符串左边开始指定个数的字符串、字符或者二进制数据表达式 LEFT(select LEFT(‘football’,4)返回foot)
    截取右边字符串RIGHT
    截取字符串 SUBSTRING
    生成内容
    生成空格字符串 SPACE
    按指定次数重复生成字符串 REPLICATE
    删除再重新插入字符串内容 STUFF
    生成带分隔符的unicode字符串 QUOTENAME
    改变与转换
    清除左边空格 LTRIM
    清除右边空格 RTRIM
    转换为小写字符串 LOWER
    转换为大写字符串 UPPER
    反序字符串 REVERSE
    替换字符串 REPLACE
    转换浮点数字为字符串 STR(float_expression[,length[,deciamal]])
  • 数学函数
    绝对值函数ABS(x)和返回圆周率的函数PI()
    平方根函数SQRT(x)
    获取随机数的函数RAND()和RAND(x)
    四舍五入函数ROUND(x,y)保留小数点y位
    符号函数SIGN(x)
    获取整数的函数CEILING(x)不小于x最小整数和FLOOR(x)不大于x最大整数
    幂运算函数POWER(x,y)、SQUARE ( x)和EXP(x)
    对数运算函数LOG(x)和LOG10(x)
    角度与弧度相互转换的函数RADIANS(x)和DEGREES(x)
    正弦函数SIN(x)和反正弦函数ASIN(x)
    余弦函数COS(x)和反余弦函数ACOS(x)
    正切函数、反正切函数和余切函数
  • 数据类型转换函数
    不能隐式转换的使用CAST(x as type)和CONVERT(type,x)
    convert(time,‘2012-01-12’)
    select cast(‘1’ as date)
  • 文本和图像函数
    TEXTPRT(column) 返回文本指针值TEXTVALID(‘table.column’,text_ptr)检查特定文本指针是否有效
  • 时间和日期函数
    1 获取系统当前日期的函数GETDATE()
    2 返回UTC日期的函数UTCDATE()
    3 获取天数的函数DAY(d)
    4 获取月份的函数MONTH(d)
    5 获取年份的函数YEAR(d)

6 获取日期中指定部分字符串值的函数DATENAME(dp,d)
7 获取日期中指定部分的整数值的函数DATEPART(dp,d)
在这里插入图片描述

8 计算日期和时间的函数DATEADD(dp,num,d)执行日期加运算
在这里插入图片描述

  • 系统函数
    COL_LENGTH(table,column):返回table表中column字段的长度;
    COL_NAME(TABLE_ID,COLUMN_ID):返回指定表中指定字段的名称;
    在这里插入图片描述

CURRENT_TIMESTAMP: 返回当前的日期和时间。此函数等价于 GETDATE()
CURRENT_USER: 返回当前的用户。
DATALENGTH(x): 返回字段x的数据的实际长度,即字节数,NULL的长度为NULL;
DB_ID(db_name)返回数据库编号。smallint类型
DB_NAME(db_id)返回数据库名称。
HOST_ID();
HOST_NAME():
OBJECT_ID(db_name.schema_name.object_name,object_type)返回数据库编号
OBJECT_NAME(object_id,[,database_id])返回数据可对象名称
@@ERROR: 返回最后执行的 Transact-SQL 语句的错误代码
GETANSINULL: 返回会话的数据库的默认为空性。
HOST_ID: 返回工作站标识号。
HOST_NAME: 返回工作站名称。
SUSER_SID()返回SID
SUSER_SNAME()返回用户登录名
USER_ID(user):根据指定用户名返回数据库用户的ID
USER_NAME(id):根据与数据库用户关联的ID返回数据库用户名

IDENTITY(函数): 只用在带有 INTO table 子句的 SELECT 语句中,以将标识列插入到新表中。
ISDATE: 确定输入表达式是否为有效的日期
ISNULL: 使用指定的替换值替换 NULL
ISNUMERIC: 确定表达式是否为一个有效的数字类型
NEWID: 创建 uniqueidentifier 类型的唯一值
SERVERPROPERTY: 返回有关服务器实例的属性信息
SYSTEM_USER: 返回当前系统用户名
@@TRANCOUNT: 返回当前连接的活动事务数

Transact-SQL查询
  • 使用select查询
    *和列名
    、distinct取消重复
    、top(select top N * from tablename)
    、修改列标题
    、在查询结果集中显示字符串
    、查询的列为表达式
  • where字句进行条件查询
    使用关系表达式查询>、<、=、<>(或!=)
    使用BETWEEN AND表示范围
    使用IN关键字
    使用LIKE关键字
    使用IS NULL查询空值
    使用EXISTS关键字
    使用ORDER BY排序
    使用GROUP BY分组
    使用HAVING对分组结果过滤
    使用COMPUTE子句对查询结果小计(解决group by返回结果集直邮和技术局没有原始详细记录)
    使用COMPUTE BY子句分组小计
    使用UNION合并查询结果集
  • 使用聚合函数统计汇总
    SUM() AVG() MAX() MIN() COUNT()统计
  • 嵌套查询
    使用比较运算符
    在这里插入图片描述

使用IN关键字
使用ANY、SOME和ALL关键字
在这里插入图片描述

使用EXISTS关键字(select * from table1 where exists(select …))

  • 多连接查询
    相等连接
    在这里插入图片描述

不等连接
带选择条件的连接
自连接

  • 外连接
    left outer join(返回左表中所有记录和右表中连接字段相等的记录,不满足条件填入NULL)、right outer join 、full outer join
  • 使用排序函数
    ROW_NUMBER(按顺序对所有行进行编号(例如 1、2、3、4、5))在这里插入图片描述

    RANK(为关系提供相同的数值(例如 1、2、2、4、5))、在这里插入图片描述
    DENSE_RANK(序号相同,接下来递增) 在这里插入图片描述
    在这里插入图片描述
    、NTILE(N)分为N组,各组有编号从1开始,返回此组编号
    在这里插入图片描述
  • 动态查询
    在这里插入图片描述

数据更新

分为更新单条和多条数据
insert
update
delete

规则、默认和完整性约束

  1. 规则和默认概述
    规则是对存储的数据表的列或用户定义数据类型中的值的约束,规则与其作用的表或用户定义数据类型是相互独立的

  2. 规则的基本操作

  • 创建规则(规则不能引用列或其他数据库对象)
    create rule rule_name as codition_expression
    在这里插入图片描述

  • 把自定义规则绑定到列(用存储过程)
    sp_bindrule ‘rule’,‘object_name’[,‘futureonly_flag’]
    在这里插入图片描述

  • 验证规则作用

  • 取消规则绑定
    sp_unbindrule ‘object_name’[,‘futureonly_flag’]

  • 删除规则

drop rule rule_name
  1. 默认的基本操作
    默认值只在insert语句中用,update,delete语句将忽略
  • 创建默认
create default <default_name>
as <constraint_expression>

create default defaultSex as 'Female':
  • 把自定义默认绑定到列(使用系统存储过程sp_binddefalut
    在这里插入图片描述
    在这里插入图片描述

  • 验证默认作用

  • 取消默认绑定
    在这里插入图片描述
    在这里插入图片描述

  • 删除默认
    drop default defalutSex

  1. 完整性约束
    包含实体完整性(primary key,unique,dientity),参照完整性(foreign key,check),用户自定义完整性(规则,触发器,存储过程,约束)
  • 主键约束
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    默认clustered
    删除主键:在这里插入图片描述

  • 外键约束
    在这里插入图片描述

  • 唯一性约束Unique(一列或多列,允许为空)

  • CHECK约束
    在这里插入图片描述

  • DEFAULT约束
    在这里插入图片描述

  • NOT NULL约束

索引

索引的建立可以加快数据库的查询速度,其他市县数据参照完整性加速表和表之间的连接,显著减少查询中分组和排序的时间。
缺点:耗费时间,占用磁盘空间,数据变化时索引需要动态维护

SQL Server中的索引有两种:

  • 聚集索引
    基于数据航键值,在表内排序和存储这些数据航,每个表只有一个聚集索引
    考虑:
    在这里插入图片描述

  • 非聚集索引
    完全独立数据航的结构,不用按照物理上数据排序。包含索引键值和指向标数据存储位置的行定位器。
    对表或索引视图创建多个非聚集索引。通常,用来改善经常使用没有剪辑狙击索引的查询的性能
    使用场景:
    在这里插入图片描述
    -其他索引
    唯一索引,包含列索引,**索引视图,**全文索引,空间索引,筛选索引,XML索引

设计索引原则
(1)索引并非越多越好,如果有大量的索引,会占用大量的磁盘空间,而且会影响INSERT、DELETE、UPDATE等语句的性能。表中数据更改的同时,索引也会进行调整和更新。
(2)避免对经常更新的表进行过多的索引,并且索引中的列尽可能少。而对经常用于查询的字段应该创建索引,但要避免添加不必要的字段。
(3)数据量小的表最好不要使用索引,由于数据较少,查询花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化效果。
(4)在条件表达式中经常用到的、不同值较多的列上建立索引,在不同值少的列上不要建立索引。比如在学生表的“性别”字段上只有“男”与“女”两个不同值,因此就无须建立索引。如果建立索引,不但不会提高查询效率,反而会严重降低更新速度。
(5)当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引能够确保定义的列的数据完整性,提高查询速度。
(6)在频繁进行排序或分组(即进行GROUP BY或ORDER BY操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

  • 创建索引
    使用对象资源管理器创建索引
    在这里插入图片描述

使用T-SQL语句创建索引
在这里插入图片描述
在这里插入图片描述

  • 管理和维护索引
    数据表改变是索引页出现碎块,为提高性能需要关机,包括显示索引信息,索引性能分析和维护,删除索引等
    1 显示索引信息sp_helpindex
    在这里插入图片描述
    dbss show_statistics返回指定表或试图特定对象(索引,列)统计信息(分析索引性能,维护索引)
    在这里插入图片描述

2 重命名索引 用sp_rename存储过程
在这里插入图片描述
除了index还可以是column,database,object(check,foreign key ,primary/unique key,用户表,规则等)。userdatatype
3 删除索引 drop,不能删create/alter table创建的主键和唯一性序偶因,系统表中的索引
drop index ‘index’ on ‘[table|view]’

SQL书写规范

1、 语句中出现的所有表名、字段名全部小写,系统保留字、内置函数名、Sql保留字大写。
2、 连接符or、in、and、=、!=等前后加上一个空格。
3、 对较为复杂的sql语句加上注释,说明算法、功能。
4、缩进风格
(1) 一行有多列,超过80个字符时,基于列对齐原则,采用下行缩进
(2) where子句书写时,每个条件占一行,语句另起一行时,以保留字或者连接符开始,连接符右对齐。
5、 多表连接时,使用表的别名来引用列。
6、 供别的文件或函数调用的函数,绝不应使用全局变量交换数据;
7、命名规范,用英文,名字反映变量作用。如:
g名称 全局变量
m名称 局部变量
c名称 光标
p名称 参数
8、 查找数据库表或视图时,只取需要的那些字段,不能使用列的序号,不要使用*。
9、 功能相似的过程和函数,尽量写到同一个包中,加强管理。

其他语句

1.SELECT INTO 语句
从一个表中选取数据,然后把数据插入另一个表中。
SELECT INTO 语句常用于创建表的备份复件或者用于对记录进行存档。

-- 从ST_User查询数据,填充至新生成的临时表 
select * into #DU_User2 from ST_User where ID<8 
--将查询结果集(多条数据)插入临时表 
insert into #t select * from ST_User 
--不能这样插入 
--select * into #t from dbo.ST_User 

事务和锁

事务管理为了保证一批对数据库操作能够全部完成,从而保证数据完整性。
锁机制控制多个用户对统一数据进行的操作,解决数据库并发问题。

事务管理

事务是SQL Server基本工作单元,是用户定义的一个数据库操作序列,要么全部执行,要么一个也不执行。事务主要可以分成自动提交事务,隐式提交,显式事务,分布式事务。
在这里插入图片描述
事务的原理
1.事务含义
要有非常明确地开始和结束点,sql server中每一条数据操作语句,select,insert都是隐式事务一部分。
事务开始后,事务操作写入事务日志(整队数据的操作如插入修改删除和针对任务的操作如创建索引),取消事务操作时,系统执行反操作,保证事务一致性。系统自动生成一个检查点机制,它周期检查事务日志,事务如果全部完成就将该事务提交到数据库并做完成标志,如果事务没完成,就不提交到数据库,做未提交标志。事务的恢复及检查点保证了系统的完整性和可恢复。

  • 事务四个特性
    原子性:操作指令时要么全执行要么全不执行
    一致性:必须使数据库从一个一致性状态转换成另一个一致性状态
    隔离性:多个用户并发访问数据库时,多个并发事务互相隔离(识别事务状态要么是另一并发事务修改之前的状态,要么是之后状态,不识别中间态的数据,称为可串行性)
    持久性:事务一旦提交,对数据的改变是永久的
  • 建立事务应当遵循原则:
    在这里插入图片描述

2.事务管理的常用语句
SQL Server中常用的事务管理语句包含如下几条:
BEGIN TRANSACTION——建立一个事务
COMMIT TRANSACTION——提交事务
ROLLBACK TRANSACTION——事务失败时执行回滚操作
SAVE TRANSACTION——保存事务
3.事务四个隔离级别
事务具有隔离性,每个数据同一时刻只能有一个事务进行操作,将数据锁定,其他事务就要排队,防止多个事务互相印象。
为了提高并发使用效率,在事务读取数据设置隔离状态。

  • READ UNCOMMITED级别/读未提交:不隔离数据,事务正在使用数据时其他事务能同时修改和删除数据。不会发出共享锁防止其他事务修改当前事务读取的数据。
  • READ COMMITED级别/读已提交:不能读取其他数据已经修改未提交的数据,避免脏读。其他事物可以在当前事务的各个语句之间更改数据,产生幻读,不可重复读数据。SQL Server默认配置。
  • REPETABLE READ/可重复读:不能读取其他数据已经修改未提交的行,并且制定其他任何事务都不能再当前事务完成之前修改由当前事务读取的数据。设置了共享锁保持到事务完成为止。防止其他事物修改当前事务读取的任何行。
  • SNAPSHOT/快照级别:读取的数据时事务开始前便存在的数据事务上一致版本。
  • SERIALIZABLE/可序列化级别:全部锁定,不允许其他事务改变数据,降低并发性,其他事务必须排队。
    在这里插入图片描述
    在这里插入图片描述
    事务以BEGING TRANSATION开始,以COMMIT TRAN或ROLLBACK TRAN结束。

在这里插入图片描述

在同一时间可以有很多个事务正在处理数据,但是每个数据在同一时刻只能有一个事务进行操作。如果将数据锁定,使用数据的事务就必须要排队等待,这样可以防止多个事务互相影响。但是如果有几个事务因为锁定了自己的数据,同时又在等待其他事务释放数据,则造成死锁。

解决当多个用户同时对一个数据库修改产生的的并发问题。避免发现数据不一致。

1.锁的内涵

并发操作带来的问题:

  1. 脏读:一个事务处理过程里读取了另一个未提交的事务中的数据。例如,员工表中编号1001的员工工资8000,事务1将工资修改为9000,还没确认提交。事务2读取员工工资为9000后,事务1执行回滚,取消修改,但是事务2已经把1001的8000读走了。
  2. 幻读:执行insert和delete操作后,该数据行恰好被另一个事务读取,另一个事务发生幻读。例如,将6000以下工资涨到6000,事务1使用update语句进行更新操作,事务2读取这批数据然后在其中插入工资小于6000记录,事务后如果查看数据表中的数据就发现update后还有工资小于6000的记录。
    (解决:使用表级锁,读取数据总量之后才释放锁)
    使用set更改事务隔离级别
  3. 不可重复读:一个事务范围内多次查询却返回了不同的数据值,因为读取中间另一个事务修改了数据。针对update操作 ,读取了其他事物更改的数据
    (解决:使用行级锁,锁定该行,读取操作完成后再释放)
  4. 丢失更新
    一个事务更新数据库后,另一个事物又更新数据库,系统只保留一个数据库的修改。
2.可锁定的资源

sql server可以锁定不同类型的锁,自动将资源锁定合适层次。锁的层次越高,粒度越粗,资源用较少,因为要维护的锁较少。
SQL Server根据粒度大小分为6种可锁定的资源。有细到粗:数据行、索引键(索引中的特定键,相同索引页中其他键不收影响)、页(锁定该页所有数据或索引键)、区段页(一组连续8个数据页)、数据表(系统资源占用少,数据资源占用大)、数据库。

锁的类型:

有些类型可以兼容,有些不可以。锁模式决定了并发实物访问资源的模式。

  • 修改/更新锁(U )
    一般用于可更新的资源,防止多个回话在读取,锁定,以及资源更新出现死锁现象。当一个事务查询数据以便修改时,可以对数据项加更新锁,如果事务修改资源,更新锁转换为排它锁,如果不修改资源,则转化为共享锁。一次只有一个事务可以获得资源上的更新锁,允许其他事务对资源共享访问,但阻止排他式访问。
    使用共享锁时,修改数据的操作分为两步,首先获得一 个共享锁,读取数据,然后将共享锁升级为独占锁,然后再执行修改操作。这样如果同时有两个或多个事务同时对一个事务申请了共享锁,在修改数据的时候,这些 事务都要将共享锁升级为独占锁。这时,这些事务都不会释放共享锁而是一直等待对方释放,这样就造成了死锁。

  • 独占/排它 (X)锁
    用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。它所锁定的资源,其他事务不能读取也不能修改。独占锁不能和其他锁兼容。

  • 共享锁(S)
    用于读取数据资源,允许多个事务读取相同数据,但不允许其他事物修改当前数据,如 SELECT 语句。多个事务读取一个存在共享锁的资源,其他事务不能修改数据,除非提高事务隔离级别到可重复度,数据被读取后,SQL Server立即释放共享锁。

  • 键范围锁
    防止幻读,通过保护行之间键的范围,防止事务访问的记录集进行幻想插入或删除。

  • 结构/架构锁
    结构锁分为结构修改锁(Sch-M)和结构稳定锁(Sch-S)。执行表定义语言操作时,SQL Server采用Sch-M锁,防止对表的并发访问。意味着释放架构修改锁之前,该锁的所有操作都会被阻止。编译查询时,SQL Server采用Sch-S锁。
    。。。

  • 意向锁 用于建立锁的层次结构。意向锁的类型为:意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。 在表级设置意向锁可防止另一个事务随后在包含那一页的表上获取排它 (X) 锁。意向锁可以提高性能。
    意向共享 (IS) 通过在各资源上放置 S 锁,表明事务的意向是读取层次结构中的部分(而不是全部)底层资源。
    意向排它 (IX) 通过在各资源上放置 X 锁,表明事务的意向是修改层次结构中的部分(而不是全部)底层资源。IX 是 IS 的超集。 与意向排它共享 (SIX) 通过在各资源上放置 IX 锁,表明事务的意向是读取层次结构中的全部底层资源并修改部分(而不是全部)底层资源。允许顶层资源上的并发 IS 锁。例如,表的 SIX 锁在表上放置一个 SIX 锁(允许并发 IS 锁),在当前所修改页上放置 IX 锁(在已修改行上放置 X 锁)。虽然每个资源在一段时间内只能有一个 SIX 锁,以防止其它事务对资源进行更新,但是其它事务可以通过获取表级的 IS 锁来读取层次结构中的底层资源。

  • 大容量更新 (BU) 批量复制数据时使用批量修改锁。可以通过表的TabLock提示或者使用系统存储过程sp_tableoption的“table lock on bulk load”选项设定批量修改锁。

3.死锁

两个或多个任务中,每个任务锁定其他任务试图锁定的资源,造成这些任务永久阻塞,出现死锁。此时系统处于死锁状态。

3.1产生死锁的四个必要条件

(1) 互斥条件:资源每次只能被一个进程使用。
(2) 请求与保持条件:获得资源的进程可同时申请新的资源。
(3) 非剥夺条件:已获得的资源不能在该进程中剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

3.2可能会造成死锁的资源

(1)锁。等待获取资源的锁可能导致死锁
(2)工作线程。排队等待可用工作线程的任务可能导致死锁。
(3)内存
(4)并行执行的相关策略

3.3减少死锁发生的策略

(1).按同一顺序访问资源。(注:避免出现循环)
(2).避免事务中的用户交互。(注:减少持有资源的时间,较少锁竞争)
(3).保持事务简短并处于一个批处理中。(注:同(2),减少持有资源的时间)
(4).使用较低的隔离级别。(注:使用较低的隔离级别(例如已提交读)比使用较高的隔离级别(例如可序列化)持有共享锁的时间更短,减少锁竞争)
(5).使用绑定连接/Bound Connections。同一应用程序打开两个或多个连接可以相互合作,想朱简介获取的锁那样持有次级连接获取的任何锁,反之亦然,不会互相阻塞。
(6).使用基于行版本控制的隔离级别。持快照事务隔离和指定READ_COMMITTED隔离级别的事务使用行版本控制,可以将读与写操作之间发生死锁的几率降至最低。
SET READ_COMMITTED_SNAPSHOT ON指定READ_COMMITTED隔离级别的事务,在已提交读隔离级别下运行的事务在读操作其间将使用行版本控制而不是共享锁。在默认情况下,SELECT语句会对请求的资源加S(共享)锁,而开启了此选项后,SELECT不会对请求的资源加S锁。
SET ALLOW_SNAPSHOT_ISOLATION ON事务可以指定SNAPSHOT事务隔离级别,读操作不使用共享锁;

3.4锁的应用案例

(1)锁定行
在这里插入图片描述

(2)锁定表
在这里插入图片描述

(3)排它锁
在这里插入图片描述
在这里插入图片描述

(4)共享锁
在这里插入图片描述

(5)死锁
发生死锁,SQL Server选择一个死锁牺牲,对牺牲的事务进行回滚,另一个事务继续正常运行。默认选择回滚代价最低的事务牺牲掉。无法避免死锁,只能采用相应规则有效减少死锁

游标

游标用来逐条读取较大查询结果集中的记录。

1.认识游标

1.1游标的概念

游标是一种数据处理芳芳,主要用于存储过程,触发器,transact-sql脚本,使结果集中的内容可以用于其他transact-SQL语句。在查看或处理结果集中的数据,可以提供向前向后浏览数据的功能。类似指针,可以指向结果集中任意位置。
当对数据结果集进行逐行单独处理时,必须声明一个指向该结果集的游标变量。

1.2游标的优缺点

Select语句返回的是一个结果集,有时候不能对整个结果集有效处理。游标提供一种机制从包含多条数据记录的结果集中每次提取一条记录,游标总与一条SQL选择语句关联,由结果集和指向特定记录的游标位置组成。使用游标具有以下特点。

优点:
(1) 可以灵活操作表中检索出的数据,对select返回行结果集中每一行进行相同或不同操作,而不是对整个集合执行同一个操作
(2)可以基于游标位置对数据删除或更新。
(3)作为数据库管理系统和应用程序设计之间的桥梁,将两种处理方式连接起来。
缺点:复杂低效,速度慢

1.3分类

SQL Server支持3中游标实现:
transact-sql游标(基于DECLARE CURSOR语法,主要用于TRANSACT SQL语法,存储过程,触发器。在服务器实现,并由客户端发送到服务器的Transact-SQL语句管理),API服务器游标,客户端游标(通过在客户端高速缓存所有结果集中的行实现)。

SQL server支持4中API服务器游标类型:只进游标(不支持滚动,只支持顺序提取),静态游标(始终是只读的,不反应在数据库中国做的修改),有键集驱动的游标(由唯一标识符控制。键集是打开游标时来自符合SELECT语句要求的所有行的一组键值),动态游标(与静态游标相对,反应结果集中所做的所有更改)

2.游标(结果集加游标位置)的基本操作

2.1声明游标

在这里插入图片描述

在这里插入图片描述

2.2打开游标

在这里插入图片描述
在这里插入图片描述

2.3读取游标总的数据

fetch命令可以读取由表中某一行的数据
在这里插入图片描述
在这里插入图片描述

2.4关闭游标

释放游标与数据库的连接
在这里插入图片描述

2.5释放游标

将游标从内存中删除,释放系统资源在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述

3.游标运用

3.1使用游标变量

在这里插入图片描述

3.2用游标为变量赋值

在这里插入图片描述
在这里插入图片描述

3.3用order by字句改变游标中行的顺序

在这里插入图片描述
在这里插入图片描述

3.4用游标修改数据

在这里插入图片描述

在这里插入图片描述

3.5用游标删除数据

可以使用游标删除数据时,既可以删除游标结果集中的数据,也可以删除基本表中的数据
在这里插入图片描述

4.使用系统存储过程管理游标

4.1 sp_cursor_list存储过程

可以查看当前连接打开服务器游标属性
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2 sp_describe_cursor存储过程

可以查看服务器游标属性
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.3 sp_describle_cursor_columns

可以查看服务器游标结果集中列的属性
在这里插入图片描述
在这里插入图片描述

4.4 sp_describle_cursor_tables

可以查看服务器游标被一弄对象或基本表的属性
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

存储过程和自定义函数

存储过程是一条或多条SQL语句的集合,可被视为批处理文件,但作用不仅限于批处理。

1.存储过程概述

目的在于方便从系统表中查询信息,完成与更新数据库表相关的管理人无或其他系统管理人无。Transact-SQL语句是SQL Server数据库与应用程序之间的编程接口。
简而言之,存储过程是SQL Server为了实现特定任务,将需要多次调用的固定操作语句编写成程序段,存储在服务器上,让数据库服务器通过子程序调用。
优点:

  • 加快系统运行速度,存储过程只在创建时编译,以后执行不需重新编译
  • 可以封装复杂的数据库操作,简化操作流程
  • 实现模块化的程序设计,存储过程可以多次调用,提供统一的数据库访问接口,改进应用程序的可维护性
  • 增强代码的安全性,用户不能直接操作存储过程中引用的队形,并且可以设定用户对指定存储过程的执行全兴
  • 降低网络流量,在客户端与服务器通信过程中,不会产生大量的T-SQL代码流量

缺点:

  • 数据库移植不方便,以来与数据库管理系统,SQL Server存储过程中封装的操作代码不能直接移植到其他的数据库管理系统中
  • 不支持免息那个对象设计,无法采用面向对象方式将逻辑业务进行封装,形成通用的可支持服务的业务逻辑框架。
  • 代码可读性差,不易维护
  • 不支持集群

2.存储过程分类

分类:系统存储过程,自定义存储过程,扩展存储过程

2.1系统存储过程

用于主要从系统表中获取信息,系统存储过程位于数据库服务器中,以sp_开头,存放在系统数据库master中,一些系统存储过程只能有系统管理员使用,一些可以授权被其他用户使用。

2.2自定义存储过程

自定义存储过程即用户使用T-SQL语句编写的、为了实现某一特定业务需求,在用户数据库中编写的T-SQL 语句集合,用户存储过程可以接受输入参数、向客户端返回结果和信息、返回输出参数等。
创建自定义存储过程时,存储过程名前面加上“#l#”表示创建了一个全局的临时存储过程;存储过程名前面加上“#”时,表示创建局部临时存储过程。局部临时存储过程只能在创建它的会话中使用,会话结束时,将被删除。这两种存储过程都存储在 tempdb数据库中。
分为两类:Transact-SQL和CLR
Transact-SQL:保存的T-SQL语句集合,可以接受和返回用户提供的参数。
CLR:指引用Microsoft.NET Framework公共语言方法的存储过程,可以接受和返回用户提供的参数。

2.3扩展存储过程

通过SQL Server环境外执行的动态链接库(DLL)实现,可以加在到实例运行地址空间中执行,可以使用扩展存储过程API完成编程。xp_标识。

3.创建存储过程

3.1创建存储过程

在这里插入图片描述
在这里插入图片描述
创建存储规则
在这里插入图片描述

3.2调用存储过程

在这里插入图片描述

3.3创建带参数的输入存储过程

在这里插入图片描述
传递参数方式:直接给出参数的值,使用参数名=参数值
在这里插入图片描述
不指定参数会出错,如果希望不给出参数也能正常呀运行或希望提供一个默认的结果,则设置默认值
在这里插入图片描述

3.4创建带输出参数的存储过程

可以从存储过程中返回一个或多个值,用output关键字

在这里插入图片描述
·
在这里插入图片描述

4.管理存储过程

可以使用OBJECT_DEFINITION系统函数查看存储过程的内容,如果修改存储过程,可以使用ALTER PROCEDURE语句。管理存储过程包括:修改,查看,重命名,删除存储过程

4.1 修改存储过程

在这里插入图片描述
在这里插入图片描述

4.2查看存储过程信息

OPBJECT_DEFINITION,sp_help,sp_helptext.
在这里插入图片描述

4.3重命名存储过程

sp_rename _, _

4.4删除存储过程

在这里插入图片描述
在这里插入图片描述

5.扩展存储过程

在编程语言中创建自己的外部例程,可以直接在实例地址空间中运行。
在这里插入图片描述

6.自定义函数

可以像系统函数一样在查询,存储过程中调用,使用EXECUTE命令执行。可以接受参数,执行参数,将操作结果用值得形式返回。返回值可以用单个标量值或结果集。
1.标量函数
返回类型可以是除了text,ntext,image,cursor,timestamp外
2.表值函数
返回值类型是table,返回的表值是单个select语句查询的结果,相当于一个参数化的视图
3.多语句表值函数
返回值的表中的函数是由函数体中的语句插入的,可以进行多次查询,对数据进行多次筛选与合并。

定义函数优点:
1.允许模块化的设计
2.执行速度更快
T-SQL函数更适用于数据访问密集型逻辑
3.减少网络流量
可以在where字句中调用

1.创建标量函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.创建表值函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
多语句表值函数
多语句表值函数,则是需要指定具体的Table类型的结构。

CREATE FUNCTION function_name(@parameter_name parameter_data_type) 
--CREATE FUNCTION 函数名称(@参数名 参数的数据类型)
RETURNS @Table_Variable_Name table (Column_1 culumn_type,Column_2 culumn_type)    
--RETURNS @表变量 table 表的定义(即列的定义和约束)
[WITH ENCRYPTION]  --如果指定了 encryption 则函数被加密
[AS]
BEGIN
     函数体(即 Transact-SQL 语句)
 RETURN  
END

出处–海盗船长 https://www.cnblogs.com/baidawei/p/4732969.html
在这里插入图片描述

  1. returns后面直接定义返回的表类型。
  2. 在begin/end语句块中,直接将需要返回的结果insert到returns定义的表,在最后return时,会将结果返回。
  3. return后不跟任何变量。
3.修改函数

alter

4.删除函数

在这里插入图片描述

视图操作

视图是一个虚拟表,如同真实的表,包含行,列数据。

1.视图概述

是从数据库中一个或多个表中导出来的。视图是一个虚拟表。在视图中用户可以使用SELECT语句查询数据,以及使用insert,update,delete语句修改记录。对于对视图的操作最终转换为对基本数据表的操作。

1.1视图概念

视图存储在数据库中,与其对应的数据没有再储存,视图看到的数据只是存放在基本表中的数据。

1.1视图的分类
  1. 标准视图
    组合了一个或多个表的数据
  2. 索引视图
    经过计算并存储。可以为视图创建索引。索引视图可以显著提高某些类型查询的性能,尤其适于聚合许多行的查询,不太适合经常更新的基本数据集。
  3. 分区视图
    在一台或多台服务器间水平连接一组成员表中的分区数据。

视图的优点和作用
1.简单化
经常使用的查询被定义为视图,用户不必为以后每次操作指定全部操作
2. 安全性
用户值能查询和修改能见的数据。数据库授权命令可以使每个用户对数据库的检索 特定数据库 ,但不能授权到数据库特定行和特定的列
3.逻辑数据独立性
屏蔽真是表结构带来的影响

2.创建视图

  1. 使用视图设计器创建视图

  2. 使用T-SQL命令创建视图
    在这里插入图片描述
    select字句不能包含:compute(by),order by(除非 top字句),into子,option字句,引用临时表或表变量
    单个表中建立图
    在这里插入图片描述
    在多表上 创建视图
    在这里插入图片描述

3.修改视图

1.在SQL Server管理平台中,鼠标右击要修改的视图,从弹出的菜单中选择“设计”选项,出现视图修改对话框。该对话框与创建视图的对话框相同,可以按照创建视图的方法修改视图。
2.使用ALTER VIEW语句修改视图,但首先必须拥有使用视图的权限,然后才能使用ALTER VIEW语句。ALTER VIEW语句的语法格式与CREATE VIEW语法格式基本相同,除了关键字不同。
在这里插入图片描述

4.查看视图信息

查看视图信息

  1. 使用SSMS图形化工具查看视图定义信息
  2. 使用系统存储过程查看视图定义信息
    sp_help系统存储过程报告有关数据库对象,用户定义数据类型或SQL Server提供的数据类型洗
sp_help view_name

在这里插入图片描述
sp_helptext viewname 显示 规则,默值,未加密的存储过程,用户定义桉树,触发器,视图文本
在这里插入图片描述

5.使用视图修改数据

更新视图是指通过视图来插入,更新,删除表中的数据。
修改视图需要注意:

在这里插入图片描述

5.1.通过视图向基本表中插入数据

在这里插入图片描述
在这里插入图片描述

5.2 通过视图修改基本表中的数据

在这里插入图片描述

5.3 通过视图删除基本表中的数据

在这里插入图片描述

6.删除视图

1使用对象资源管理器删除视图
2使用T-SQL命令删除视图
在这里插入图片描述

7.视图与表

7.1视图与表区别

在这里插入图片描述
在这里插入图片描述

7.2视图与表联系

视图是在基本表之上建立的表,一个视图对应一个基本表,也可以对应多个基本表。视图是基本表的抽象和在逻辑意义建立的新关系

触发器

一种特殊存储过程。触发器可以 复杂的数据库操作和完整性约束过程,最大特点是其被调用执行T-SQL语句时是自动的。
使用触发器注意:

  • 对于相同表相同事件只能创建一个触发器,否则报错。
  • 不再使用的触发器要及时删除,因为需求变化 触发器没有进行相应的改变,依然执行旧的语句,影响数据完整性。

1.触发器概述

定义:修改指定表值时执行的存储过程(特定事件,insert,update,delete自动执行),保证相关数据引用完整性和一致性。
特点如下:
优点:触发器是自动的,可以通过数据库相关表进行层叠更改,可以强制限制
缺点:可移植性差;占用服务器资源;速度取决数据库服务器性能与触发器代码的复杂度;嵌套调用出现问题,排除困难

作用:保证复杂的参照完整性和数据的一致性,可以对数据库表进行级联修改,提供比check约束更复杂的数据完整性,并自定义错误信息。主要作用如下:
在这里插入图片描述

触发器分类:
在这里插入图片描述
使用DML触发器情形:
在这里插入图片描述
在这里插入图片描述

2.创建DML触发器

2.1insert触发器

在这里插入图片描述
after是默认设置,只能在表上 创建
在这里插入图片描述
在这里插入图片描述

2.2delete触发器

在这里插入图片描述
在这里插入图片描述

2.3update触发器

更新前额记录储存在delete表,更新后的记录储存在inserted表
在这里插入图片描述

2.4替代/INSTEAD OF触发器

在执行INSTEAD OF触发器代码时,先建立两张临时表,然后解触发/INSTEAD OF触发器,二拒绝执行用户输入的DML操作语句
。基于多个基本表的视图必须使用/INSTEAD OF触发器来对多个表的数据进行操作
在这里插入图片描述

2.5允许使用嵌套触发器

一个触发器执行操作调用了另一个触发器,这个触发器又接着调用下一个触发器,形成嵌套触发器。安装时被启用,可以 系统储存过程sp_configure禁用或重新启用。
最多嵌套32层,多了终止并回滚。注意:
在这里插入图片描述
下列情况需要禁用触发器:
·在这里插入图片描述

2.6递归触发器

一个触发器从其内部再一次激活该触发器,如update(需要内部判断),否则死循环。包括直接递归和间接递归。默认选项禁用。
在这里插入图片描述

3.创建DDL触发器

3.1语法

在这里插入图片描述

3.2创建服务器作用域DDL触发器

在这里插入图片描述

在这里插入图片描述
drop table…
在这里插入图片描述

4.管理触发器

4.1查看

在这里插入图片描述
在这里插入图片描述

4.2修改

在这里插入图片描述
create改成alter,修改与创建触发器语法格式完全相同

4.3删除

drop trigger...
在这里插入图片描述
在这里插入图片描述

4.4启用和禁用

禁用触发器可以用alter table 或disable trigger语句
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启用触发器可以用alter table,enable trigger语句
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

安全机制

SQL Server 的安全机制简介
SQL Server 整个安全体系结构从顺序上可以分为认证和授权两个部分,其安全机制可以分为5个层级。
(1)客户机安全机制
(2)网络传输的安全机制
(3)实例级别安全机制
(4)数据库级别安全机制
(5)对象级别安全机制
基本安全术语

  1. 数据库所有者
  2. 数据库对象
  3. 数据库组
  4. 系统管理员
  5. 许可
  6. 用户名
  7. 主体
  8. 角色

安全验证方式

  1. Windows身份验证模式
  2. 混合模式
  3. 设置验证模式

SQL Server登录名

  1. 创建登录账户
  2. 修改登录账户
  3. 删除登录账户

SQL Server 2012的角色与权限

  1. 固定服务器角色
  2. 数据库角色
  3. 自定义数据库角色
  4. 应用程序角色
  5. 将登陆指派到角色
  6. 将角色指派到多个登录
  7. 权限管理

数据库备份与恢复

备份类型
1、完全备份
可以备份整个数据库,包含用户表、系统表、索引、视图和存储过程等所有数据库对象。
2、事务日志备份
是自上次备份事务日志后对数据库执行的所有事务的一系列记录。可以使用事务日志备份将数据库恢复到特定的即时点(如输入多余数据前的那一点)或恢复到故障点。
3、差异备份
也叫增量备份,只记录自上次数据库备份后发生更改的数据。差异数据库备份比数据库备份小,而且备份速度快,因此可以更经常地备份,经常备份将减少丢失数据的危险。
4、文件备份
可以备份和还原数据库中的个别文件。可以只还原已损坏的文件,而不用还原数据库的其余部分,从而加快了恢复速度。
备份设备
备份设备类型
1.磁盘备份设备
2.命名管道设备
3.磁带备份设备
4.物理和逻辑设备
创建备份设备
查看备份设备
删除备份设备

使用T-SQL语言备份数据库

  1. 完整备份与差异备份
  2. 文件和文件组备份
  3. 事务日志备份

在SQL Server Management Studio中还原数据库
还原数据库的方式

  1. (1)新建数据库与要还原的数据库名同名
    (2)还原数据库时覆盖现有数据库
  2. 通过“还原文件和文件组”进行还原
  3. 数据库分离和附加
  4. 还原数据库前要注意的事项
  5. 还原数据库备份
  6. 还原文件和文件组备份

用T-SQL语言还原数据库

  1. 完整备份还原BACKUP DATABASE在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    NOINTIT:备份追加到现有备份集,避免覆盖完整备份

  2. 差异备份还原在这里插入图片描述

  3. 文件和文件组备份还原BACKUP在这里插入图片描述在这里插入图片描述

  4. 事务日志备份还原BACKIUP LOG在这里插入图片描述
    在这里插入图片描述

  5. 将数据库还原到某个时间点在这里插入图片描述
    insert->delete->对象资源管理器,点击该数据库,任务-还原-数据库-时间线-选中特定日期和时间-确认-返回确认备份设备

  6. 将文件还原到新位置上RESTORE DATABASE在这里插入图片描述

  7. 建立自动备份的维护计划
    数据库备份非常重要,并且有些数据的备份非常频繁,例如事务日志,如果每次都要把备份的流程执行一遍,那将花费大量的时间,非常繁琐和没有效率.sql server可以建立自动备份计划

链接服务器

1.适用场景
当我们要跨本地数据库,访问另外一个数据库表中的数据时,本地数据库中就必须要创建远程数据库的DBLINK,通过DBLINNK数据库可以像访问本地数据库一样访问远程数据库表中的数据。
链接服务器允许访问针对OLE DB数据源的分布式异构查询。创建链接服务器后,可以针对此服务器运行分布式查询,并且查询可以连接来自多个数据源的表。如果链接服务器被定义为SQL Server的实例,则可以执行远程存储过程。
2.创建过程
在这里插入图片描述
在这里插入图片描述

3.链接服务器的优缺点
优点
1、允许跨服务器访问。
2、数据量少的情况下使用比较简单,迅速。
3、可以执行远程存储过程等。
缺点
1、远程查询时易受网络等影响。
2、链接稳定性较差。
3、大量消耗数据库资源。
4、可扩展性较差。
5、维护性差、安全性较低。

性能优化

  1. 减少嵌套
  2. 使用临时表缓存中间结果。可以考虑适当拆成几步,先生成一些临时数据表,再进行关联操作。
  3. 少使用*
  4. 连接条件全写上
  5. 用distinct替代group by
SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID

可改为:

SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10
  1. union all代替union,UNION ALL不执行SELECT DISTINCT函数,这样就会减少很多不必要的资源消耗。
  2. 尽量不要用SELECT INTO语句。SELECT INOT 语句会导致表锁定,阻止其他用户访问该表.
  3. 建立索引,提高查询速度,同时应避免索引未被使用
    (1)在索引字段上进行函数或表达式操作时,将导致引擎放弃使用索引而进行全表扫描。
SELECT * FROM SomeTable WHERE col_1 * 1.1 > 100;-- 不会用到索引
SELECT * FROM SomeTable WHERE col_1  > 100* 1.1;--把运算的表达式放到查询条件的右侧,就能用到索引了。
SELECT * FROM SomeTable WHERE SUBSTR(col_1, 1, 1) = 'a’;--在查询条件的左侧使用函数,也不能用到索引。
使用索引时,条件表达式的左侧应该是原始字段!任何对索引字段的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

(2)IS NULL 谓词
通常,索引字段是不存在 NULL 的,所以指定 IS NULL 和 IS NOT NULL 的话会使得索引无法使用,进而导致查询性能低下。
在 DB2 和 Oracle 中,IS NULL 条件也能使用索引。这也许是因为它们在实现时为 NULL赋了某个具有特殊含义的值。但是,这个特性不是所有数据库都有的。

(3)下面这几种否定形式不能用到索引,会进行全表查询。
<>、!=、IN、NOT IN
针对字符串,IN可以使用EXISTS替代,NOT IN则使用NOT EXISTS替代。
经常需要写一个T_SQL语句比较一个父结果集和子结果集,从而找到是否存在在父结果集中有而在子结果集中没有的记录,如:

SELECT a.hdr_key FROM hdr_tbl a WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)
SELECT a.hdr_key FROM hdr_tbl a LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL 
SELECT hdr_key FROM hdr_tbl WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl)
这三种写法都可以得到同样正确的结果,但是效率依次降低。
使用 EXISTS 代替 IN:
SELECT * FROM Class_A WHERE id IN (SELECT id FROM Class_B)-- 慢
SELECT * FROM Class_A A WHERE EXISTS (SELECT * FROM Class_B B WHERE A.id = B.id)-- 快
EXISTS更快的原因:如果连接列(id )上建立了索引,那么查询 Class_B 时不用查实际的表,只需查索引就可以了。
如果使用 EXISTS ,那么只要查到一行数据满足条件就会终止查询,不用像使用 IN 时一样扫描全表。在这一点上 NOT EXISTS 也一样。*当 IN 的参数是子查询时,数据库首先会执行子查询,然后将结果存储在一张临时的工作表里(内联视图),然后扫描整个视图,很多情况下很消耗资源*。使用 EXISTS 的话,数据库不会生成临时的工作表。
针对数字类型的数据,能够用BETWEEN的就不要用IN
SELECT * FROM T1 WHERE ID IN (10,11,12,13,14)

改成:

SELECT * FROM T1 WHERE ID BETWEEN 10 AND 14

(4)OR的使用
尽量避免使用 or 来连接条件;在 where 子句中使用 or 来连接条件,引擎将放弃使用索引而进行全表扫描。可以使用

select id from t where num=10 union all select id from t where num=20
--替代下式
select id from t where num=10 or num=20

(5)使用联合索引时,列的顺序影响
假设存在这样顺序的一个联合索引“col_1, col_2, col_3 ”这时,指定条件的顺序就很重要。
SELECT * FROM SomeTable WHERE col_1 = 10 AND col_2 = 100 AND col_3 = 500;
SELECT * FROM SomeTable WHERE col_1 = 10 AND col_2 = 100 ;
× SELECT * FROM SomeTable WHERE col_1 = 10 AND col_3 = 500 ;
× SELECT * FROM SomeTable WHERE col_2 = 100 AND col_3 = 500 ;
× SELECT * FROM SomeTable WHERE col_2 = 100 AND col_1 = 10 ;

联合索引中的第一列(col_1 )应写在查询条件的开头,而且索引中的列按顺序排列,可以提高查询效率。
如果无法保证查询条件里列的顺序与索引一致,可以考虑将联合索引拆分为多个索引。

(6)LIKE谓词
使用like的时候要注意是否会导致全表扫描,有的时候会需要进行一些模糊查询例如:select id from table where username like ‘%hollis%’关键词%hollis%,由于hollis前面用到了“%”,因此该查询会使用全表扫描,除非必要,否则不要在关键词前加%。
LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”
即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >‘98000’,在执行查询时就会利用索引来查询,显然会大大提高速度。

(7)进行默认的类型转换
避免使用不兼容的数据类型。例如float和int、char和varchar、binary和varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如:

SELECT name FROM employee WHERE salary > 60000

在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。
对 char类型的“col_1”列指定条件的示例
× SELECT * FROM SomeTable WHERE col_1 = 10;
SELECT * FROM SomeTable WHERE col_1 = '10';
SELECT * FROM SomeTable WHERE col_1 = CAST(10 AS CHAR(2));
默认的类型转换不仅会增加额外的性能开销,还会导致索引不可用,可以说是有百害而无一利。虽然这样写还不至于出错,但还是不要嫌麻烦,在需要类型转换时显式地进行类型转换(转换要写在 条件表达式的右边)。

(8)模糊查询时使用全文索引contains函数替代使用LIKE函数

SELECT * FROM YSGZZ..TBBRJBXX WHERE CJTZZ LIKE'%内蒙古鄂尔多斯市%'  
SELECT * FROM YSGZZ..TBBRJBXX WHERE CONTAINS(CJTZZ, '内蒙古鄂尔多斯市') 

后一句使用了全文索引,因此查询速度会比上一句快很多。
当然CONTAINS函数也不是绝对的好,它会系统内把要查找的字符串进行分词,然后再按词来查找,因此,字符串的长度并不是越长越好,经SQL内验证,它只适用于不太长的字符串查找,如果字符串很长,用这个函数去查数据会造成部分满足LIKE条件的数据无法用CONTAINS查到,因此它只适用于短词查找
10.必要时强制查询优化器使用索引

SELECT * FROM T1 WHERE nextprocess = 1 AND processid IN (8,32,45)

改成:

SELECT * FROM T1 (INDEX = IX_ProcessID) WHERE nextprocess = 1 AND processid IN (8,32,45)

在执行时查询优化器将会强行利用索引IX_ProcessID 执行查询。
11、在 GROUP BY 子句和 ORDER BY 子句中使用索引
一般来说,GROUP BY 子句和 ORDER BY 子句都会进行排序,来对行进行排列和替换。不过,通过指定带索引的列作为 GROUP BY 和 ORDER BY 的列,可以实现高速查询。

12、 使用视图加速查询
  把表的一个子集进行排序并创建视图,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:

SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id = rcvlbes.customer_id AND rcvblls.balance>0 AND cust.postcode>98000ORDER BY cust.name

如果这个查询要被执行多次,可以把所有未付款的客户找出来放在一个视图中,并按客户的名字进行排序:

CREATE VIEW DBO.V_CUST_RCVLBES AS SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id= rcvlbes.customer_id AND rcvblls.balance>0 ORDER BY cust.name

然后以下面的方式在视图中查询:

SELECTFROM V_CUST_RCVLBES WHERE postcode>98000

视图中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。
参考《SQL SERVER 2012从0开始学》

常用sql

创建数据库

create database test2 
on(name='test2_dat',filename='D:\SQLDB\test2.mdf',size=3MB,maxsize=9MB,filegrowth=8%)
log on(name='test2_log',filename='D:\SQLDB\test2_log.ldf',size=1MB,maxsize=5MB,filegrowth=0)

创建数据表 transact sql

CREATE TABLE table_name
(column_name1 data_type(size),column_name2 data_type(size),column_name3 data_type(size),....); 

修改表字段
添加列:
ALTER TABLE table_name ADD column_name datatype
删除列:
ALTER TABLE table_name DROP COLUMN column_name
改表中列的数据类型:
ALTER TABLE table_name ALTER COLUMN column_name datatype

修改表约束
添加主键约束:
alter table TbStudent add constraint PK_TbStudent_stuId primary key(stuId)
添加唯一性约束:
alter table TbStudent add constraint UK_TbStudent_stuName unique(stuName)
添加check约束:
alter table TbStudent add constraint CK_TbStudent_stuAge check(stuAge>=18 and stuAge<=35)
添加非空约束,实际上就是对列的数据类型修改:
alter table TbStudent alter column stuPhone char(11) not null
添加外键约束:
alter table TbStudent add constraint FK_TbStudent_stuClassId foreign key(stuClassId) references TbClass(clsId)
删除约束:
alter table TbStudent drop constraint Fk_TbStudent_stuClassId

查看表中有关信息
SELECT * FROM TABLENAME WHERE …groupby…having…order by…

删除表
DROP TABLE TABLENAME

  • 1
    点赞
  • 0
    评论
  • 3
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

路新航

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值