数据库专题

第十章 数据库专题

10.1. 如何获取当前数据库版本?

答:运行 SQL SERVER 服务管理器,在任务栏小托盘处,右键单击管理器图标,选“关于”,在弹出的窗口中,对照上面的信息即可获取。java

10.2. InnoDB 题

一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 MySQL 数据库,又插入了一条数据,此时 id 是几?
答:表类型若是是 MyISAM ,那 id 就是 8。
表类型若是是 InnoDB,那 id 就是 6。mysql

10.3. 序列的做用

Oracle 使用序列来生成惟一编号,用来处理一个表中自增字段。 Oracle 序列是原子对象,而且是一致的。也就是说,一旦您访问一个序列号,Oracle 将在处理下一个请求以前自动递增下一个编号,从而确保不会出现重复值。算法

10.4. 触发器的做用:

触发器是一中特殊的存储过程,主要是经过事件来触发而被执行的。它能够强化约束,来维护数据的完整性和一致性,能够跟踪数据库内的操做从而不容许未经许可的更新和变化。能够联级运算。如,某表上的触发器上包含对另外一个表的数据操做,而该操做又会致使该表触发器被触发。sql

10.5. 什么是存储过程?用什么来调用?

存储过程是一个预编译的 SQL 语句,优势是容许模块化的设计,就是说只需建立一次,之后在该程序中就能够调用屡次。若是某次操做须要执行屡次 SQL,使用存储过程比单纯SQL 语句执行要快。
调用:
1)能够用一个命令对象来调用存储过程。
2)能够供外部程序调用,好比:java 程序。数据库

10.6. 存储过程的优缺点?

优势:
存储过程是预编译过的,执行效率高。
存储过程的代码直接存放于数据库中,经过存储过程名直接调用,减小网络通信。
安全性高,执行存储过程须要有必定权限的用户。
存储过程能够重复使用,可减小数据库开发人员的工做量。
缺点:
移植性差编程

10.7. 存储过程与函数的区别

存储过程 函数用于在数据库中完成特定的操做或者任务(如插入、删除等)用于特定的数据(如选择)程序头部声明用 procedure 程序头部声明用 function程序头部声明时不需描述返回类型 程序头部声明时要描述返回类型,并且PL/SQL 块中至少要包括一个有效的return 语句可使用 in/out/in out 三种模式的参数可使用 in/out/in out 三种模式的参数可做为一个独立的 PL/SQL 语句来执行 不能独立执行,必须做为表达式的一部分调用能够经过 out/in out 返回零个或多个值经过 return 语句返回一个值,且改值要与声明部分一致,也能够是经过 out类型的参数带出的变量SQL 语句(DML或 SELECT)中不可调用存储过程SQL 语句(DML 或 SELECT)中能够调用函数数组

10.8. 索引的做用?和它的优势缺点是什么?

索引:索引就一种特殊的查询表,数据库的搜索能够利用它加速对数据的检索。
优势:它很相似与现实生活中书的目录,不须要查询整本书内容就能够找到想要的数据。索引能够是惟一的,建立索引容许指定单个列或者是多个列。
缺点:是它减慢了数据录入的速度,同时也增长了数据库的尺寸大小。安全

10.9. 什么样的字段适合建索引

惟1、不为空、常常被查询的字段服务器

10.10. 索引类型有哪些?

逻辑上:
1.Single column 单行索引
2.Concatenated 多行索
3.Unique 惟一索引
4.NonUnique 非惟一索引
5.Function-based 函数索引
6.Domain 域索引 物理上:
7.Partitioned 分区索引
8.NonPartitioned 非分区索引
9.tree :
Normal 正常型 B 树
Rever Key 反转型 B 树 Bitmap 位图索引网络

10.11. 什么是数据库事务?

答案:
单个逻辑单元执行的一系列操做,这些操做要么全作要么全不作,是不可分割的.事务的开始和结束用户是能够控制的,若是没控制则由数据库默认的划分事务.事务具备如下性质:
(1) 原子性:
指一个事务要么全执行,要么全不执行.也就是说一个事务不可能执行到一半就中止了.
(2) 一致性:
指事务的运行并不改变数据库中的一致性.好比 a+b=10;a 改变了,b 也应该随之改变.
(3) 独立性:- 63 -
两个以上的事务不会出现交替运行的状态,由于这样可能致使数据的不一致
(4) 持久性:
事务运行成功以后数据库的更新是永久的

10.12. SQL 中分别有几种事务?各有什么特色?:

答:4 种事务:
自动提交事务
隐式事务特色
显示事务
分布式事务
自动提交事务特色:每条单独语句都是一个事务。
隐式事务特色:前一个事务完成时新事务隐式启动,每一个事务仍以 COMMIT 或ROLLBACK 语句、显示结束。
显示事务特色:每一个事务均已 BEGIN TRANSACTION 语句显示开始,以 COMMIT 或ROLLBACK 语句显示结束。
分布式事务特色:跨越多个服务器的事务

10.13. 什么是回滚?

为了保证在应用程序、数据库或系统出现错误后,数据库可以被还原,以保证数据库的完整性 ,因此须要进行回滚。回滚(rollback)就是在事务提交以前将数据库数据恢复到事务修改以前数据库数据状态。

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

事务:
事务就是被绑定在一块儿做为一个逻辑工做单元的 SQL 语句分组,若是任何一个语句操做失败那么整个操做就被失败,之后操做就会回滚到操做前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可使用事务。要将有组语句做为事务考虑,就须要经过ACID 测试,即原子性,一致性,隔离性和持久性。
锁:
在全部的 DBMS 中,锁是实现事务的关键,锁能够保证事务的完整性和并发性。与现
实生活中锁同样,它可使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。
固然锁还分级别的。- 64 -

10.15. 什么是封锁?封锁的基本类型有哪几种?含义是什么?

封锁:
所谓封锁就是当一个事务在对某个数据对象(能够是数据项、记录、数据集、以致整个数据库)进行操做以前,必须得到相应的锁,以保证数据操做的正确性和一致性。
基本的封锁类型有两种:排它锁和共享锁
(1)排它锁:排它锁又称写锁,简称为 X 锁,其采用的原理是禁止并发操做。
(2)共享锁:共享锁又称读锁,,简称为 S 锁,其采用的原理是容许其余用户对同一数
据对象进行查询,但不能对该数据对象进行修改。

10.16. sql 数据库里锁是什么以及分类介绍

目前的 C/S,B/S 结构都是多用户访问数据库,每一个时间点会有成千上万个 user 来访问DB,其中也会同时存取同一份数据,会形成数据的不一致性或者读脏数据,数据库必须有锁的机制来确保数据的完整和一致性
6 种锁的类型:
(1) 共享锁:
共享锁用于全部的只读数据操做.
(2) 修改锁:
修改锁在修改操做的初始化阶段用来锁定可能要被修改的资源,这样能够避免使用共享
锁形成的死锁现象
(3) 独占锁:
独占锁是为修改数据而保留的。它所锁定的资源,其余事务不能读取也不能修改。独占
锁不能和其余锁兼容。
(4) 架构锁
结构锁分为结构修改锁(Sch-M)和结构稳定锁(Sch-S)。执行表定义语言操做时,
SQLServer 采用 Sch-M 锁,编译查询时,SQLServer 采用 Sch-S 锁。
(5) 意向锁
意向锁说明 SQL Server 有在资源的低层得到共享锁或独占锁的意向。
(6) 批量修改锁
批量复制数据时使用批量修改锁

10.17. 什么是死锁?产生死锁的必要条件。

1)在同时处于等待状态的两个或多个事务中,每一个事务都在等待其中另外一个事务解除封锁,它才能继续执行下去,结果形成任何一个事务都没法继续执行,这种状态称为死锁.
2)发生死锁的必要条件有如下四条:
(1)互斥条件:一个数据对象一次只能被一个事务所使用,即对数据的封锁采用排它式;
(2)不可抢占条件:一个数据对象只能被占有它的事务所释放,而不能被别的事务强行抢占
(3)互斥条件:一个数据对象一次只能被一个事务所使用,即对数据的封锁用排它式;
(4)不可抢占条件:一个数据对象只能被占有它的事务所释放,而不能被别的事务强行抢占

10.18. 什么叫视图?游标是什么?

视图:
是一种虚拟的表,具备和物理表相同的功能。能够对视图进行增,改,查,操做,试图一般是有一个表或者多个表的行或列的子集。对视图的修改会影响基本表。它使得咱们获取数据更容易,相比多表查询。
游标:
是对查询出来的结果集做为一个单元来有效的处理。游标能够定在该单元中的特定行,从结果集的当前行检索一行或多行。能够对结果集当前行作修改。通常不使用游标,可是须要逐条处理数据的时候,游标显得十分重要。

10.19. 使用游标的基本步骤有哪些?

  1. 声明游标
  2. 打开游标
  3. 读取游标中的数据
  4. 关闭游标
  5. 释放游标

10.20. 视图的优缺点

优势:
对数据库的访问,由于视图能够有选择性的选取数据库里的一部分。用户经过简单的查询能够从复杂查询中获得结果。维护数据的独立性,试图可从多个表检索数据。对于相同的数据可产生不一样的视图。
缺点:
性能:查询视图时,必须把视图的查询转化成对基本表的查询,若是这个视图是由一个复杂的多表查询所定义,那么,那么就没法更改数据。

10.21. 列举几种表链接方式,有什么区别?

内链接、自链接、外链接(左、右、全)、交叉链接
内链接:只有两个元素表相匹配的才能在结果集中显示。
外链接:左外链接:左边为驱动表,驱动表的数据所有显示,匹配表的不匹配的不会显示。
右外链接: 右边为驱动表,驱动表的数据所有显示,匹配表的不匹配的不会显示。
全外链接:链接的表中不匹配的数据所有会显示出来。
交叉链接: 笛卡尔效应,显示的结果是连接表数的乘积。

10.22. 主键和外键的区别?

1.主键在本表中是惟一的、不可惟空的。
2.外键能够重复能够惟空。
3.外键和另外一张表的主键关联,不能建立对应表中不存在的外键。

10.23. 在数据库中查询语句速度很慢,如何优化?

  1. 建索引
  2. 减小表之间的关联
  3. 优化 sql,尽可能让 sql 很快定位数据,不要让 sql 作全表查询,应该走索引,把数据 量大的表排在前面
  4. 简化查询字段,没用的字段不要,已经对返回结果的控制,尽可能返回少许数据
  5. 尽可能用 PreparedStatement 来查询,不要用 Statement

10.24. 数据库三范式是什么?

(1)第一范式(1NF):
所谓第一范式(1NF)是指在关系模型中,对于添加的一个规范要求,全部的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。
(2)第二范式(2NF):
在 1NF 的基础上,非码属性必须彻底依赖于候选码(在 1NF 基础上消除非主属性对主码的部分函数依赖)。
第二范式(2NF)是在第一范式(1NF)的基础上创建起来的,即知足第二范式(2NF)必须先知足第一范式(1NF)。第二范式(2NF)要求数据库表中的每一个实例或记录必须能够被惟一地区分。选取一个能区分每一个实体的属性或属性组,做为实体的惟一标识。
(3)第三范式(3NF):
第三范式(3NF)是第二范式(2NF)的一个子集,即知足第三范式(3NF)必须知足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。

10.25. union 和 union all 有什么不一样?

Union:
UNION 在进行表连接后会筛选掉重复的记录,因此在表连接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最多见的是过程表与历史表 UNION。
union all:
UNION ALL 只是简单的将两个结果合并后就返回。这样,若是返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。 从效率上说,UNION ALL 要比UNION 快不少,因此,若是能够确认合并的两个结果集中不包含重复的数据的话,那么就使用 UNION ALL。

10.26. CHAR 和 VARCHAR 的区别是什么?

答:
(1)CHAR 的长度是固定的,而 VARCHAR 的长度是能够变化的。
(2)CHAR 的效率比 VARCHAR 的效率稍高。
(3)目前 VARCHAR 是 VARCHAR 的同义词。

10.27. Varchar2 和 varchar 有什么区别?

Char 的长度是固定的,而 varchar2 的长度是能够变化的,好比,存储字符串“abc”对于 char(20),表示你存储的字符将占 20 个字节,包含 17 个空,而一样的 varchar2(20)只占了 3 个字节,20 只是最大值,当你存储的字符小于 20 时,按实际长度存储。 char 的效率要被 varchar2 的效率高。 目前 varchar 是 varchar2 的同义词,工业标准的 varchar类型能够存储空字符串,可是 oracle 不能这样作,尽管它保留之后这样作的权利。Oracle本身开发了一个数据类型 varchar2,这个类型不是一个标准的 varchar,他将在数据库中varchar 列能够存储空字符串的特性改成存储 null 值,若是你想有向后兼容的能力,oracle建议使用 varchar2 而不是 varchar

10.28. float 和 double 的区别是什么?

(1)范围
float 和 double 的范围是由指数的位数来决定的。
(2)精度
float 和 double 的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,因为它是不变的,故不能对精度形成影响。

10.29. Oracle 和 Mysql 的区别?

1)库函数不一样。
2)Oracle 是用表空间来管理的,Mysql 不是。
3)显示当前全部的表、用户、改变链接用户、显示当前链接用户、执行外部脚本的语句的不一样。
4)分页查询时候时候,mysql 用 limit oracle 用 rownum

10.30. sql 语句应该考虑哪些安全性?

(1)防止 sql 注入,对特殊字符进行转义,过滤或者使用预编译的 sql 语句绑定变量。
(2)最小权限原则,特别是不要用 root 帐户,为不一样的类型的动做或者组建使用不一样的帐户。
(3)当 sql 运行出错时,不要把数据库返回的错误信息所有显示给用户,以防止泄漏服务器和数据库相关信息。

10.31. 什么是内存泄漏?

答:通常咱们所说的内存泄漏指的是堆内存的泄漏。堆内存是程序从堆中为其分配的,大小任意的,使用完后要显示释放内存。当应用程序用关键字 new 等建立对象时,就从堆中为它分配一块内存,使用完后程序调用 free 或者 delete 释放该内存,不然就说该内存就不能被使用,咱们就说该内存被泄漏了。

10.32. Delete、truncate、drop 都是删除语句,它们有什么分别?

  1. delete 属于 DML 语句,删除数据,保留表结构,须要 commit,能够回滚,若是数据量大,很慢。
  2. truncate 属于 DDL 语句,删除全部数据,保留表结构,自动 commit,不能够回滚,一次所有删除全部数据,速度相对较快。
  3. Drop 属于 DDL 语句,删除数据和表结构,不须要 commit,删除速度最快。

10.33. order by 和 groupby 的区别

order by: 排序查询、asc 升序、desc 降序
group by:分组查询、having 只能用于 groupby 子句、做用于组内,having 条件子句能够直接跟函数表达式。使用 group by 子句的查询语句须要使用聚合函数。

10.34. 何谓悲观锁与乐观锁

乐观锁对应于生活中乐观的人老是想着事情往好的方向发展,悲观锁对应于生活中悲观的人老是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另一种人。
悲观锁
老是假设最坏的状况,每次去拿数据的时候都认为别人会修改,因此每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资 源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了不少这种锁机制,好比行锁,表锁 等,读锁,写锁等,都是在作操做以前先上锁。Java中 synchronized 和 ReentrantLock 等独占锁就是悲观锁思想的实现。
乐观锁
老是假设最好的状况,每次去拿数据的时候都认为别人不会修改,因此不会上锁,可是在更新的时候会判断一下在此期间别人有没有去更新这个数据,能够 使用版本号机制和CAS 算法实现。乐观锁适用于多读的应用类型,这样能够提 高吞吐量,像数据库提供的相似于 write_condition 机制,其实都是提供的乐 观锁。在 Java 中java.util.concurrent.atomic 包下面的原子变量类就是使用了 乐观锁的一种实现方式 CAS实现的。
两种锁的使用场景
从上面对两种锁的介绍,咱们知道两种锁各有优缺点,不可认为一种好于另外一 种,像乐观锁适用于写比较少的状况下(多读场景),即冲突真的不多发生的 时候,这样能够省去了锁的开销,加大了系统的整个吞吐量。但若是是多写的 状况,通常会常常产生冲突,这就会致使上层应用会不断的进行 retry,这样反 却是下降了性能,因此通常多写的场景下用悲观锁就比较合适。
乐观锁常见的两种实现方式
乐观锁通常会使用版本号机制或 CAS 算法实现。
版本号机制
通常是在数据表中加上一个数据版本号 version 字段,表示数据被修改的次 数,当数据被修改时,version 值会加一。当线程 A 要更新数据值时,在读取数 据的同时也会读取version 值,在提交更新时,若刚才读取到的 version 值为当 前数据库中的 version 值相等时才更新,不然重试更新操做,直到更新成功。
举一个简单的例子:假设数据库中账户信息表中有一个 version 字段,当前值 为 1 ;
而当前账户余额字段( balance )为 $100 。

  1. 操做员 A 此时将其读出( version=1 ),并从其账户余额中扣除 $50

( $100-$50 )。

  1. 在操做员 A 操做的过程当中,操做员 B 也读入此用户信息( version=1 ),并从

其账户余额中扣除 $20 ( $100-$20 )。

  1. 操做员 A 完成了修改工做,将数据版本号加一( version=2 ),连同账户扣除后余额( balance=$50 ),提交至数据库更新,此时因为提 交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。
  2. 操做员 B 完成了操做,也将版本号加一( version=2 )试图向数据库 提交数据( balance=$80 ),但此时比对数据库记录版本时发现,操 做员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不满 足 “ 提交版本必须大于记录当前版本才能执行更新 “ 的乐观锁策略, 所以,操做员 B 的提交被驳回。这样,就避免了操做员 B 用基于 version=1 的旧数据修改的结果覆盖操做员 A 的操做结果的可能。
  3. CAS 算法

即 compare and swap(比较与交换),是一种有名的无锁算法。无锁编程, 即不使用锁的状况下实现多线程之间的变量同步,也就是在没有线程被阻塞的 状况下实现变量的同步,因此也叫非阻塞同步(Non-blocking Synchronization)。CAS 算法涉及到三个操做数须要读写的内存值 V进行比较的值 A拟写入的新值 B当且仅当 V 的值等于 A 时,CAS 经过原子方式用新值 B 来更新 V 的值,不然不会执行任何操做(比较和替换是一个原子操做)。通常状况下是一个自旋操做,即不断的重试。
乐观锁的缺点
ABA 问题是乐观锁一个常见的问题
1 ABA 问题
若是一个变量 V 初次读取的时候是 A 值,而且在准备赋值的时候检查到它仍然 是 A 值,那咱们就能说明它的值没有被其余线程修改过了吗?很明显是不能的,由于在这段时间它的值可能被改成其余值,而后又改回 A,那 CAS 操做就 会误认为它历来没有被修改过。这个问题被称为 CAS 操做的 "ABA"问题。
JDK 1.5 之后的 AtomicStampedReference 类就提供了此种能力,其中的compareAndSet 方法就是首先检查当前引用是否等于预期引用,而且当前标志是 否等于预期标志,若是所有相等,则以原子方式将该引用和该标志的值设置为 给定的更新值。
2 循环时间长开销大
自旋 CAS(也就是不成功就一直循环执行直到成功)若是长时间不成功,会给 CPU 带来很是大的执行开销。 若是 JVM 能支持处理器提供的 pause 指令那么 效率会有必定的提高,pause 指令有两个做用,第一它能够延迟流水线执行指 令(de-pipeline),使 CPU 不
会消耗过多的执行资源,延迟的时间取决于具体 实现的版本,在一些处理器上延迟时间是零。第二它能够避免在退出循环的时 候因内存顺序冲突(memory order violation)而引发 CPU 流水线被清空 (CPU pipeline flush),从而提升 CPU 的执行效率。
3 只能保证一个共享变量的原子操做
CAS 只对单个共享变量有效,当操做涉及跨多个共享变量时 CAS 无效。可是 从 JDK1.5 开始,提供了 AtomicReference 类来保证引用对象之间的原子性,你 能够把多个变量放在一个对象里来进行 CAS 操做.因此咱们可使用锁或者利 用 AtomicReference类把多个共享变量合并成一个共享变量来操做。CAS 与 synchronized 的使用情景
简单的来讲 CAS 适用于写比较少的状况下(多读场景,冲突通常较少),synchronized适用于写比较多的状况下(多写场景,冲突通常较多)
1.对于资源竞争较少(线程冲突较轻)的状况,使用 synchronized 同步锁 进行线程阻塞和唤醒切换以及用户态内核态间的切换操做额外浪费消耗 cpu 资源;而 CAS 基于硬件实现,不须要进入内核,不须要切换线程, 操做自旋概率较少,所以能够得到更高的性能。

  1. 对于资源竞争严重(线程冲突严重)的状况,CAS 自旋的几率会比较 大,从而浪费更多的 CPU 资源,效率低于 synchronized。

补充: Java 并发编程这个领域中 synchronized 关键字一直都是元老级的角 色,好久以前不少人都会称它为 “重量级锁” 。可是,在 JavaSE 1.6 以后进行了 主要包括为了减小得到锁和释放锁带来的性能消耗而引入的 偏向锁 和 轻量级 锁 以及其它各类优化以后变得在某些状况下并非那

相关文章
相关标签/搜索