今天着重整理一下SQL Server的理论基础
一、各概念的自我理解
定义都比较长,面试时也不可能记的全,要有理解,试着用一两句话概括一下各个概念
1、触发器:一种根据条件(事件)执行的存储过程,在项目中没用过,一般业务逻辑用程序来控制,数据库尽量只使用数据存储,不进行业务逻辑。
2、存储过程:一段预编译的SQL语句,因为编译过,所以执行起来比普通SQL快。在项目中主要用于一连串事务性的操作
3、索引:假设一本字典是按拼音排序,目录有拼音和笔划。索引就像目录,聚焦索引就像拼音索引,是物理上有序的,比如我要查L开头的,就知道大概在字典的中部,一张表只有一个聚焦索引,一般是主键。非聚焦索引就像笔划目录,也可以很方便查到相应数据,但物理上是无序的。索引会增加存储空间和降低数据修改的速度,但一般业务上都是对查询的速度要求高,对编辑的速度没那么敏感,而且现在存储设备价格低廉,空间不是问题。
4、约束:数据库有很多约束功能,非空、唯一、主外键、check、触发器等。一般除了必要的一些约束,尽量让数据库只进行数据的存取,不进行太多业务上的逻辑处理。因为业务逻辑不断变化,各项目也可能要共用数据库。
5、事务:有ACID特性(原子性、一致性、隔离性、持久性),要么全成功要么全失败,一般用于转账、出入库等
6、锁:锁定库、表、字段,有各种锁(表锁、行锁、共享锁、更新锁、排它锁等),比较细,有机会再仔细研究一下。项目中常用到的是WITH(NOLOCK),这样不受并发修改的锁影响,但数据可能不准确。
7、视图:把多表连接成一张表。项目中如果有固定的多表连接,可以做成视图,一般还是在程序中处理。
8、游标:像指针一样对查询结果集进行一行一行的处理,一行处理完指向下一行。性能比较差,有时逐条处理数据时会用到。Ado.Net的DataReader就是相当于一个向前只读的游标。只不过DataReader不过把结果集预先全查出来,所以对大数据性能比较好,而指针是要把结果集先查出来,再对结果集一行行处理(不知理解的对不对)
9、NULL:DECLARE @i=INT; 此时@i的值是NULL,而不像C#是0。。。有时没注意会被坑。SQL的可空类型对应的C#是<NULLABLE>,另外,NULL和''(空字符串)是不一样的,而且只能用 IS NULL来判断,=NULL是无效的(但不报错。。。也是一个大坑),为了保险,项目中经常用 ISNULL(xx,'')='' 之类的进行判断
10、主键外键:由于主键一般聚焦索引,常用自增长ID作主键,插入记录后可用@@IDENTITY获取插入新行的主键值。外键一般用于一对多,比如一个读者,其名下的借书记录。
二、各函数
太基本的函数就不列了,整理一些比较常用的
1、NEWID():获取GUID,配合ABS(CHECKSUM(NEWID())),可以在循环中获取随机数
2、RAND():获取随机数,但在循环中只会产生一个,要用NEWID()
3、字符串处理函数:
SELECT ASCII('a') --97,字符转成ASCII
SELECT ASCII('1') --49
SELECT ASCII(1) --49,数字可以不加单引号
SELECT CHAR(97) --a,ASCII转成字符
SELECT STR(12,2) --'12',数字转字符串
SELECT STR(12,1) --*,不足的以*表示
SELECT STR(12,3) --' 12',超出的前补0
SELECT STR(12) --' 12',默认10位
SELECT LTRIM(' a bc ') --'a bc ',去左端空格
SELECT RTRIM(' a bc ') --' a bc',去右端空格
SELECT LEFT('abc',2) --ab
SELECT RIGHT('abc',2) --bc
SELECT RIGHT('0000'+'123',4) --0123,用于前补0
SELECT SUBSTRING('abcd',1,2) --ab,【前一参数】包含第1位,取【后一参数】个
SELECT SUBSTRING('abcd',5,2) --'',超过为空
SELECT SUBSTRING('abcd',-1,2) --'',负数为空
SELECT SUBSTRING('abcd',4,2) --'d',取完为止
SELECT CHARINDEX('a','abcd') --1,子串出现位置,从1开始
SELECT CHARINDEX('e','abcd') --0,注意:C#有IndexOf,js有indexOf,找不到都为-1,SQL则是为0
SELECT PATINDEX('%a%','abcd') --1,子串出现位置,前后必须有百分号
SELECT PATINDEX('a','abcd') --0,前后必须有百分号否则返回0
SELECT QUOTENAME('abc','') --[abc],返回被特定字符括起来的字符串,默认[]
SELECT QUOTENAME('abc','{}') --{abc}
SELECT REPLICATE('ab',2) --abab,重复次数
SELECT REPLICATE('ab',0) --'',0为''
SELECT REPLICATE('ab',-2) --NULL,负数为NULL
SELECT REVERSE('abc') --cba,颠倒顺序
SELECT REVERSE(12) --21,颠倒顺序
SELECT REPLACE('abc','ab','AB') --ABc
SELECT SPACE(1) --' ',指定长度空白符
SELECT SPACE(0) --''
SELECT SPACE(-1) --NULL
SELECT STUFF('abcd',1,2,'X') --Xcd
SELECT STUFF('abcd',5,2,'X') --NULL
SELECT STUFF('abcd',-1,2,'X') --NULL
SELECT STUFF('abcd',2,-1,'X') --NULL