上善若水

水善利万物而不争
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

sqlserver SQL 面试题

Posted on 2022-03-24 09:41  董锡振  阅读(142)  评论(0编辑  收藏  举报

1. 索引的作用?和它的优点缺点是什么?

索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速对数据的检索。索引很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。

缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。

 

2. 使用索引有哪些需要注意的地方?

创建索引的的字段尽量小,最好是数值,比如整形int等;

对于频繁修改的字段,尽量不要创建索引,维护索引的成本很高,而且更容易产生索引碎片;

定期的索引维护,如索引碎片的修复等;

不要建立或维护不必要的重复索引,会增加修改数据(新增、修改、删除数据)的成本;

使用唯一性高的字段创建索引,切不可在性别这样的低唯一性的字段上创建索引;

在SQL语句中,尽量不要在Where条件中使用函数、运算符或表达式计算,会造成索引无法正常使用

尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描;

尽量避免在 where 子句中使用!=或<>操作符,否则将导致引擎放弃使用索引而进行全表扫描;

 

3. 索引碎片是如何产生的?有什么危害?又该如何处理?

索引在使用一段时间后(主要是新增、修改、删除数据,如果该页已经存储满了,就要进行页的拆分,频繁的拆分,会产生较多的索引碎片)会产生索引碎片。

索引碎片会严重印象数据的查询效率,如果碎片太多,索引可能不会被使用。

碎片的处理方式主要有两种:

第一种是预防:设置页的填充因子  意思就是在页上设置一段空白区域,在新增数据的时候,可以使用这段空白区域,可以一定的避免页的拆分,从而减少索引碎片的产生。

填充因子就是用来描述这种页中填充数据的一个比例,一般默认是100%填充的。如果我们修改填充因子为80%,那么页在存储数据时,就会剩余20%的剩余空间,这样在下次插入的时候就不会拆分页了。 那么是不是我们可以把填充因子设置低一点,留更多的剩余空间,不是很好嘛?当然也不好,填充因子设置的低,会需要分配更多的存储空间,叶子节点的深度会增加,这样是会影响查询效率的,因此,这是要根据实际情况而定的。

那么一般我们是怎么设置填充因子的呢,主要根据表的读写比例而定的。如果读的多,填充因子可以设置高一点,如100%,读写各一半,可以80~90%;修改多可以设置50~70%。

第二种是索引修复:定期对索引进行检查、维护,写一段SQL检查索引的碎片比例,如果碎片过多,进行碎片修复或重建,定期执行即可。 

 

4. 介绍存储过程基本概念和优缺点

存储过程是一个预编译的SQL语句,他的优点是允许模块化的设计,也就是说只需创建一次,在该程序中就可以调用多次。例如某次操作需要执行多次SQL,就可以把这个SQL做一个存储过程,因为存储过程是预编译的,所以使用存储过程比单纯SQL语句执行要快。

缺点是可移植性差,交互性差。

 

5. 锁的目的是什么?

主要解决多个用户同时对数据库的并发操作时会带来以下数据不一致的问题:

1、丢失更新,同时修改一条数据

2、读脏,A修改了数据后,B读取后A又取消了修改,B读脏

3、不可重复读,A用户读取数据,随后B用户读取该数据并修改,此时A用户再读取数据时发现前后两次的值不一致

并发控制的主要方法是封锁,锁就是在一段时间内禁止用户做某些操作以避免产生数据不一致

 

6. 锁的粒度有哪些?

数据库锁:锁定整个数据库,这通常发生在整个数据库模式改变的时候。

表锁:锁定整个表,这包含了与该表相关联的所有数据相关的对象,包括实际的数据行(每一行)以及与该表相关联的所有索引中的键。

区段锁:锁定整个区段,因为一个区段由8页组成,所以区段锁定是指锁定控制了区段、控制了该区段内8个数据或索引页以及这8页中的所有数据行。

页锁:锁定该页中的所有数据或索引键。

行或行标识符:虽然从技术上将,锁是放在行标识符上的,但是本质上,它锁定了整个数据行。

 

7. 什么是事务?什么是锁?

事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上个节点。

为了确保要么执行,要么不执行,就可以使用事务。要将所有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。

锁是实现事务的关键,锁可以保证事务的完整性和并发性。

 

8. 视图的作用,视图可以更改么?

视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的sql操作,隐藏具体的细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。视图的目的在于简化检索,保护数据,并不用于更新。

 

9. 什么是触发器(trigger)? 触发器有什么作用?

触发器是数据库中由一定时间触发的特殊的存储过程,他不是由程序掉用也不是手工启动的。触发器的执行可以由对一个表的insert,delete, update等操作来触发,触发器经常用于加强数据的完整性约束和业务规则等等。

 

10. SQL里面IN比较快还是EXISTS比较快?

这个题不能一概而论,要根据具体情况来看。IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。参考资料:http://www.zyiz.net/tech/detail-182426.html

 

11. 维护数据库的完整性和一致性,你喜欢用触发器还是自写业务逻辑?为什么?

尽可能使用约束,如check、主键、外键、非空字段等来约束。这样做效率最高,也最方便。其次是使用触发器,这种方法可以保证,无论什么业务系统访问数据库都可以保证数据的完整新和一致性。最后考虑的是自写业务逻辑,但这样做麻烦,编程复杂,效率低下。

 

12、oauth是什么?有哪些方式?

oauth是开发授权协议。主要用来颁发令牌(token)。有四种授权方式。

授权码(authorization-code) 隐藏式(implicit) 密码式(password) 客户端凭证(client credentials)

授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。


13、decimal的精度为什么比double高?

float 单精度浮点 32bit,

double 双精度浮点64bit,

decimal是高精度 128bit,浮点型。

float double 是 基本类型(primitive type),decimal不是。

float 有效数字7位,范围 ±1.5 × 10E−45 to ±3.4 × 10E38

double 有效数字15/16 位,范围 ±5.0 × 10 E−324 to ±1.7 × 10E308

decimal 有效数字 28/29 位,范围 ±1.0 × 10E−28 to ±7.9 × 10E28 

decimal的有效位数很大,达到了28位,但是表示的数据范围却比float和double类型小。使用的时候会对计算时的性能有影响。

数值存储范围越小的精度越高,存储数值范围越大,精度就越不准确,如果存储正常金额的情况下,使用money,好处在于可以存储不指定的小数点位数的数值,比较真实。如果对于既要求精度,又固定小数点位数的数值存储,采用decimal(numeric),优点在于可以自定义小数点位数,精度高。如特殊情况,如数值范围巨大只能用float(real)类型了,此类型一般不提倡使用