题目来源牛客网文章——《感谢牛客网!发一波面经!》
索引:
Q | Title |
---|---|
1 | 数据库连接方式 |
2 | 数据库的事务特性 |
3 | 数据库隔离等级 |
4 | 乐观锁和悲观锁 |
Q1:数据库连接方式
A | id | name | B | id | job | userId |
---|---|---|---|---|---|---|
1 | 张三 | 1 | 医生 | 3 | ||
2 | 李四 | 2 | 警察 | 7 | ||
3 | 王五 | 3 | 地痞 | 2 |
内连接
两个表做匹配,保留所有左右均可以取到有效值的行
SELECT a.*,b.*
FROM A a INNER JOIN B b -- 内连接
ON a.id = b.userId
id | name | id | job | userId |
---|---|---|---|---|
2 | 李四 | 3 | 地痞 | 2 |
3 | 王五 | 1 | 医生 | 3 |
左连接
两个表做匹配,以左侧表为主,保留左侧所有行,哪怕右侧没有匹配值(用null填充)
SELECT a.*,b.*
FROM A a LEFT JOIN B b -- 内连接
ON a.id = b.userId
id | name | id | job | userId |
---|---|---|---|---|
1 | 张三 | null | null | null |
2 | 李四 | 3 | 地痞 | 2 |
3 | 王五 | 1 | 医生 | 3 |
右连接
两个表做匹配,以右侧表为主,保留右侧所有行,哪怕左侧没有匹配值(用null填充)
SELECT a.*,b.*
FROM A a RIGHT JOIN B b -- 内连接
ON a.id = b.userId
id | name | id | job | userId |
---|---|---|---|---|
3 | 王五 | 1 | 医生 | 3 |
null | null | 2 | 警察 | 7 |
2 | 李四 | 3 | 地痞 | 2 |
全连接
两个表做匹配,保留两个表所有行,哪怕对应另一侧没有匹配值(用null填充)
SELECT a.*,b.*
FROM A a RIGHT JOIN B b -- 内连接
ON a.id = b.userId
id | name | id | job | userId |
---|---|---|---|---|
1 | 张三 | null | null | null |
2 | 李四 | 3 | 地痞 | 2 |
3 | 王五 | 1 | 医生 | 3 |
null | null | 2 | 警察 | 7 |
Q2:数据库的事务特性(四大特性)
事务
事务是一系列对系统中数据进行访问与更新的操作组成的一个程序逻辑单元。
通俗来说就是:不可分割的许多基础数据库操作
原子性(Atomicity)
事务包含的操作要么全部成功,要么全部失败回滚。
一致性(Consistency)
一个事务执行前后,应该使数据库从一个一致性状态转换为另一个一致性状态。
比方说假设A、B两个人,共有5000元。那么无论A给B转多少钱,转多少次,总数仍然是5000没有改变
隔离性(Isolation)
多个用户并发访问数据库时,比如操作同一张表,数据库为每一个用户开启的事务,不能被其他事务的操作干扰。多个并发事务间需要隔离。
持久性(Durability)
一旦一个事务被提交,对数据库中的数据改变是永久的,即使数据库系统故障,也不会丢失提交事务操作。
举例:提交了对数据库的事务操作,数据库会返回“操作成功”,哪怕此时数据库出现问题,也需要继续把这个事务完成,否则我们得到的提示和实际产生出入。
Q3:数据库隔离等级
多线程同时开启事务,操作数据库中数据,数据库系统需要做隔离操作。那么如果不做隔离操作会怎么样?
脏读
在一个事务中,读取到了另一个事务未提交事务的操作。
比如说A给B转100元。两步SQL
UPDATE acount SET money = money + 100 WHERE name = 'B';
UPDATE acount SET money = money - 100 WHERE name = 'A';
假设在两条SQL中间,B查询自己的余额,此时余额增加了100。而转钱这个事务最终未完成(A扣费失败,或事务没有提交),那么实际上回滚以后,B是没有收到这笔钱的
不可重复读
不可重复读指的是,对于某个数据,在一个事务范围里,多次查询却返回了不同的值。原因是查询间隔的时候,这个数据被其他事务修改并提交了。
与脏读区别在于,脏读没有提交,而不可重复读是由于其他事务在中间提交。
幻读
幻读与不可重复读类似,只是作用对象从某个数据,变成了一批数据整体。
比如说表里所有的张三修改为李四。在修改的时候,另一个人新增了一个“张三”的数据进表。刚做完替换操作的用户一看,怎么还有一个数据项没有修改,我是不是出现幻觉了。这就是幻读的来历。
MYSQL隔离等级(由高到低)
Serializable(串行化):
避免脏读、不可重复读、幻读
Repeatable Read(可重复读):(MYSQL默认选择)
避免脏读、不可重复读
Read Committed(读已提交):
避免脏读
Read uncommitted(读未提交):
最低级别,任何情况都无法保证
引申
Oracle数据库中,仅有Serializable(串行化)和Read Committed(读已提交)两种隔离方式,默认选择读已提交的方式。
Q4:乐观锁和悲观锁
乐观锁
总认为不会有并发问题,不对数据上锁,更新时采用version获得其他线程最后对某数据的修改结果
UPDATE TABLE
SET id=id+1,version = version + 1
WHERE id={#id} AND version={#version};
网友评论