SQL语句
连接查询
- 外连接(左外连接、右外连接):解决外键为空的数据查询,当数据表之间没有物理建立主外键时,出现外键为空的情况直接联查查不到,使用外连接就可以解决这一问题(如左外连接会先将左表所有列查出,再从右表中找到符合条件的列,对于没有符合条件的坐标列对应右表字段为NULL)
- 子查询:以一张表查询结果作为第二张表的查询条件的查询
数量查询问题
select count(*) from table
select count(1) from table
select count(row) from table
以上三种方式中,前两种方式性能较高且能够查询出所有数量;第三种方式 较低,且对于该字段为空的列的数量不计
存储引擎
在MySQL5.1之前的版本中,默认的存储引擎是MyISAM,在5.5之后的版本中,默认的存储引擎变更为InnoDB
InnoDB | MyISAM |
支持事务,外键 | 不支持事务,外键 |
聚集索引(索引和数据存放在一起) | 非聚集索引 |
不支持全文索引(5.6.4后也支持了) | 支持全文索引 |
支持到行锁 | 支持表锁 |
不保存表数据总条数 | 保存表数据总条数 |
读写阻塞与事务相关 | 读会阻塞写 |
选择方面,在读写分离时,主库使用InnoDB,从库使用MyISAM
事务
事务的四大特性:ACID(atomicity原子性,consistency一致性,isolation隔离性,durability持久性)
- 原子性:一个事务过程是一个整体,类似于一个不可再分的原子,事务要么全部完成要么全部不完成。
- 持久性:事务完成之后,对数据的处理操作是永久的,即使时系统瘫痪也不会出现数据丢失
- 一致性:事务开始前与完成后,数据库的完整性不会被破坏,事务结果需要与库的预期符合,其他三个特点也都是为了保证数据一致性,这是最终目标
4. 隔离性
脏读、不可重复读、幻读
- 脏读:事务读取了另一个事务提交而更新了的数据,如一个事务对某列进行更新,另一个事务读取了同一列,之后前事务由于某些原因对更新做了回滚操作,此时后事务读取的数据时不正确的
- 不可重复读:事务两次重复的读取之间存在另一事务对数据的改变,导致两次读取的数据不一致;如果是主动提起的多次查询请求不可重复读不是问题,但同一事务中先后读取数据,在此时不可重复读引起两次得到的数据不一致就会造成问题
- 幻读(虚读):一次事务进行数据读取之后另一事务对数据进行了更新,出现新的列导致数据没有被前事务读取到;常出现于前事务对数据进行批量操作时,导致漏网之鱼的出现,如对数据进行加锁后,另一事务增加了新列,导致新列的数据没有被加锁
隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
READ UNCOMMITTED | 是 | 是 | 是 | 否 |
READ COMMITTED | 否 | 是 | 是 | 否 |
REPEATABLE READ(默认的隔离级别) | 否 | 否 | 是 | 否 |
SERIALIZABLE | 否 | 否 | 否 | 是 |
存储过程
具有复杂逻辑的SQL语句创建为数据库的对象
- 创建存储过程
delimeter $$
create procedure procs(in id integer)
begin
delete from table where id = table.id;
end $$
- 调用存储过程
call procs(1)
优点:能够封装复杂的商业逻辑
缺点:在高并发环境下存在性能问题
JDBC
JDBC基本使用流程
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
Class.forName(Driver.class);
conn = DriverManager.getConnection(url,username,password);
String sql = "";
pstmt = conn.preparedStatement(sql);
rs = pstmt.excute();
if(conn!=null){
conn.close;
conn=null;
}
if(pstmt !=null){
pstmt .close;
pstmt =null;
}
if(rs !=null){
rs .close;
rs =null;
}
调用存储过程
Connection conn = DriverManger.getConnection(url,username,password);
CallableStatement callStmt = conn.prepareCall(processName);
callStmt.execute();
数据库连接池
常见的数据库连接池:Druid,c3p0,HikariCP(Springboot默认)
基本原理
连接池启动时会建立许多数据库连接在连接池中,每次应用需要访问数据库时就从连接池获取一个连接,使用完之后也不会将连接断开,而是将连接放回连接池中
常见面试题
- 数据库驱动是什么?
JDBC规范的实现
- 操作数据库的步骤
加载驱动,获取Connection,构造Statement,执行sql,关闭连接
- Statement与PreparedStatement的区别
PreparedStatement能够防止SQL注入,性能更高,编写方便