A 原子性,要么全成功,要么全失败 由undo log日志保证,其记录需要回滚日志信息,回滚就撤销执行成功的sql。
C 一致性,事务不提交,就不会应用到数据库 一般由代码层面和其他三大特性共同保证。
I 隔离性,一个事务修改最终提交前,其他事务不可见 事务之间不相互影响,由锁和MVCC保证
D 持久化,一旦提交,修改永久存储到数据库 由内存+ redo log保证,修改数据同时在内存和redo log记录,提交通过redo log刷盘,宕机可以从redo log恢复。 redo log是物理操作,undo log是逻辑日志。
9-1分裂和5-5分裂。
表频繁update、delete
发生了alter table… move操作
幻读解决:Next-Key: 记录锁 + 间隙锁
使用:
START TRANSACTION; # 开始事务
SELECT xxx FROM xxx FOR UPDATE; # 获得锁
UPDATE ...
COMMIT; # 释放锁
加锁可能性
InnoDB | MyISAM | |
---|---|---|
事务 | 支持事务、回滚、崩溃修复、事务安全,通过MVCC支持高并发事务 | 不支持事务但是性能较高 |
外键 | 支持 | 不支持 |
索引 | 主键是聚簇索引,其他是非聚簇索引 | 均为非聚簇索引,内存效率更高 |
保存具体行数 | 没有 | 有,查询方便 |
操作粒度 | 行锁 | 表锁 并发受限 |
场景 | 插入频繁 | 大量查询少量插入,数据仓库 |
data域存储实质 | 数据地址 | 辅助索引是主键值,所以最好使用短主键 |
引入了buffer pool,操作先在buffer pool实现,然后写入磁盘。
表空间:InnoDB存储引擎逻辑结构最高层,一个idb文件。
段:表空间由各个段组成,如数据段,索引段回滚段等,段是逻辑概念,创建一个索引会创建两个段,索引段(非叶子节点)和数据段(叶子节点),表的段数为索引数*2。
区:一个段由多个区组成,每个段至少有一个区,一个段管理的空间大小无限,但是最小单位就是区,一个区空间为1M,可以放64页。有点像操作系统的段页式。
页:一页为16kb,存放一个节点的数据,也是磁盘管理的最小单位,(一个B+树节点,页编号可以映射到物理文件偏移)
行:一个记录
字段:一个记录里面的一个字段
多版本并发控制,MVCC使得数据库读不会对数据库加锁,提高了其并发处理能力。
只在读已提交和可重复读两个级别使用。
原理:聚簇索引中有两个隐藏的列,一个用来记录对数据做出修改的事务id,另一个指向上一个版本的位置。
不可重复读下每次查询都会创建新的readview,所以可能会造成不一致。
可重复读下使用同一个readview,所以两次结果相同,实现读时不允许写。
引入了buffer pool,操作先在buffer pool实现,然后写入磁盘。
mysql在线ddl 加字段 加索引等的操作
整个过程会锁表,造成当前表无法写入数据,数据越大等待时间越长,卡死在那里(拒绝执行update和insert操作,表现就是延迟一直在等)
有点像Excel的一维表转化为二维表
两种方法都需要配合SUM函数,实质是筛选出不同的列的条件求和,不满足的为0。
UPDATE…FROM…
update b set b.col=a.col from a,b where a.id=b.id;
update b set col=a.col from b inner join a on a.id=b.id;
update b set b.col=a.col from b left Join a on b.id = a.id;
CREATE TABLE t1 ( id INT NOT NULL, name CHAR(30) NOT NULL, UNIQUE INDEX UniqIdx(id) );
ALTER TABLE book ADD UNIQUE INDEX UniqidIdx (bookId);
CREATE UNIQUE INDEX UniqidIdx ON book (bookId);
首先定位性能瓶颈然后再想办法解决。
MySQL中慢查询日志默认是关闭的,可以通过配置文件my.ini或者my.cnf中的log-slow-queries选项打开,也可以在MySQL服务启动的时候使用–log-slow-queries[=file_name]启动慢查询日志。
启动慢查询日志时,需要在my.ini或者my.cnf文件中配置long_query_time选项指定记录阈值,如果某条查询语句的查询时间超过了这个值,这个查询过程将被记录到慢查询日志文件中。分析慢查询日志,
explain字段解释:
需要优化的情况和措施
MyISAM禁用索引
InnoDB
避免SELECT *
where中过滤不必要列
where中不要用比较操作,会全表扫描
exists代替in,后者会笛卡尔积再筛选,前者对每条记录进行条件判断
用where代替having,having先操作再过滤
当MySQL单表记录数据过大(业界500万行),性能会下降,所以需要采取措施,尽可能不拆表,拆分会比较麻烦。
一般先垂直再水平
垂直:
微服务拆分,一般已经坐到垂直分库了
对于库内字段多的表,将不常用,数据大的再进行拆分
水平则需要根据业务场景来决定用什么字段,比如日单1000万,大部分场景是C端,使用user_id作为sharding_key,数据支持查到最近3个月订单,超过3个月归档,3个月就是9亿,分1024张,每张1000万左右。如对id进行hash然后对1024取模,落到对应表。
设定步长,每个表设定不同的步长,主键落到不同表不会冲突。
分布式ID,雪花算法或者自己实现
分表后不使用主键作为查询依据,每个表新增加一个字段作为唯一主键使用,比如订单表订单号唯一的,不管在哪张表都可用。
涉及主节点的一个线程(binlog dump)和从节点的两个线程(IO,SQL)
DAO(Data Access Object)数据访问接口。
Mybatis 优秀持久层ORM框架,建立实体和SQL的映射关系,半自动化的ORM实现,使用Mybatis可以解决驱动注册、connection获取等,可以使开发人员关注业务sql本身。
sql,表示是sql语句,可以在其他语句中引用
parameterType 指定参数类型,可以指定基本数据类型、包装类型以及自己编写的JavaBean
resultType 指定返回信息对应的Java数据类型
#{}预处理语句,没法模糊查询,${}直接拼接,可以模糊查询,但是可能SQL注入
sql片段标签,如where,if,foreach set trim choose when otherwise bind,可以通过include引入
dao层的方法不能直接在java文件中重载,因为xml中id不能重复,可以通过动态sql来实现重载,比如判断是否为空等。
三选二
非关系型 | 关系型 | |
---|---|---|
数据一致性 | CAP | ACID一致性高 |
效率 | 并发读写很高 | 较低 |
数据存储结构 | 存储结构多种 | 固定表结构 |
可扩展性 | 扩展性较强,因为数据结构灵活 | 扩展性较弱,数据结构不易变动 |