1.事务四大特性
原子性,要么执行,要么不执行
隔离性,所有操作全部执行完以前,其它会话不能看到过程
一致性,事务前后,数据总额一致
持久性,一旦事务提交,对数据的改变就是永久的
2.数据库隔离级别,每个级别会引发什么问题,mysql默认是哪个级别
脏读:事务B读取事务A还没有提交的数据
不可重复读:两次事务读的数据不一致
幻读:事务A修改了数据,事务B也修改了数据,这时在事务A看来,明明修改了数据,怎么不一样,像是产生了幻觉。
隔离级别
Serializable (串行化):可避免脏读、不可重复读、幻读的发生
Repeatable read (可重复读):可避免脏读、不可重复读的发生。
Read committed (读已提交):可避免脏读的发生。
Read uncommitted (读未提交):最低级别,任何情况都无法保证
以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。
在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。
3.MYSQL的两种存储引擎区别(事务、锁级别等等),各自的适用场景
MYISAM 不支持事务,不支持外键,表锁,插入数据时,锁定整个表,查表总行数时,不需要全表扫描
INNODB 支持事务,支持外键,行锁,查表总行数时,全表扫描
4.索引有B+索引和hash索引,各自的区别
hash索引,等值查询效率高,
不能排序
不能进行范围查询
B+索引
数据有序
范围查询
5.B+索引数据结构,和B树的区别
1.单一节点存储更多的元素,B+树空间利用率更高,使得查询的IO次数更少。
2.所有查询都要查找到叶子节点,查询性能稳定。
3.所有叶子节点形成有序链表,便于范围查询
6.索引的底层实现(B+树,为何不采用红黑树,B树)
增加,删除,红黑树会进行频繁的调整,来保证红黑树的性质,浪费时间
B树,查询性能不稳定,查询结果高度不致,
B树,每个结点保存指向真实数据的指印,相比B+树每一层每屋存储的元素更多,显得更高一点。
7.聚集索引和非聚集索引区别
聚集索引,数据按索引顺序存储,中子结点存储真实的物理数据
非聚集索引,存储指向真正数据行的指针
8.索引的优缺点,什么时候使用索引,什么时候不能使用索引(重点)
索引最大的好处是提高查询速度,
缺点是更新数据时效率低,因为要同时更新索引
对数据进行频繁查询进建立索引,如果要频繁更改数据不建议使用索引。
9.B树,也是B-树
先看二叉查找树,时间复杂度log(n),考虑磁盘IO,所以需要二叉查找树矮宽,减小树的高度。
1.根结点至少有两个子女。
2.每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m
3.每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m
4.所有的叶子结点都位于同一层。
5.每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划
k的大小取决于磁盘页的大小,主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,
此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。
10.InnoDB索引和MyISAM索引的区别:
一是主索引的区别,InnoDB的数据文件本身就是索引文件。而MyISAM的索引和数据是分开的。
二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。
11.为什么使用B-/+Tree
索引查找过程中就要产生磁盘I/O消耗,主要看IO次数,和磁盘存取原理有关。
根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,
将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入
局部性原理与磁盘预读
12.B+树具体实现
一个m阶的B+树具有如下几个特征:
1.有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
2.所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3.所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素
13.数据库的优化(一条sql中能使用一个索引,多个索引会自动选择最优的索引,从sql语句优化和索引两个部分回答)
原则1.sql尽量使用索引
2.对sql语句优化
子查询变成left join
limit 分布优化,先利用ID定位,再分页
or条件优化,多个or条件可以用union all对结果进行合并(union all结果可能重复)
不必要的排序
where代替having,having 检索完所有记录,才进行过滤
避免嵌套查询
对多个字段进行等值查询时,联合索引
14.是否使用索引explain查看查询计划
15.索引最左前缀问题
如果对三个字段建立联合索引,如果第二个字段没有使用索引,第三个字段也使用不到索引了。
16.索引分类,索引失效条件
普通索引:最基本的索引,没有任何限制
唯一索引:与”普通索引”类似,不同的就是:索引列的值必须唯一,但允许有空值。
主键索引:它是一种特殊的唯一索引,不允许有空值。
全文索引:针对较大的数据,生成全文索引很耗时好空间。
组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则
失效条件
条件是or,如果还想让or条件生效,给or每个字段加个索引
like查询,以%开头
内部函数
对索引列进行计算
is null不会用,is not null 会用
16.数据库的主从复制
默认异步复制,容易造成主库数据和从库不一致
一个数据库为Master,一个数据库为slave,通过Binlog日志
slave两个线程,一个线程去读master binlog日志,写到自己的中继日志
一个线程解析日志,执行sql
master启动一个线程
给slave传递binlog日志
半同步复制
只有把master发送的binlog日志写到slave的中继日志,这时主库
才返回操作完成的反馈,性能有一定降低
并行复制
slave 多个线程去请求binlog日志
17.long_query怎么解决
设置参数,开启慢日志功能,得到耗时超过一定时间的sql
18.varchar和char的使用场景
用来存储字符
varchar适用字符长度经常变的
char适用字符长度固定的
19.数据库连接池的作用
维护一定数量的连接,减少创建连接的时间
更快的响应时间
统一的管理
20.分库分表,主从复制,读写分离
读写分离,读从库,写主库
spring配置两个数据库,通过AOP(面向切面编程),在写或读方法前面进行判断得到动态切换数据源。
21.数据库三范式
1NF 属性不可分
2NF 非主键属性,完全依赖于主键属性
3NF 非主键属性无传递依赖
22.关系型数据库和非关系型数据库区别
数据库
类型 特性
关系型数据库mysql 1、关系型数据库,是指采用了关系模型来组织数据的数据库,
2.关系型数据库的最大特点就是事务的一致性;
优点
1、容易理解:二维表结构是非常贴近逻辑世界一个概念,关系模型相对网状、层次等其他模型来说更容易理解;
2、使用方便:通用的SQL语言使得操作关系型数据库非常方便;
3、易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率;
4、支持SQL,可用于复杂的查询。
缺点
1、为了维护一致性所付出的巨大代价就是其读写性能比较差;
2、固定的表结构;
3、不支持高并发读写需求;
4、不支持海量数据的高效率读写;
非关系型数据库 特性
HBase 1、使用键值对存储数据;
2、分布式;
优点
无需经过sql层的解析,读写性能很高
基于键值对,数据没有耦合性,容易扩展
存储数据的格式:nosql的存储格式是key,value形式
缺点
不支持事务
不提供sql支持
23.数据库中join的inner join, outer join, cross join
以A,B两张表为例
A left join B
选出A的所有记录,B表中没有的以null 代替
right join 同理
inner join
A,B的所有记录都选出,没有的记录以null代替
cross join (笛卡尔积)
A中的每一条记录和B中的每一条记录生成一条记录
例如A中有4条,B中有4条,cross join 就有16条记录
24.有哪些锁,select时怎么加排它锁
乐观锁,自己实现,通过版本号
悲观锁:共享锁,多个事务,只能读不能写,加 lock in share mode
排它锁,一个事务,只能写,for update
行锁
表锁
25.死锁怎么解决
找到进程号,kill 进程
26 最左匹配原则 (左前缀匹配原则)
最左匹配原则是针对索引的
举例来说:两个字段(name,age)建立联合索引,如果where age=12这样的话,是没有利用到索引的,这里我们可以简单的理解为先是对name字段的值排序,然后对age的数据排序,如果直接查age的话,这时就没有利用到索引了,查询条件where name=’xxx’ and age=xx 这时的话,就利用到索引了,再来思考下where age=xx and name=’xxx‘ 这个sql会利用索引吗,按照正常的原则来讲是不会利用到的,但是优化器会进行优化,把位置交换下。这个sql也能利用到索引了
1、触发器的作用?
触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的。它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算。如,某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。
2、什么是存储过程?用什么来调用?
存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。 调用: 1)可以用一个命令对象来调用存储过程。 2)可以供外部程序调用,比如:java程序。
3、存储过程的优缺点?
优点: 1)存储过程是预编译过的,执行效率高。 2)存储过程的代码直接存放于数据库中,通过存储过程名直接调用,减少网络通讯。 3)安全性高,执行存储过程需要有一定权限的用户。 4)存储过程可以重复使用,可减少数据库开发人员的工作量。 缺点:移植性差
4、存储过程与函数的区别
5、索引的作用?和它的优点缺点是什么?
索引就一种特殊的查询表,数据库的搜索可以利用它加速对数据的检索。它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者是多个列。缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。
6、什么样的字段适合建索引
唯一、不为空、经常被查询的字段
7、索引类型有哪些?
逻辑上:
Single column 单行索引
Concatenated 多行索引
Unique 唯一索引
NonUnique 非唯一索引
Function-based 函数索引
Domain 域索引 物理上:
Partitioned 分区索引
NonPartitioned 非分区索引
B-tree :
Normal 正常型B树
Rever Key 反转型B树 Bitmap 位图索引
8、什么是事务?什么是锁?
事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。 锁:在所以的DBMS中,锁是实现事务的关键,锁可以保证事务的完整性和并发性。与现实生活中锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。当然锁还分级别的。
9、什么叫视图?游标是什么?
视图:是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,试图通常是有一个表或者多个表的行或列的子集。对视图的修改会影响基本表。它使得我们获取数据更容易,相比多表查询。 游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。
10、视图的优缺点
优点: 1)对数据库的访问,因为视图可以有选择性的选取数据库里的一部分。 2 )用户通过简单的查询可以从复杂查询中得到结果。 3 )维护数据的独立性,试图可从多个表检索数据。 4 )对于相同的数据可产生不同的视图。 缺点: 性能:查询视图时,必须把视图的查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,那么就无法更改数据
11、列举几种表连接方式,有什么区别?
内连接、自连接、外连接(左、右、全)、交叉连接 内连接:只有两个元素表相匹配的才能在结果集中显示。 外连接: 左外连接:左边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。 右外连接:右边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。 全外连接:连接的表中不匹配的数据全部会显示出来。 交叉连接: 笛卡尔效应,显示的结果是链接表数的乘积。
12、主键和外键的区别?
主键在本表中是唯一的、不可唯空的,外键可以重复可以唯空;外键和另一张表的主键关联,不能创建对应表中不存在的外键。
13、在数据库中查询语句速度很慢,如何优化?
1.建索引 2.减少表之间的关联 3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据 量大的表排在前面 4.简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据 5.尽量用PreparedStatement来查询,不要用Statement
14、数据库三范式是什么?
第一范式:列不可再分 第二范式:行可以唯一区分,主键约束 第三范式:表的非主属性不能依赖与其他表的非主属性 外键约束 且三大范式是一级一级依赖的,第二范式建立在第一范式上,第三范式建立第一第二范式上
15、union和union all有什么不同?
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION。 UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。 从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL。
16、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
17、Oracle和Mysql的区别?
1)库函数不同。 2)Oracle是用表空间来管理的,Mysql不是。 3)显示当前所有的表、用户、改变连接用户、显示当前连接用户、执行外部脚本的语句的不同。 4)分页查询时候时候,mysql用limit oracle用rownum
mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15 //为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1: mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last. //如果只给定一个参数,它表示返回最大的记录行数目: mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行 //换句话说,LIMIT n 等价于 LIMIT 0,n。 5)sql的语法的不同。
18、Oracle语句有多少类型
Oracle语句分三类:DDL、DML、DCL。 DDL(Data Definition Language)数据定义语言,包括: Create语句:可以创建数据库和数据库的一些对象。 Drop语句:可以删除数据表、索引、触发程序、条件约束以及数据表的权限等。 Alter语句:修改数据表定义及属性。 Truncate语句:删除表中的所有记录,包括所有空间分配的记录被删除。 DML(Data Manipulation Language)数据操控语言,包括: Insert语句:向数据表张插入一条记录。 Delete语句:删除数据表中的一条或多条记录,也可以删除数据表中的所有记录,但是它的操作对象仍是记录。 Update语句:用于修改已存在表中的记录的内容。 DCL(Data Control Language)数据库控制语言,包括: Grant语句:允许对象的创建者给某用户或某组或所有用户(PUBLIC)某些特定的权限。 Revoke语句:可以废除某用户或某组或所有用户访问权限
19、oracle分页查询语句
使用rownum,两种如下: 第一种: select * from (select t.*,rownum row_num from mytable t) b where b.row_num between 1 and 10 第二种: select * from ( select a.*, rownum rn from mytable a where rownum <= 10 ) where rn >= 1 使用rowid, 如下: select * from scott.emp where rowid in (select rd from (select rowid as rd ,rownum as rn from scott.emp ) where rn<=6 and rn>3)
20、从数据库中随机取50条
select * from (select * from t_example order by dbms_random.random) where rownum <= 50
21、order by与group by的区别
order by 排序查询、asc升序、desc降序 group by 分组查询、having 只能用于group by子句、作用于组内,having条件子句可以直接跟函数表达式。使用group by 子句的查询语句需要使用聚合函数。
22、commit在哪里会运用
oracle的commit就是DML语句提交数据(这里是释放锁不是锁表),在未提交前你前面的操作更新的都是内存,没有更新到物理文件中。 执行commit从用户角度讲就是更新到物理文件了,事实上commit时还没有写date file,而是记录了redo log file,要从内存写到data物理文件,需要触发检查点,由DBWR这个后台进程来写,这里内容有点多的,如果不深究的话你就理解成commit即为从内存更新到物理文件。
23、行转列、列换行怎么转
1)使用decode函数 2)使用case when语句
24、什么是PL/SQL?
PL/SQL是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL)。PL/SQL是Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算。PL/SQL 只有 Oracle 数据库有。 MySQL 目前不支持 PL/SQL 的。
25、序列的作用
Oracle使用序列来生成唯一编号,用来处理一个表中自增字段。 Oracle序列是原子对象,并且是一致的。也就是说,一旦您访问一个序列号,Oracle将在处理下一个请求之前自动递增下一个编号,从而确保不会出现重复值。
26、表和视图的关系
视图其实就是一条查询sql语句,用于显示一个或多个表或其他视图中的相关数据。 表就是关系数据库中实际存储数据用的。
27、oracle基本数据类型
1)字符串类型 char、nchar、varchar、varchar2、nvarchar2 2)数字类型 number、integer 3)浮点类型 binary_float、binary_double、float 4)日期类型 date、 timestamp 5)LOB类型 blob、clob、nclob、bfile
28、truncate与 delete区别
TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。 DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。
TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。 TRUNCATE,DELETE,DROP 放在一起比较:
TRUNCATE TABLE :删除内容、释放空间但不删除定义。
DELETE TABLE: 删除内容不删除定义,不释放空间。
DROP TABLE :删除内容和定义,释放空间。
29、oracle获取系统时间
select to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss') from dual;
30、oracle怎么去除去重
使用distinct关键字
1. 锁
共享锁和排他锁:在一般的应用中,为了应付大量并发,我们一般使用一次封锁法,在方法的开始阶段,已经预先知道会用到哪些数据,然后全部锁住,在方法运行之后,再全部解锁。在这种方法在数据库中却不适用,因为在事务开始阶段,数据库并不知道会用到哪些数据。数据库遵循的是两段锁协议,将事务分成两个阶段,加锁阶段和解锁阶段(所以叫两段锁)。
加锁阶段:在该阶段可以进行加锁操作。在对任何数据进行读操作之前要申请并获得S锁(共享锁,其它事务可以继续加共享锁,但不能加排它锁),在进行写操作之前要申请并获得X锁(排它锁,其它事务不能再获得任何锁)。加锁不成功,则事务进入等待状态,直到加锁成功才继续执行。
解锁阶段:当事务释放了一个封锁以后,事务进入解锁阶段,在该阶段只能进行解锁操作不能再进行加锁操作。
2、锁机制
共享锁:由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写
排它锁:由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型mysql事务中
start transaction;
select * from user where userId = 1
forupdate;
执行完这句以后
1)当其他事务想要获取共享锁,比如事务隔离级别为Serializable的事务,执行select * from user;
将会被挂起,因为Serializable的select语句需要获取共享锁
2)当其他事务执行
select * from user where userId = 1 for update;
update user set userAge = 100 where userId = 1;
也会被挂起,因为for update会获取这一行数据的排它锁,需要等到前一个事务释放该排它锁才可以继续进行。
行锁:对某行记录加上锁
表锁:对整个表加上锁
悲观锁(Pessimistic Lock):顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁(Optimistic Lock):顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,如果期间被修改,则给用户做出提示。可以使用版本号等机制记录状态。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。