2018-11-07 数据库SQL面试常考

数据库软件

常见的关系数据库有Oracle、DB2、Sybase、SQL Server、Informax和MySQL等,非关系型数据库有MongoDB、memcachedb和Redis等。

数据库三范式

https://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.html

  1. 第一范式(确保每列保持原子性)
    第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
  2. 第二范式(确保表中的每列都和主键相关)
    第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
    比如一个订单号可以有多个上面,那么订单号和商品编号一起才能作为主键,这样商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。
  3. 第三范式(确保每列都和主键列直接相关,而不是间接相关)
    第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段

索引分类

https://www.cnblogs.com/newpanderking/p/3781043.html
https://www.cnblogs.com/lj820403/p/7246657.html
根据索引的顺序与数据表的物理顺序是否相同分为聚集索引和非聚集索引。

  1. 聚集索引:对表中的数据行按指定键值(即索引列值)进行排序后再重新存储到磁盘上,使数据表的物理顺序与索引一致。每个表只能建立一个聚集索引
    优点:检索速度比非聚集索引快。
    缺点:重组了表的物理顺序并且在建立聚集索引时需要足够的工作空间。
  2. 非聚集索引:具有完全独立于数据行的结构,不需要将数据表中的数据行按索引值重新排序。非聚集索引表中存储了组成非聚集索引的键值和行定位器,行定位器是指向数据行的指针,该数据行具有与索引键值相同的字段值。
    优点:不需要改变数据行的存储顺序,而且可以建立多个非聚集索引。

如果一个表中既要建立聚集索引,又要建立非聚集索引,应该先创建聚集索引,然后创建非聚集索引。
一般需要建立索引的情况:

  1. 主键和外键
  2. 检索频繁的字段
  3. 经常需要排序的字段

死锁

https://www.cnblogs.com/wezheng/p/8366029.html

增删改查,查询语句重点

  1. 增加
    insert into(可省略) 表名(列名) values(具体值)
    批量插入
    insert into(可省略) 表名(列名)
    values(值1) ,(值2)
  2. 删除
    Delete from(可省略) 表名 where<条件表达式> --删除数据会导致编号中断
    truncate table 表名 –清空表中数据,将表重置
  3. 修改
    update 数据表 set 字段名1=表达式1
    where<条件表达式>
  4. 查询
    Select top n * form 表名

创建表 id自增

create table tbname
(
id int identity(1,1) not null
)
id起始为1,步长为1。

数据库的设计过程

需求分析阶段,其成果是数据流图描述的处理需求和数据字典描述的数据需求;
概念设计阶段,其成果是E-R图表示的概念模型;
逻辑设计阶段,其成果是某个DBMS所支持的数据模型;
物理设计阶段,其成果是包括存储结构和存取方法的物理结构。

SQL优化

  1. 查询语句中不要使用 *
    查询出比你应用的功能实际需要过多的列,耗费时间和资源
  2. 尽量减少子查询,使用关联查询(left join, right join, inner join)替代
    因为子查询会先将子查询部分提取出来,然后将其与外部查询进行笛卡儿积,最后根据条件筛选,这样就导致多次遍历所有的数据(视你的子查询的层次而定),而连接查询只会遍历一次。
  3. 减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代
    https://www.cnblogs.com/emilyyoucan/p/7833769.html
    exists()适合内表比外表数据大的情况
    确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
    指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。
    --查询选修了课程代码为“110001”的学生的学号、姓名和班级代号
    Select studentcode, studentname, classcode
    From t_student
    Where studentcode in
    (select studentcode from t_grade where coursecode = ‘110001’)
    --使用exists表达相同的意思,效率高于in
    Select studentcode, studentname,classcode
    From t_student
    Where exists
    (select * from t_grade where t_student.studentcode = t_grade.studentcode and t_grade.coursecode = ‘110001’)
  4. or 的查询尽量用 union或者union all 代替
    (在确认没有重复数据或者不用剔除重复数据时,union all会更好)
  5. 合理的增加冗余的字段(减少表的联接查询)
  6. 增加中间表进行优化(这个主要是在统计报表的场景,后台开定时任务将数据先统计好,尽量不要在查询的时候去统计)
  7. 建表的时候能使用数字类型的字段就使用数字类型(type,status...),数字类型的字段作为条件查询比字符串的快
  8. 可以过滤掉最大数量记录的条件必须写在WHERE子句执行顺序的前面
    **mysql **从左到右 Oracle 从右到左
  9. 尽量在大小写上统一,避免在数据库软件进行大小写统一转换上耗费时间。

使用索引时有些不生效的情况

  1. 使用like关键字模糊查询时,% 放在前面索引不起作用,只有“%”不在第一个位置,索引才会生效(like '%文'--索引不起作用)
  2. 使用联合索引时,只有查询条件中使用了这些字段中的第一个字段,索引才会生效
  3. 使用OR关键字的查询,查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,索引才会生效,否则索引不生效。
  4. 尽量避免在where子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描。
  5. 对查询进行优化,应尽量避免全表扫描,首先应考虑在where以及order by涉及的列上建立索引。
  6. 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
      select id from t where num/2=100
      应改为:
      select id from t where num=100*2
  7. 尽量避免在where子句中对字段进行函数操作,将导致引擎放弃使用索引而进行全表扫描。
  8. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
  9. 并不是所有的索引对查询都有效,sql是根据表中的数据来进行查询优化的,当索引列有大量数据重复时,sql查询不会去利用索引,如一表中有字段
      sex,male,female几乎个一半,那么即使在sex上建立了索引也对查询效率起不了作用。
  10. 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,
      因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,
      若太多则应考虑一些不常使用到的列上建的索引是否有 必要。
  11. 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。
      这是因为引擎在处理查询和连接时会 逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
  12. mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。
       因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引。
  13. order by 索引 ,不起作用的问题(除了主键索引之外):
     如果select 只查询索引字段,order by 索引字段会用到索引,要不然就是全表排列;
     如果有where 条件,比如where vtype=1 order by vtype asc . 这样order by 也会用到索引

游标

https://www.cnblogs.com/knowledgesea/p/3699851.html

推荐阅读更多精彩内容