数据库

1、视图的特点

视图只是一种逻辑对象,是一种虚拟表,它并不是物理对象,因为视图不占物理存储空间

优点:

对数据库的访问,因为视图可以有选择性的选取数据库里的一部分

用户通过简单的查询可以从复杂查询中得到结果

维护数据的独立性,试图可从多个表检索数据

对于相同的数据可产生不同的视图

缺点: 查询视图时,必须把视图的查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么就无法更改数据

 

2、存储过程的特点

存储过程是存储在服务器上的一组预编译的Transact-SQL语句,存储过程是一种封装重复任务操作的一种方法,支持用户提供的变量,具有强大的编程功能

优点:

存储过程是预编译过的,执行效率高

存储过程的代码直接存放于数据库中,通过存储过程名直接调用,减少网络通讯

安全性高,执行存储过程需要有一定权限的用户

存储过程可以重复使用,可减少数据库开发人员的工作量

缺点:移植性差触发器的特点

 

3、触发器的作用

触发器是一种特殊的存储过程,主要是通过事件来触发而被执行的。

当有操作影响到触发器保护的数据时,触发器就自动发生,因此触发器是在特定表上进行定义的,该表也称为触发器表,也是一种特殊类型的存储过程

与存储过程的区别:存储过程可以由用户直接调用执行,但是触发器不能被直接调用执行

触发器的类型:insert类型,update类型,delete类型

4、存储过程和函数的区别

一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。

对于存储过程来说可以返回参数,而函数只能返回值或者表对象。

存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。

当存储过程和函数被执行的时候,SQL Manager会到procedure cache中去取相应的查询语句,如果在procedure cache里没有相应的查询语句,SQL Manager就会对存储过程和函数进行编译

 

5、三个范式

属性唯一, 记录唯一, 表唯一

第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。

第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。

第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系: 关键字段 → 非关键字段x → 非关键字段y

 

6、索引是什么?有什么作用以及优缺点?

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

我的理解:索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。

MySQL数据库几个基本的索引类型:普通索引、唯一索引、主键索引、全文索引

索引加快数据库的检索速度索引降低了插入、删除、修改等维护任务的速度唯一索引可以确保每一行数据的唯一性通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能索引需要占物理和数据空间

 

7、什么样的字段适合建索引

唯一、不为空、经常被查询的字段

 

8、什么情况下设置了索引但无法使用,索引无效

以”%”开头的LIKE语句,模糊匹配索引无法使用

在索引列上使用IS NULL 或IS NOT NULL操作

在索引字段上使用not,<>,!=,eg<> 操作符

对索引字段进行计算操作

在索引字段上使用函数

 

9、什么是事务

事务(Transaction)是并发控制的基本单位。它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。

 

10、数据库的乐观锁和悲观锁是什么

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

乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

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

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

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

通常通过索引查询数据比全表扫描要快.但是我们也必须注意到它的代价.

索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时,索引本身也会被修改. 这意味着每条记录的INSERT,DELETE,UPDATE将为此多付出4,5 次的磁盘I/O. 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.使用索引查询不一定能提高查询性能,索引范围查询(INDEX RANGE SCAN)适用于两种情况:

基于一个范围的检索,一般查询返回结果集小于表中记录数的30%

基于非唯一性索引的检索

12、简单说一说drop、delete与truncate的区别

SQL中的drop、delete、truncate都表示删除,但是三者有一些差别

delete和truncate只删除表的数据不删除表的结构速度,一般来说: drop> truncate >delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发。truncate,drop是ddl, 操作立即生效,原数据不放到rollback segment中,不能回滚. 操作不触发trigger.

 

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

不再需要一张表的时候,用drop想删除部分数据行时候,用delete,并且带上where子句保留表而删除所有数据的时候用truncate

 

14、数据库事务的四个特性及含义

数据库事务transanction正确执行的四个基本要素

原子性(Atomicity):事务要么成功(可见),要么失败(不可见)。不存在事务部分成功的情况。

一致性(Consistency):数据库在事务开始前和结束后都应该是一致的。

隔离性(Isolation):一个事务不会看到另外一个还未完成的事务产生的结果。每个事务就像在单独、隔离的环境下运行一样。

持久性(Durability):成功提交的事务,数据是持久保留,不会因为系统失败而丢失。

 

15、事务的隔离级别(http://www.cnblogs.com/fjdingsd/p/5273008.html)

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

当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下

   update account set money=money+100 where name=’B’; (此时A通知B)
   update account set money=money - 100 where name=’A’;

当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

不可重复读:不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了

例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读

不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……

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

例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读

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

现在来看看MySQL数据库为我们提供的四种隔离级别:

Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

Repeatable read (可重复读):可避免脏读、不可重复读的发生。

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

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

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)

在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。

 

16、数据库优化的思路

SQL语句优化

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

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

select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询select id from t where num=0

     很多时候用 exists 代替 in 是一个好的选择

     用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤

创建索引优化

数据库结构优化

服务器硬件优化

 

17、MySQL优化

适当建立索引

对表进行水平划分

对表进行垂直划分

选择适当的字段类型,特别是主键

文件、图片等大文件用文件系统存储,不用数据库

宁可集中批量操作,避免频繁读写

选择合适的引擎(myisam快,innodb,memory)

SQL语句优化

数据库参数配置

读写分离

 

18、MyISAM 和InnoDB

基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。

MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。

两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁。而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用

 

19、union和union all有什么不同?

Union和Union All的区别之一在于对重复结果的处理。

UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。

而UNION ALL只是简单的将两个结果合并后就返回。如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。

从效率上说,UNION ALL要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL,

 

20、注册Jdbc驱动程序的三种方式

Class.forName("com.mysql.jdbc.Driver"); 
DriverManager.registerDriver(new com.mysql.jdbc.Driver())
System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");

 

21、用JDBC如何调用存储过程

package com.zhang.test;
​
import java.lang.String;
import java.lang.System;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;
​
public class Test {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "123");
String sql = "select * from user";
preparedStatement = conn.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
String id = resultSet.getString(1);
String name = resultSet.getString(2);
Date time = resultSet.getDate(3);
System.out.println(id + name + time);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

22、Class.forName的作用?为什么要用?

按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。

 

23、说出数据连接池的工作机制是什么?

J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关连接,而是把它代理的Connection对象还回到连接池中。

 

24、为什么要用 ORM? 和 JDBC有何不一样?

orm是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变成object,我们可以用jdbc来实现这种思想。其实如果我们的项目是严格按照oop方式编写的话,我们的jdbc程序不管是有意还是无意,就已经在实现orm的工作了

 

原文地址:https://www.cnblogs.com/zhangjinru123/p/8595560.html