1.什么是事务?
并发控制的基本单位,是一个操作序列。
不可分割,要么都行,要么都不执行。
事务的四个特性:
原子性:事务操作是个不可分割的整体,要么同时成功,要么同时失败
一致性:数据库在事务对其进行操作时数据保持一致
隔离性:一个事务在最终提交之前,对其他事务不可见
持续性:事务提交后便永久保存于数据库中
2.乐观锁和悲观锁?
悲观锁:对任何数据执行前都加上排他锁。
例:
//0.开始事务
begin;/begin work;/start transaction; (三者选一就可以)
//1.查询出商品信息
select status from t_goods where id=1 for update;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2;
//4.提交事务
commit;/commit work;
这里使用select…for update 对t_goods表中的一行数据加上行级锁。这样保证在事务提交 前这一行的数据都不会被修改。
缺点:产生额外开销和死锁。
乐观锁:在数据提交时检查版本号。
例:
1.查询出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status为2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};
这里操作数据时对版本号进行+1操作,提交时再检查版本,如果其他事务对这行数据进行了操作,则提交的version肯定不相同,此时需进行回滚操作。
3.索引查询一定能提高查询的性能吗?为什么
不一定,因为索引占用存储空间,还需要维护,例如update、delete等操作将为此多付出4,5 次的磁盘I/O(为了维护一个平衡树)。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。
但是索引在范围查找方面有自己的优势。
索引
扩展问题:
为什么要给表加上主键?
没加主键的表就是常规意义上整齐排列的表,加了主键的表蜕变成平衡树即一个索引,就是所谓的聚集索引。
为什么加索引后会使查询变快?
加了索引之后表变成平衡二叉树,查找一个数据的IO消耗指数级别的下降:
例如一个有1亿级别数据的表,没加索引,查找一个数需要1亿个IO消耗,而通过索引只需要10以内的IO消耗。
为什么加索引后会使写入、修改、删除变慢?
为了维持平衡树的结构,增删改查都会改变原有数据结构,重新梳理平衡二叉树,产生额外开销。
什么情况下要同时在两个字段上建索引?
当使用覆盖索引的时候。
索引一般分为非聚集索引和聚集索引,依靠主键建立的索引是聚集索引,不依靠主键的索引是非聚集索引,当通过非聚集索引查找数据的时候仍然是先在非聚集索引上查到对应得主键,再进行聚集索引查询,这样造成的开销较大。
如果为一个索引指定两个字段, 那么这个两个字段的内容都会被同步至非聚集索引之中。当进行非聚集查询索引查询的时候就不用回表了。
4.请谈一谈脏读、幻读和不可重复读?
脏读:一个事务修改将数据修改却还未提交,此时这个数据被另一个事务读到。
幻读:一个事务在两次读取同一个数据时,另一个事务提交了数据,使得两次读到数据个数不相同。(强调个数不一致)
不可重复读:一个事务查询同一条记录2次,得到的结果不一致(强调数据不一致)。
5.谈一谈隔离级别?
read uncommitted(读未提交):一个事务还未提交就被其他事务读到数据,产生脏读,违反事务的隔离性。
read committed(读提交):事务只能读取已提交的事务的数据,满足了隔离性,避免了脏读。
repeatable read(可重复读):保证在一个事务中读到的数据是一致的,满足了隔离性和一致性,避免了可重复读。
Serializable(可串行化):最高的隔离级别,通过每行数据加共享锁来实现。避免了幻读。
其中mysql数据库默认的隔离级别是可重复读,其他主流数据库默认读提交。
6.常用的表关联有哪些?
常用的关联有:
内关联(inner join):结果集是两张表中 都存在的记录,是一个交集。
比如:在学生表中,有一个班级ID,我们想根据班级ID,在班级表中找到班级信息:
select * from t_student a
-- 要关联查询的表
join t_class b
-- 使用什么字段去关联这两张表
on a.c_id = b.c_id;
或
SELECT A.value, B.value
FROM tablea AS A INNER JOIN tableb AS B
ON A.key = B.key;
外关联(left join,right join):都是选定一个表为主表,无论是否存在关联,主表都会存在。
例如:
SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Orders.cust_id;
多表联结的另一个例子:
(外联接)有学生表和近视学生表,找出不带眼镜的学生人数
select a.姓名 as 不带眼镜学生名单
from 学生表 as a
left join 近视学生表 as b
on a.学号 = b.学生学号
where b.序号 is null
内联接、左连接、右连接、全外连接区别
7.数据库的三范式是什么?
第一范式(1NF)
符合1NF的关系中的每个属性都不可再分,关系型数据库的最基本要求。
第二范式(2NF)
满足1NF,表中的字段必须完全依赖于全部主键而非部分主键
第三范式
满足2NF,非主键外的所有字段必须互不依赖
范式
8.MyBatis中 # 和 $ 的区别是什么?
-
#符号将传入的数据都当做一个字符串,会对自动传入的数据加一个双引号
-
$符号将传入的数据直接显示在生成的SQL语句中。
-
#符号存在预编译的过程,对问号赋值,防止SQL注入。
-
$符号是直译的方式,一般用在order by ${列名}语句中。
例子