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持久性)
脏读:事务读取了另一个事务提交而更新了的数据,如一个事务对某列进行更新,另一个事务读取了同一列,之后前事务由于某些原因对更新做了回滚操作,此时后事务读取的数据时不正确的
不可重复读:事务两次重复的读取之间存在另一事务对数据的改变,导致两次读取的数据不一致;如果是主动提起的多次查询请求不可重复读不是问题,但同一事务中先后读取数据,在此时不可重复读引起两次得到的数据不一致就会造成问题
幻读(虚读):一次事务进行数据读取之后另一事务对数据进行了更新,出现新的列导致数据没有被前事务读取到;常出现于前事务对数据进行批量操作时,导致漏网之鱼的出现,如对数据进行加锁后,另一事务增加了新列,导致新列的数据没有被加锁
隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
---|---|---|---|---|
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)
优点:能够封装复杂的商业逻辑
缺点:在高并发环境下存在性能问题
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,关闭连接
PreparedStatement能够防止SQL注入,性能更高,编写方便