zoukankan      html  css  js  c++  java
  • 面试准备——(二)专业知识(6)数据库

     羽中总结;

    索引 --》b树、b+树的区别
    事务的隔离级别和对应解决的几种问题,mysql的默认事务隔离级别
    手写sql语句(招银网络)(列出平均分大于80分的学生的信息 )
    数据库范式
    sql语句的执行顺序
    如何对一行数据数据加锁
    left join ,inner join

    1. 索引

    索引是一种数据结构,对数据库表中的一或多列的值进行排序,是为了帮助MYSQL高效获取数据

    优点:

    1. 大大加快了数据的检索速度
    2. 保证了数据的唯一性
    3. 加速了表与表之间的联系
    4. 在使用order by、group by子句进行数据索引的时候,可以显著减少时间

    缺点:

    1. 索引需要占用物理内存
    2. 如果修改、增加、删除表中数据,索引也要动态维护。

    索引的类型:

    根据索引的功能,可以将索引划分为四类:普通索引、唯一索引、主键索引、聚集索引

    2. 使用索引查询一定能提高查询的性能吗?为什么

    不一定。通常通过索引查询数据比全表扫描要快,但是因为索引需要空间来存储,也需要动态维护,这意味着增、添、改三个操作会为此多付出4、5次I/O操作。所以,不必要的索引反而会时查询速度变慢。对于索引范围查询适用于两种情况:

    1. 基于一个范围的检索,一般查询返回结果集<表中记录数的30%
    2. 基于非唯一性索引

    3. B树、B+树的区别

    1. 相关术语:

    结点的度(阶):含有子树的个数

    树的度:所有结点最大的度

    结点的层次/深度从根节点开始,根为第一层,根的子结点为第二层,以此类推。

    树的深度:一棵树中所有结点的层次的最大值。

    结点的高度从叶子结点开始,叶子结点作为1, 自底向上累加的

    虽然结点的深度可能相同,但是它的高度不一定相同

    2. B树

    B树是平衡多路查找树,主要用于文件系统的索引。

    1)定义对于一个度数为d的B树,

      1. 每个结点最多有d个孩子
      2. 如果根结点不是叶子结点,那它至少有两个孩子
      3. 每个非叶子结点(非根结点)孩子:⎡d/2⎤<=n<=d
      4. 每个非叶子结点含有

    n个关键字信息和n+1个指向孩子的指针

      ,[n, p0, k1, p1, k2,p2,...,kn,pn]:
      1. ki(i=1,...n)为关键字,且按升序排列,即:k(i-1)<k(i)
      2. pi(i=0,...,n)为指向子树根的指针,且p(i-1)指向子树中所有的关键字均小于k(i),都大于k(i-1)
    1. 每个叶子结点都在同一层,并且不包含任何关键字信息

    例如:这是一个3阶B树,

     2)B树结点的代码实现

    #define MAX 10  /*定义B树的最大阶数为10*/
    typdef int KeyType   /*KeyType为关键字类型*/
    typedef struct BTNode{
        int keynum;      /*当前结点拥有的关键字数目*/
        KeyType key[keynum+1];   /*key[0]不用,有keynum个关键字*/
    
        struct BTNode *parent;
        struct BTNode *child[keynum+1]; /*孩子结点的指针:child[0, 1, ...., keynum]*/
         
    }

    3)B树的复杂度和高度

    对于一个含有n个关键字,d阶B树,它的高度h<=log⎡d/2⎤((n+1)/2)+1

    1.  根为1个结点,他至少有两个孩子,也就是第二层至少有2个结点,
    2. 其余非叶子结点,至少有:⎡d/2⎤个结点,因此第三层至少有:2*⎡d/2⎤
    3. 以此类推:第四层至少有:2*⎡d/2⎤2 、第五层至少有:2*⎡d/2⎤3,...,第l层至少有:2*⎡d/2⎤l-2个结点

    所以:

    1+2+2*⎡d/2⎤+...+2*⎡d/2h-2 <=n
    
    =>1+2*(1-2*⎡d/2h-1)/(1-⎡d/2⎤)<=n
    
    =>1+2*(⎡d/2⎤-1)(2*⎡d/2h-1-1)/(⎡d/2⎤-1)<=n  因为d>2
    
    =>h<=log⎡d/2⎤((n+1)/2)+1

     4)检索一个key,其查找结点个数的复杂度:O(logd(N))

    3. B+树

    与B树的不同之处:

    1)内结点不存储数据,只存储指针看做索引的一部分,结点中含有其子树根结点中最大(最小)关键字——B树的内结点包含了部分关键字信息

    2)叶子结点包含了全部关键字信息,及指向含有这些关键字记录的指针,且叶子结点本身按照关键字从小到大的顺序链接。

    通常在B+树上有两个头指针,一个指向根节点,一个指向关键字最小的叶子结点。

    B树的查找过程:

    其中,浅蓝色的是磁盘块,其中存放了数据项和指针;例如:磁盘1包含了数据项:17,35,但是只是作为索引,而不是真的关键字,所有的关键字都包含在叶子结点

    例如:要查找29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO

    B+树特性:
    1. 内结点存放索引,关键字都存放在叶子结点。——每个磁盘盘存放数据量更多——减少IO次数

    因为IO次数取决于B+树的高度h,假设当前数据表的数据为N,每个磁盘块的数据项的数量是m,则h=logm+1N。

    2. 最左匹配原则。

    当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;但当(20,F)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是F的数据了, 这个是非常重要的性质,即索引的最左匹配特性。

      

    4. 事务,事务的隔离级别和对应解决的几种方法,MySql的默认事务隔离级别

    1. 事务:是指作为单个逻辑工作单元执行的一系列操作,要么完全执行,要么完全不执行,是一个不可分隔的工作单位。事务是数据库系统维护数据一致性的单位,在每个事务结束时,都能保持数据的一致性。

    事务的四个特性:ACID

    • 原子性:是指事务所包含的操作要么全部成功,要么全部失败回滚
    • 一致性事务执行之前和执行之后都是一致性状态
    • 隔离性:多个并发事务相互隔离
    • 持久性:一旦一个事务提交了,那么对数据库中的数据修改是持久的

     2. 事务的隔离性:
    多个线程都开启事务操作数据库中的数据时,数据库系统要进行隔离操作,以保证各个线程获取数据的准确性。如果不考虑隔离性,会产生三个问题

    1)脏读:指在一个事务处理过程中读取了另一个未提交事务中的数据

    2)不可重复读:对于数据库中某个数据,一个事务范围内多次查询却得到了不同的数据值,也就是在查询间隔,另一个事务提交了。(读取了前一个事务提交的数据

    3)幻读(虚读):幻读是事务非独立执行时发生的现象。

    例如:事务T1对一个表中所有的行的某个数据项做了从“1”到“2”的更改,这时事务T2插入了一行,T1 就会发现还有一行没有修改。

    幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

    3. MySQL数据库为我们提供的四种隔离级别

      ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。——级别最高,执行效率最低

      ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。(MYSQL中默认)

      ③ Read committed (读已提交):可避免脏读的发生。

      ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。——级别最低,效率最高

    另外:隔离级别的设置只对当前链接有效

    • 对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;
    • 对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

    5. 数据库的乐观锁和悲观锁是什么?

    数据库管理系统中的并发控制,是确保在多个事务同时存取数据库中的同一数据时,不会破坏事务的隔离性以及数据库的统一性。

    乐观锁和悲观锁时并发控制中主要采用的技术手段。

    乐观锁:假设不会发生并发冲突,只是在提交时检查是否违反数据的完整性

    悲观锁:假设会发生并发冲突,屏蔽一切可能违反数据库完整性的操作。

     

    6. 数据库中的超键、候选键、主键、外键

    超键:在关系中能唯一标识元组的属性集

    候选键:能唯一的标志每个实体的属性或者属性组。(不含有多余属性的超键 

    主键:在实体集中区分不同实体的候选码,一个实体集只能有一个主键,但是能有多个候选码。

    外键:一个属性同时存在在表1和表2找那个,他不是表1的主键,是表2的主键,则可以称它是表1的外健键

    例如,假设有如下两个表:
    学生(学号,姓名,性别,身份证号,教师编号)
    教师(教师编号,姓名,工资)

    1. 超键:在学生表中,任何包含了学号、身份证号的属性集,都称作“超键”;任何包含了“教师编号”的属性集都称为“超键”

    2. 候选键属于超键,它是最小的超键,就是说如果再去掉候选键中的任何一个属性它就不再是超键了。学生表中的候选键为:(学号)、(身份证号)。

    3. 主键:从候选键中选择一个。例如:学号

    4. 外键:教师编号在学生表中不是主键,但是在教师表中是主键,所以教师编号是外键。

    7. 数据库的范式

    范式:设计关系数据库的规范,越高的范式,数据库冗余度越小

    1. 第一范式1NF:所有关系数据库都满足

    数据库表中的字段都是单一属性不可分割

    2. 第二范式2NF:——必须满足1NF

    在1NF基础上,要求实体的属性完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖

    3. 第三范式3NF——是2NF子集,必须满足2NF

    在1NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

    第三范式(3NF)要求一个关系中不包含已在其它关系中包含的非主关键字信息

    例如:存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。

    4. 巴斯-科德范式(BCNF)——是对3NF的修改

    在1NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)

    举例:

    1. 1NF:设计学生信息表:(学号,学生姓名、年龄、性别、课程、课程学分、系别、学科成绩,系办地址、系办电话)

    2. 2NF:

    原则:任何非主属性完全依赖于候选码。

    最初的学生信息表,存在依赖:(学号,课程)——>(学生姓名,年龄,课程,系别)

    因此不满足第二范式的要求,会产生如下问题:
    1) 数据冗余:同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
    2)更新异常:

    1. 若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。
    2. 假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。

    3)删除异常 :假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。

    所以将表拆分为三个表:

    1. 学生:Student(学号,姓名,年龄,性别,系别,系办地址、系办电话);
    2. 课程:Course(课程名称,学分);
    3. 选课关系:SelectCourse(学号,课程名称,成绩)。

    3. 3NF

    原则:消除2NF上的传递依赖

    接着看上面的学生表Student(学号,姓名,年龄,性别,系别,系办地址、系办电话),关键字为单一关键字"学号",因为存在如下决定关系:
    (学号)→ (姓名,年龄,性别,系别,系办地址、系办电话
    但是还存在下面的决定关系:
    (学号) → (系别)→(系办地点,系办电话)
    存在非关键字段"系办地点"、"系办电话"对关键字段"学号"的传递函数依赖
    它也会存在数据冗余、更新异常、插入异常和删除异常的情况。
    根据第三范式把学生关系表分为如下两个表就可以满足第三范式了:
    学生:(学号,姓名,年龄,性别,系别);
    系别:(系别,系办地址、系办电话)。
    上面的数据库表就是符合I,Ⅱ,Ⅲ范式的,消除了数据冗余、更新异常、插入异常和删除异常。

    8. SQL语句中:drop、delete、truncate

    三个都是表示删除:

    • 定义:drop和truncate表示删除表格的结构,delete是删除数据
    • 速度:一般来说:drop>truncate>delete
    • SQL语句类型:deletedml数据操控语言,这个操作会放在rollback segment事务提交以后才生效。如果有相应的触发器,执行的时候被触发;drop和truncateddl数据定义语言,操作立即生效,不会放在rollback segment,无法回滚,操作不触发触发器trigger。

    drop

    9.drop、delete与truncate分别在什么场景之下使用?

    • drop:不再需要一张表的时候:比如删除一个索引:alter table drop index index_name
    • truncate:保留表,只删除其中的数据
    • delete:删除部分数据,加上where子句

     

    10. 什么是视图?以及视图的使用场景

    视图:是一张虚拟的表,通常是一个表或者多个表的行或列的子集,具有和物理表相同的功能。可以对视图进行增添查改,但是不会影响基本表,它使得我们获取数据更容易,相比于多表查询

    适用场景:

    • 只暴露部分数据给访问者,并且访问者的操作不会影响基本表数据
    • 查询的数据来源于多个表,而查询者希望以统一的方式查询,建立一个视图,不必考虑数据来源于不同表的差异。

     

    11. SQL语句的执行顺序

     每个步骤都会产生一张虚拟表,该虚拟表作为下一步的输入。但是这些虚拟表队对调用者都是不可用的,直到最后一步才会返回给调用者。

    (8)SELECT (9)DISTINCT  (11)<Top Num> <select list>
    (1)FROM [left_table]
    (3)<join_type> JOIN <right_table>
    (2)ON <join_condition>
    (4)WHERE <where_condition>
    (5)GROUP BY <group_by_list>
    (6)WITH <CUBE | RollUP>
    (7)HAVING <having_condition>
    (10)ORDER BY <order_by_list>

    逻辑查询处理阶段:

    1. FROM:对FROM中的前两个表执行笛卡尔积(交叉联接)生成虚拟表VT1

    2. ON:对VT1应用筛选器。只用对<join condition>为真的才能被插入VT2

    3. OUTER(JOIN)

    • left join:把左表作为保留表
    • right join:把右表作为保留表
    • full join:两个表都是保留
    • inner join:至少又一个匹配才返回

    把在保留表中未找到匹配的行将作为外部行插入到VT2中,生成VT3。

    如果FROM中含有两个以上的表,则则对上一个联接生成的结果表和下一个表重复执行1~3操作,直到处理完所有的表。

    4. WHERE:对VT3应用WHERE筛选器,只有使<where_condition>为true的行才被插入VT4。

    5. GROUP BY:按GROUP BY子句中的列表对VT4行进行分组,生成VT5

    6. CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6。

    7. HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.

    8. SELECT:处理SELECT列表生成VT8

    9. DISTINCT:将重复咧从VT8中移除,生成VT9

    10. ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).

    11. TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。

    12. 比较 inner join、left join、right join

     

     

    14. MyISAM和InnoDB

     1. MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。

    2. InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。


    15. 什么是存储过程?有哪些优缺点?

    存储过程就是一些预编译的T-SQL语句组成的代码块,这个代码块像一个方法一样实现一些功能(对单表的增添改查),给它一个名字,需要时调用它就行了。

    优点:

    1. 由于数据库启动时,是先编译后执行。然而存储过程是一个编译过的代码段,所以执行效率高
    2. 网络交互时可以代替大量的T-SQl语句,所以也能降低网络的通信量,提高通信速率
    3. 通过存储过程能够使没有权限的用户在控制之下间接地存取数据库,从而确保数据的安全

    16. 手写SQL语句

  • 相关阅读:
    机器学习中的距离度量
    ubuntu 安装JDK
    pandas 代码
    pandas 常用统计方法
    python内置函数map/reduce/filter
    详解SQL Server连接(内连接、外连接、交叉连接)
    什么是SAD,SAE,SATD,SSD,SSE,MAD,MAE,MSD,MSE?
    数据挖掘算法源代码:很好的参考资料
    python linecache模块读取文件用法详解
    python读取文件指定行
  • 原文地址:https://www.cnblogs.com/lesleysbw/p/6472598.html
Copyright © 2011-2022 走看看