Java 面试题之数据库

数据库基础

1. 数据抽象:物理抽象、概念抽象、视图级抽象,内模式、模式、外模式

数据库系统三级抽象是指:

  • 视图级抽象:把现实世界抽象为数据库的外模式;把现实世界中的信息按照不同用户的观点抽象为多个逻辑数据结构,每个逻辑结构称为一个视图,描述了每个用户关心的数据,即数据库的一个侧面。所有视图的集合形成了数据库的外模式。
  • 概念级抽象:把数据库外模式抽象为数据库的概念模式。将外模式所有视图综合为数据库整体逻辑结构,这就是数据库概念模式,即全体用户关心的现实抽象。
  • 物理级抽象:把数据库概念模式抽象为数据库的内模式。

三种数据库模式:外模式、概念模式和内模式:

(1)模式

定义:也称逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图。

理解:

① 一个数据库只有一个模式;

② 是数据库数据在逻辑级上的视图;

③ 数据库模式以某一种数据模型为基础;

④ 定义模式时不仅要定义数据的逻辑结构(如数据记录由哪些数据项构成,数据项的名字、类型、取值范围等),而且要定义与数据有关的安全性、完整性要求,定义这些数据之间的联系。

(2)外模式(External Schema)

定义:也称子模式(Subschema)或用户模式,是数据库用户(包括应用程序员和最终用户)能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。

理解:

① 一个数据库可以有多个外模式;

② 外模式就是用户视图;

③ 外模式是保证数据安全性的一个有力措施。

(3)内模式(Internal Schema)

定义:也称存储模式(Storage Schema),它是数据物理结构和存储方式的描述,是数据在数据库内部的表示方式(例如,记录的存储方式是顺序存储、按照B树结构存储还是按hash方法存储;索引按照什么方式组织;数据是否压缩存储,是否加密;数据的存储记录结构有何规定)。

理解:

① 一个数据库只有一个内模式;

② 一个表可能由多个文件组成,如:数据文件、索引文件。

它是数据库管理系统(DBMS)对数据库中数据进行有效组织和管理的方法

其目的有:

① 为了减少数据冗余,实现数据共享;

② 为了提高存取效率,改善性能。

具体请看:http://www.2cto.com/database/201412/360263.html

2. SQL语言包括数据定义、数据操纵(Data Manipulation),数据控制(Data Control)

  • 数据定义:Create Table, Alter Table, Drop Table, Craete/Drop Index等
  • 数据操纵:Select, insert, update, delete
  • 数据控制:grant, revoke

3. SQL常用命令:

CREATE TABLE Student(

ID NUMBER PRIMARY KEY,

NAME VARCHAR2(50) NOT NULL);//建表

CREATE VIEW view_name AS

Select * FROM Table_name;//建视图

Create UNIQUE INDEX index_name ON TableName(col_name);//建索引

INSERT INTO tablename {column1,column2,…} values(exp1,exp2,…);//插入

INSERT INTO Viewname {column1,column2,…} values(exp1,exp2,…);//插入视图实际影响表

UPDATE tablename SET name=’zang 3’ condition;//更新数据

DELETE FROM Tablename WHERE condition;//删除

GRANT (Select,delete,…) ON (对象) TO USER_NAME [WITH GRANT OPTION];//授权

REVOKE (权限表) ON(对象) FROM USER_NAME [WITH REVOKE OPTION] //撤权

列出工作人员及其领导的名字:

Select E.NAME, S.NAME FROM EMPLOYEE E S

WHERE E.SUPERName=S.Name

4. 视图

视图(View)是从一个或多个表(或视图)导出的表。视图与表(有时为与视图区别,也称表为基本表——Base Table)不同,视图是一个虚表,即视图所对应的数据不进行实际存储,数据库中只存储视图的定义,在对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表。

数据库存储数据是通过表来实现的,其有物理存储空间,也是你数据真正存储的地方。可以通过对表的操作来实现你对数据的操作。

视图其实是物理不存在的,其是通过数据库代码来将一些表中的数据进行一个想要的逻辑结构重新进行整理。可能这样说有点更迷糊。

视图没有新建表,只是把原来表中的数据成员通过数据库语言按照我们需要的逻辑结构重新组织,而进行操作的时候跟一个表是一样的。

具体请看:http://www.w3school.com.cn/sql/sql_view.asp

5. 完整性约束:实体完整性、参照完整性、用户定义完整性

关系模型中可以有三类完整性约束:实体完整性、参照完整性和用户定义的完整性。实体完整性规则定义了对关系中主属性(主键)取值的约束,即对主属性的值域的约束;而参照完整性规则定义了参照关系和被参照关系的外码与主码之间的参照约束,即对参照关系的外码属性值域的约束,规定外码属性的值域只能是空值或是相应被参照关系主码属性的值。用户定义完整性就是针对某一具体的关系数据库的约束条件,反映某一具体应用所涉及的数据必须满足的语义要求,由应用的环境决定。例如,银行的用户帐户规定必须大于等于100000,小于999999。所以,用户定义的完整性通常是定义对关系中除主键与外键属性之外的其他属性取值的约束,即对其他属性的值域的约束。

实体完整性约束规则是指:若属性(指一个或一组属性)A 是基本关系 R 的主属性,则 A 不能取空值。所谓空值就是“不知道”或“不存在”的值。

实体完整性规则说明如下:

  • (1)实体完整性规则是针对基本关系而言的。一个基本表通常对应现实世界的一个实体集。
  • (2)现实世界中的实体是可区分的,即它们具有某种唯一的标识。
  • (3)相应地,关系模型中以主码作为唯一性标识。
  • (4)主码中的属性即主属性不能取空值。如果主属性取空值,就说明存在某个不可标识的实体,即存在不可区分的实体,这与(2)点相矛盾,因此这个规则称为实体完整性。

用户自定义完整性约束:

不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户自定义的完整性就是针对某一具体关系数据库的约束条件。它反映某一具体应用所涉及的数据必须满足的语义要求。

6. 第三范式

  • 1NF:每个属性是不可分的。强调的是列的原子性,即列不能够再分成其他几列。
  • 2NF:若关系R是1NF,且每个非主属性都完全函数依赖于R的键。例SLC(SID#, CourceID#, SNAME,Grade),则不是2NF; 首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
  • 3NF:若R是2NF,且它的任何非键属性都不传递依赖于任何候选键。首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。

7. ER(实体/联系)模型

  • 定义:ER模型又称实体联系模型(Entity-Relationship).是设计数据库的一个重要分析模型。
  • 实体:是一个数据集对象,或数据集(上篇博客数据结构导论里有介绍)。应用中可以区别的客观存在的事物。实体可以是一个人、文件、课程,它是具有自己属性、一组有意义的数据组成的一个集合体。
  • 联系:实体不是孤立的,实体之间是有联系的。例如学生和课程之间具有交叉属性,即分数;A实体和B实体之间交互产生的数据就是它们的属性。

8. 索引作用

为什么要创建索引呢?这是因为,创建索引可以大大提高系统的性能。

  • 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  • 第二,可以大大加快 数据的检索速度,这也是创建索引的最主要的原因。
  • 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
  • 第四,在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
  • 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。虽然,索引有许多优点, 但是,为表中的每一个列都增加索引,是非常不明智的。这是因为,增加索引也有许多不利的一个方面。

  • 第一,创建索引和维护索引要耗费时间,这种时间随着数据 量的增加而增加。
  • 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
  • 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

具体请看:

9. 事务

事务是一系列的数据库操作,是数据库应用的基本逻辑单位。 事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

  • ①原子性(Atomicity):事务中的所有元素作为一个整体提交或回滚,事务的个元素是不可分的,事务是一个完整操作。
  • ②一致性(Consistemcy):事物完成时,数据必须是一致的,也就是说,和事物开始之前,数据存储中的数据处于一致状态。保证数据的无损。
  • ③隔离性(Isolation):对数据进行修改的多个事务是彼此隔离的。这表明事务必须是独立的,不应该以任何方式以来于或影响其他事务。
  • ④持久性(Durability):事务完成之后,它对于系统的影响是永久的,该修改即使出现系统故障也将一直保留,真实的修改了数据库

10. 锁:共享锁、互斥锁

  • 共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁,直到已释放所有共享锁。获准共享锁的事务只能读数据,不能修改数据。
  • 排他锁(X锁):如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的锁,直到在事务的末尾将资源上的锁释放为止。获准排他锁的事务既能读数据,又能修改数据。

两段锁协议:阶段1:加锁阶段 阶段2:解锁阶段

具体请看:http://www.cnblogs.com/ggjucheng/archive/2012/11/14/2770445.html

11. 死锁及处理:事务循环等待数据锁,则会死锁。

  • ①死锁预防利用死锁预防协议,通过破坏死锁产生的必要条件来避免系统进入死锁状态,防止死锁发生。
  • ②死锁检测与恢复则是允许系统进入死锁状态,并且定期检查系统是否发生死锁。当发现系统发生死锁后,采取相应的恢复机制使系统摆脱死锁状态。

12. 存储过程:存储过程就是编译好了的一些sql语句。

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

存储过程与函数的区别:

  • 一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
  • 对于存储过程来说可以返回参数(output),而函数只能返回值或者表对象。
  • 存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。

存储过程的优点:

  • 存储过程的能力大大增强了SQL语言的功能和灵活性。
  • 可保证数据的安全性和完整性。
  • 通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。
  • 通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。
  • 在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。即存储过程在被编译后会被直接保存在数据库中,成为数据库的一部分,以后就可以反复调用,运行速度快,效率高
  • 可以降低网络的通信量。存储过程主要是在服务器上运行,减少对客户机的压力。
  • 使体现企业规则的运算程序放入数据库服务器中,以便 集中控制。
  • 存储过程可以分为系统存储过程、扩展存储过程和用户自定义的存储过程
  • 可保证数据的安全性和完整性。通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。
  • 存储过程可以接受参数、输出参数、返回单个或多个结果集以及返回值。可以向程序返回错误原因* 存储过程可以包含程序流、逻辑以及对数据库的查询。同时可以实体封装和隐藏了数据逻辑。

13. 触发器: 当满足触发器条件,则系统自动执行触发器的触发体。

触发时间:有 before,after。触发事件:有 insert,update,delete 三种。触发类型:有行触发、语句触发

14. 内联接,外联接区别?

内连接是保证两个表中所有的行都要满足连接条件,而外连接则不然。

在外连接中,某些不满条件的列也会显示出来,也就是说,只限制其中一个表的行,而不限制另一个表的行。分左连接、右连接、全连接三种

15. 存储过程和函数的区别

存储过程是用户定义的一系列sql语句的集合,涉及特定表或其它对象的任务,用户可以调用存储过程,而函数通常是数据库已定义的方法,它接收参数并返回某种类型的值并且不涉及特定用户表。

16. 事务是什么?

事务是作为一个逻辑单元执行的一系列操作,一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务:
原子性事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。
一致性事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。
隔离性由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。
持久性事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。

17. 游标的作用?如何知道游标已经到了最后?

游标用于定位结果集的行,通过判断全局变量@@FETCH_STATUS可以判断是否到了最后,通常此变量不等于0表示出错或到了最后。

18. 触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何区别。

事前触发器运行于触发事件发生之前,而事后触发器运行于触发事件发生之后。通常事前触发器可以获取事件之前和新的字段值。
语句级触发器可以在语句执行前或后执行,而行级触发在触发器所影响的每一行触发一次。

数据库MySql

1. MySql的存储引擎的不同

MySQL 中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。

  • MyISAM:这种引擎是mysql最早提供的。这种引擎又可以分为静态MyISAM、动态MyISAM 和压缩MyISAM三种:
    • 静态MyISAM:如果数据表中的各数据列的长度都是预先固定好的,服务器将自动选择这种表类型。因为数据表中每一条记录所占用的空间都是一样的,所以这种表存取和更新的效率非常高。当数据受损时,恢复工作也比较容易做。
    • 动态MyISAM:如果数据表中出现varchar、xxxtext或xxxBLOB字段时,服务器将自动选择这种表类型。相对于静态MyISAM,这种表存储空间比较小,但由于每条记录的长度不一,所以多次修改数据后,数据表中的数据就可能离散的存储在内存中,进而导致执行效率下降。同时,内存中也可能会出现很多碎片。因此,这种类型的表要经常用optimize table 命令或优化工具来进行碎片整理。
    • 压缩MyISAM:以上说到的两种类型的表都可以用myisamchk工具压缩。这种类型的表进一步减小了占用的存储,但是这种表压缩之后不能再被修改。另外,因为是压缩数据,所以这种表在读取的时候要先时行解压缩。
      但是,不管是何种MyISAM表,目前它都不支持事务,行级锁和外键约束的功能。
  • MyISAM Merge引擎:这种类型是MyISAM类型的一种变种。合并表是将几个相同的MyISAM表合并为一个虚表。常应用于日志和数据仓库。
  • InnoDB:InnoDB表类型可以看作是对MyISAM的进一步更新产品,它提供了事务、行级锁机制和外键约束的功能。
  • memory(heap):这种类型的数据表只存在于内存中。它使用散列索引,所以数据的存取速度非常快。因为是存在于内存中,所以这种类型常应用于临时表中。
  • archive:这种类型只支持select 和 insert语句,而且不支持索引。常应用于日志记录和聚合分析方面。

当然MySql支持的表类型不止上面几种。

具体请看:

2. 单个索引、联合索引、主键索引

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。

Mysql常见索引有:主键索引、唯一索引、普通索引、全文索引、组合索引

  • PRIMARY KEY(主键索引) ALTER TABLE table_name ADD PRIMARY KEY ( column )
  • UNIQUE(唯一索引) ALTER TABLE table_name ADD UNIQUE (column)
  • INDEX(普通索引) ALTER TABLE table_name ADD INDEX index_name ( column )
  • FULLTEXT(全文索引) ALTER TABLE table_name ADD FULLTEXT ( column )
  • 组合索引 ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 )

Mysql各种索引区别:

  • 普通索引:最基本的索引,没有任何限制
  • 唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
  • 主键索引:它 是一种特殊的唯一索引,不允许有空值。
  • 全文索引:仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间。
  • 组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。

3. Mysql 怎么分表,以及分表后如果想按条件分页查询怎么办

当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。

如何分表?

  • 做 mysql 集群,例如:利用 mysql cluster ,mysql proxy,mysql replication,drdb等等
  • 预先估计会出现大数据量并且访问频繁的表,将其分为若干个表
  • 利用 merge 存储引擎来实现分表

分表后如果想按条件分页查询怎么办?

  1. 如果只是为了分页,可以考虑这种分表,就是表的 id 是范围性的,且id是连续的,比如第一张表 id 是 1 到 10 万,第二张是 10 万到 20 万,这样分页应该没什么问题。
  2. 如果是其他的分表方式,建议用 sphinx 先建索引,然后查询分页
  3. 有损服务,只给他查一年内的数据,或者只存 1kw 条数据。建一个表存一年内的数据,每隔一个月把表最旧的数据迁到分表上面。如果需求方要查所有数据,让他自己选年份去查。

具体请看:http://blog.51yip.com/mysql/949.html

4. 分表之后想让一个id多个表是自增的,效率实现

多个表之间的主键不能用数据库本身的自增主键来支持,因为不同表之间生成的主键会重复。所以需要其他的方式获取主键ID。

(1)通过 MySQL 表生成 ID

在《关于 MySQL 分表操作的研究》提到了一种方法:
对于插入也就是 insert 操作,首先就是获取唯一的 id 了,就需要一个表来专门创建id,插入一条记录,并获取最后插入的 ID。

这种方法效果很好,但是在高并发情况下,MySQL 的 AUTO_INCREMENT 将导致整个数据库慢。如果存在自增字段,MySQL 会维护一个自增锁,innodb 会在内存里保存一个计数器来记录auto_increment 值,当插入一个新行数据时,就会用一个表锁来锁住这个计数器,直到插入结束。

(2)通过 redis 生成 ID

(3)队列方式

使用队列服务,如 redis、memcacheq 等等,将一定量的 ID 预分配在一个队列里,每次插入操作,先从队列中获取一个 ID,若插入失败的话,将该 ID 再次添加到队列中,同时监控队列数量,当小于阀值时,自动向队列中添加元素。
这种方式可以有规划的对ID进行分配,还会带来经济效应,比如 QQ 号码,各种靓号,明码标价。如网站的 userid, 允许 uid 登陆,推出各种靓号,明码标价,对于普通的ID打乱后再随机分配。

(5)oracle sequence : 基于第三方 oracle 的 SEQ.NEXTVAL 来获取一个 ID 优势:简单可用 缺点:需要依赖第三方 oracle 数据库

(6)mysql id 区间隔离 : 不同分库设置不同的起始值和步长,比如 2 台 mysql,就可以设置一台只生成奇数,另一台生成偶数. 或者 1 台用 0~10 亿,另一台用 10~20 亿. 优势:利用 mysql 自增id 缺点:运维成本比较高,数据扩容时需要重新设置步长。

(7)基于数据库更新+内存分配: 在数据库中维护一个 ID,获取下一个 ID 时,会对数据库进行ID=ID+100 WHERE ID=XX,拿到 100 个 ID 后,在内存中进行分配 优势:简单高效 缺点:无法保证自增顺序

具体请看:

5. MySql的主从实时备份同步的配置,以及原理(从库读主库的binlog),读写分离。

具体请看:

6. 写 SQL 语句和 SQL 优化

具体请看:

7. 索引的数据结构,B+树

具体请看:MySQL索引背后的数据结构及算法原理

8. 数据库的锁:行锁,表锁;乐观锁,悲观锁

模式行锁表锁页锁
MyISAM
BDB
InnoDB
  • 表锁: 开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
  • 行锁: 开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
  • 页锁: 开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般

表锁更适用于以查询为主,只有少量按索引条件更新数据的应用;行锁更适用于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用。

具体请看:数据库锁:乐观锁和悲观锁,共享锁和排它锁,行级锁和表级锁

9. 数据库事务的几种粒度

数据库访问控制的粒度可分为4个层次,分别是数据库级、表级、记录级(行级)和属性级(字段级)

具体请看:数据库事务的四大特性

10. 关系型和非关系型数据库区别

关系型数据库通过外键关联来建立表与表之间的关系,非关系型数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定。

当前主流的关系型数据库有 Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL 等。

非关系型数据库有 NoSql、Cloudant。

nosql 和关系型数据库比较?

优点:

  • 1)成本:nosql 数据库简单易部署,基本都是开源软件,不需要像使用 oracle 那样花费大量成本购买使用,相比关系型数据库价格便宜。
  • 2)查询速度:nosql 数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及 nosql 数据库。
  • 3)存储数据的格式:nosql 的存储格式是 key,value 形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
  • 4)扩展性:关系型数据库有类似 join 这样的多表查询机制的限制导致扩展很艰难。

缺点:

  • 1)维护的工具和资料有限,因为 nosql 是属于新的技术,不能和关系型数据库10几年的技术同日而语。
  • 2)不提供对 sql 的支持,如果不支持 sql 这样的工业标准,将产生一定用户的学习和使用成本。
  • 3)不提供关系型数据库对事物的处理。

比如 mysql 与 mongodb 的对比:

文章目录
  1. 1. 数据库基础
  2. 2. 数据库MySql
|