一、事务
所谓事务(Transcation),它是一个操作序列,这些操作要么全部执行,要么不执行,它是个不可分割的工作单位。事务的四大特性:
1 ACID四大特性
Atomicity(原子性)
原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。
Consistency(一致性)
一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
Isolation(隔离性)
多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。
这指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。
Durability(持久性)
持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
2 事务的并发问题(4类)
一个庞大的业务系统,一般会有多个线程同时访问数据库,容易产生如下4种并发问题:
丢失修改:
两个事务T1,T2读入同一数据并修改,T2提交的结果被T1破坏了,导致T1的修改丢失。(订票系统)
脏读:
事务T1修改某个数据并写回磁盘,事务T2读取同一数据,但T1由于某种原因撤销了,这时T1修改过的数据恢复原来的值,T2读取的数据就与数据库中的数据不一致。
不可重复读:
不可重复读的重点是修改,同样条件下两次读取结果不同,也就是说,被读取的数据可以被其它事务修改;
幻读:
幻读的重点在于新增或者删除,同样条件下两次读出来的记录数不一样。
3 事务的隔离等级(4个)
为了避免上面出现几种情况在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同 。Mysql的InnoDB引擎都支持。Mysql的默认隔离级别是可重复读。
未提交读(Read Uncommitted)
最低级别的隔离,通常又称为dirty read,它允许一个事务读取另一个事务还没 commit 的数据,这样可能会提高性能,但是会导致脏读问题;
提交读(Read Committed)
在一个事务中只允许对其它事务已经 commit 的记录可见,该隔离级别不能避免不可重复读问题;
可重复读(Repeatable Read)
在一个事务开始后,其他事务对数据库的修改在本事务中不可见,直到本事务 commit 或 rollback。但是,其他事务的 insert/delete 操作对该事务是可见的,也就是说,该隔离级别并不能避免幻读问题。在一个事务中重复 select 的结果一样,除非本事务中 update 数据库。
可序列化(Serializable)
最高级别的隔离,只允许事务串行执行。
MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关:
-
- MyISAM:不支持事务,用于只读程序提高性能;
- InnoDB:支持ACID事务、行级锁、并发;
- Berkeley DB:支持事务。
4 数据库的锁(4个)
锁是实现并发控制的一个非常重要的技术,所谓锁就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。常见的锁包括以下4种:
排他锁(写锁):
若事务T对数据对象A加写锁,则只允许T读取和修改A,其他事务都不能再对A加任何类型的锁,直到T释放A上的锁为止。
共享锁(读锁):
若事务T对数据对象A加读锁,则只允许T可以读取但不能修改A,其他事务只能再对A加读锁,而不能加写锁,直到T释放A上的读锁为止。
悲观锁:
悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为所有的操作均会导致并发安全问题,因此要先确保获取锁成功再进行业务操作。通常来讲,在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select … for update时会获取被select中的数据行的行锁,因此其他并发执行的select … for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。
MySQL InnoDB默认行级锁。行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住,这点需要注意。
乐观锁:
乐观锁的特点先进行业务操作,只在最后实际更新数据时进行检查数据是否被更新过,若未被更新过,则更新成功;否则,失败重试。乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。一般的做法是在需要锁的数据上增加一个版本号或者时间戳,然后按照如下方式实现:
查询出商品信息 select (status,status,version) from t_goods where id=#{id} 根据商品信息生成订单 修改商品status为2 update t_goods set status=2,version=version+1 where id=#{id} and version=#{version};
一般情况下,读多写少更适合用乐观锁,读少写多更适合用悲观锁。乐观锁在不发生取锁失败的情况下开销比悲观锁小,但是一旦发生失败回滚开销则比较大,因此适合用在取锁失败概率比较小的场景,可以提升系统并发性能。
5 小结
事务的ACID是有关系数据库管理系统(RDBMS)来实现的,RDBMS采用日志来保证事务的原子性(A)、一致性(C)、持久性(D)。日志记录了事务对数据库所做的更新,如果某个事务在执行过程中发生错误,就可以根据日志,撤销事务对数据库已做的更新,使数据库退回到执行事务前的初始状态。
RDBMS通过采用锁机制来实现事务的隔离性(I)。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。
二、索引
索引是对数据库表中一个或多个列的值进行排序的数据结构,以协助快速查询、更新数据库表中数据。
你也可以这样理解:索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。
索引的优点
-
- 索引可以避免全表扫描。多数查询可以仅扫描少量索引页及数据页,而不是遍历所有数据页。
- 对于非聚集索引,有些查询甚至可以不访问数据页。
- 聚集索引可以避免数据插入操作集中于表的最后一个数据页。
- 一些情况下,索引还可用于避免排序操作。
索引的缺点
-
-
- 时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度;
- 空间方面:索引需要占物理空间。
-
索引的分类:索引分为聚集索引和非聚集索引两类;InnoDB 主键使用的是聚集索引,MyISAM 不管是主键索引,还是二级索引使用的都是非聚集索引。
聚集索引
表中各行的物理顺序与键值的逻辑(索引)顺序相同。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。在聚集索引中,叶结点也即数据结点,所有数据行的存储顺序与索引的存储顺序一致。
在一张表上只能创建一个聚集索引,因为真实数据的物理顺序只可能是一种。如果一张表没有聚集索引,那么它被称为“堆集”(Heap)。这样的表中的数据行没有特定的顺序,所有的新行将被添加的表的末尾位置。聚集索引对应的缺点就是修改慢,因为为了保证表中记录的物理和索引顺序一致,在记录插入的时候,会对数据页重新排序。
非聚集索引
表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,该层紧邻数据页,其行数量与数据表行数据量一致。
非聚集索引与聚集索引相比:
-
-
- 叶子结点并非数据结点
- 叶子结点为每一真正的数据行存储一个“键-指针”对
- 叶子结点中还存储了一个指针偏移量,根据页指针及指针偏移量可以定位到具体的数据行。
- 类似的,在除叶结点外的其它索引结点,存储的也是类似的内容,只不过它是指向下一级的索引页的。
- 表数据存储顺序与索引顺序无关。而聚集索引表中各行的物理顺序与键值的逻辑(索引)顺序相同
- 每张表可以有多个非聚集索引,而聚集索引只能有一个。
-
索引的实现原理
索引的底层数据结构是B+树。在数据结构中,我们最为常见的搜索结构就是二叉搜索树和AVL树(高度平衡的二叉搜索树,为了提高二叉搜索树的效率,减少树的平均搜索长度)了。然而,无论二叉搜索树还是AVL树,当数据量比较大时,都会由于树的深度过大而造成I/O读写过于频繁,进而导致查询效率低下,因此对于索引而言,多叉树结构成为不二选择。
为什么用B+树不用B树:B+树在非叶子结点不保存数据,只在叶子结点保存。而B树在叶子结点和非叶子结点都会保存。这种结构导致你如果用B树来进行查询,会增加磁盘IO的次数,导致性能不如B+树。
什么样的字段适合做索引
- 经常作查询选择的字段
- 经常作表连接的字段
- 经常出现在order by, group by, distinct 后面的字段
- 离散程度高、占用空间小
索引失效
索引并不是时时都会生效的,比如以下几种情况,将导致索引失效:
-
- 如果条件中有or,即使其中有条件带索引也不会使用。 >要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
- 对于多列索引,不是使用的第一部分,则不会使用索引。
- like查询是以%开头。
- 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。
- 如果 mysql 估计使用全表扫描要比使用索引快,则不使用索引。例如,使用
<>
、not in
、not
exist
,对于这三种情况大多数情况下认为结果集很大,MySQL就有可能不使用索引。
Mysql中如何添加索引
mysql中常见的索引包括主键索引(PRIMARAY KEY)、唯一索引(UNIQUE KEY)以及普通索引(INDEX)
ALTER TABLE table_name ADD INDEX index_name (column_list) ALTER TABLE table_name ADD UNIQUE (column_list) ALTER TABLE table_name ADD PRIMARY KEY (column_list)
三、Mysql存储引擎
在MySQL 5.5之前,MyISAM是mysql的默认数据库引擎,其由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良。虽然MyISAM性能极佳,但却有一个显著的缺点: 不支持事务处理。不过,MySQL也导入了另一种数据库引擎InnoDB,以强化参考完整性与并发违规处理机制,后来就逐渐取代MyISAM。
InnoDB是MySQL的数据库引擎之一,其由Innobase oy公司所开发,2006年五月由甲骨文公司并购。与传统的ISAM、MyISAM相比,InnoDB的最大特色就是支持ACID兼容的事务功能,类似于PostgreSQL。目前InnoDB采用双轨制授权,一是GPL授权,另一是专有软件授权。具体地,MyISAM与InnoDB作为MySQL的两大存储引擎的差异主要包括:
事务支持:MyISAM强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。InnoDB提供事务、外键等高级数据库功能,具有事务提交、回滚和崩溃修复能力。
表锁差异:MyISAM只支持表级锁,用户在操作MyISAM表时,select、update、delete和insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。InnoDB支持事务和行级锁。行锁大幅度提高了多用户并发操作的新能,但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。
外键:MyISAM不支持外键,而InnoDB支持外键。
不管是MyISAM还是InnoDB,索引使用的底层数据结构都是B+树。
MyIASM引擎,B+树的数据结构中存储的内容实际上是实际数据的地址值。也就是说它的索引和实际数据是分开的,只不过使用索引指向了实际数据。这种索引的模式被称为非聚集索引。
Innodb引擎的索引的数据结构也是B+树,只不过数据结构中存储的都是实际的数据,这种索引被称为聚集索引。
四、数据库常用操作
在数据库原理中,关系运算包含 选择、投影、连接 这三种运算。相应的在SQL语句中也有表现,其中Where子句作为选择运算,Select子句作为投影运算,From子句作为连接运算。
连接运算是从两个关系的笛卡尔积中选择属性间满足一定条件的元组,在连接中最常用的是等值连接和自然连接。
-
- 等值连接:关系R、S,取两者笛卡尔积中属性值相等的元组,不要求属性相同。比如
R.A=S.B
- 自然连接(内连接):是一种特殊的等值连接,它要求比较的属性列必须是相同的属性组,并且把结果中重复属性去掉。
- 等值连接:关系R、S,取两者笛卡尔积中属性值相等的元组,不要求属性相同。比如
Join的常见用法
-
- INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录。
- LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。
- RIGHT JOIN(右连接):与 LEFT JOIN 相反,取得右表(table2)完全记录,即是左表(table1)并无匹配对应记录。
UNION常见用法
union :用于合并多个 select 语句的结果集,并去掉重复的值。 union all :作用和 union 类似,但不会去掉重复的值。
Join、Union、group by、order by、select、insert、update、delete等操作就不在此过多介绍了,详细查看:
http://www.runoob.com/mysql/mysql-union-operation.html
https://github.com/hadyang/interview/blob/master/basic/database/join.md
参考链接
https://github.com/hadyang/interview/tree/master/basic/database
https://www.cnblogs.com/wmyskxz/p/9067197.html
原文地址:https://www.cnblogs.com/kukri/p/9630889.html