原子性(atomicity)
一个事务必须被视为一个不可分割的最小工作单元,整个事务要么全部提交成功,要么全部失败回滚
一致性(consistency)
数据库总是从一个一致性的状态转换到另外一个一致性的状态。也就是事务没有进行提交不会将数据保存到数据库中
隔离性(isolation)
一个事务所做的修改在最终提交以前, 对其他事务不可见
持久性(durability)
一旦事务提交,则其所做的修改就会永久保存导数据中
MySQL 的事务隔离是在 MySQL. ini 配置文件里添加的,在文件的最后添加:transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。
隔离级别
隔离级别 | 说明 | 脏读可能性 | 不可重复可读性 | 幻读可能性 | 加锁读 |
---|---|---|---|---|---|
read uncommitted | 未提交读 | Yes | Yes | Yes | NO |
read committed | 提交读 | NO | Yes | Yes | NO |
repeatable read | 可重复读 | NO | NO | Yes | NO |
serializable | 可串行化 | NO | NO | NO | Yes |
MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control)
可以认为MVCC是行级锁的一个变种
InnoDB的MVCC:
select:
InnoDB会根据以下两个条件检查每行纪录:
只有符合上述两个条件的纪录,才能返回作为查询的结果
insert:
InnoDB为新插入的每一行保存当前系统版本号作为行版本号
delete:
InnoDB为删除的每一行保存当前版本号作为行的删除标识
update:
InnoDB为插入一行新纪录,保存当前版本号作为行版本号,同时保存当前系统版本号到原来的行作为行的删除标识
START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT = {0 | 1}
行级锁、表锁、页锁,MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低。
行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高。
说一下乐观锁和悲观锁?
乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。
常用的引擎有InnoDB、MyISAM、Memory,当然经过MySQL的不断迭代和升级,目前最常用的是InnoDB,除非使用一些InnoDB没有特性,其余的情况下,建议使用InnoDB,因为在mysql5.5版本开始InnoDB已经成为MySQL的默认引擎,说明其优势有目共睹的,同时,InnoDB支持事务,在读写方面也有了很大的提升
区别
item | MyISAM | InnoDB |
---|---|---|
事务 | 不支持 | 支持 |
外键 | 不支持 | 支持 |
锁 | 表级锁 | 行级锁 |
索引 | 支持全文索引 | 5.6.4版本后支持全文索引 |
索引 | 非聚簇索引 | 聚簇索引 |
count(*) | 快,因为内部维护计数器,但存在where时,不会变快 | 慢 |
MVCC | 不支持 | 支持 |
系统奔溃 | 困难 | |
存储文件 | 三个,表结构,索引,数据 | 两个,表结构,索引和数据 |
注意
原理
优点
缺点
1、B树,每个节点都存储key和data,所有节点组成这棵树,并且叶子节点指针为nul,叶子结点不包含任何关键字信息。
2、B+树,所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接
所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)
1、联合索引是两个或更多个列上的索引。
对于联合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。
索引: 最左原则
a b c
a b
a
a c // 只使用 a 的索引
b c // 无法锁定索引
匹配:
全值匹配
a = 2 and b = 2 and c =2
匹配最左前缀
a = 2
匹配列前缀
a like '2%'
匹配范围值
a BETWEEN 2 and 10
精确匹配某一列并范围匹配另一列
a = 2 and b like '2%'
只访问索引的查询
注意: 范围查询后的所有索引无法使用
1、表记录太少
2、经常插入、删除、修改的表
3、数据重复且分布平均的表字段,假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提高数据库的查询速度。
4、经常和主字段一块查询但主字段索引值比较多的表字段
分区表是一个独立的逻辑表,但底层由多个物理子表组成。从底层文件系统来看,每一个分区表都有一个使用 # 分隔命名的表文件
分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。
分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。
命令:show variables like '%partition%' 运行结果:
have_partintioning 的值为YES,表示支持分区。
写完sql , 尽量使用explain进行分析下,sql是否命中索引,以及是否有优化的空间
工作
具体步骤(此步骤适用于主库和从库都是刚搭建)
log_bin = mysql-bin
# 介于 1 ~ 2^32 -1 之间
server_id = 10
log_bin = mysql-bin
server_id = 2
# 指定中继日志的位置
relay_log = /var/lib/mysql/mysql-relay-bin
# 允许备库将其重放的时间也纪录到自身的二进制日志中
log_slave_updates = 1
# 阻止任何没有特权权限的线程修改数据
read_only =1
mysql> change master to MASTER_HOST = ‘server1’,
-> MASTER_USER = ‘repl’,
-> MASTER_PASSWORD =‘password’,
-> MASTER_LOG_FILE = ‘mysql-bin.000001’,
-> MASTER_LOG_POS =0;
注意:
1、MASTER_LOG_POS 参数被设置为0,因为要从日志的开头读起。
2、可以使用 SHOW SLAVE STATUS 语句检查复制是否正确执行
mysql> START SLAVE