Storage engine
1. What is a storage engine and what is it useful for?
存储引擎是MySQL中特有的一个术语,其他数据库没有(oracle数据库中有,但是不叫这个名字)
实际上存储引擎是一个表存储/组织数据的方式
不同的存储引擎,表存储数据的方式不同
2. How to add/specify storage engine to the table?
可以在建表的时候给表指定存储引擎
语法格式:
create table table_name(
id int primary key,
name varchar(255)
)engine=InnoDB default charset=utf8/gbk
在建表的时候可以在最后小括号“)”的右边使用
ENGINE来指定存储引擎
CHARSET来指定这张表的字符编码方式
MySQL默认的存储引擎是:InnoDB
MySQL默认的字符编码方式是:utf8
3. Check which storage engines MySQL supports
语法:
show engines \G
mysql> show engines \G
*************************** 1. row ***************************
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 2. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 3. row ***************************
Engine: CSV
Support: YES
Comment: CSV storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 4. row ***************************
Engine: FEDERATED
Support: NO
Comment: Federated MySQL storage engine
Transactions: NULL
XA: NULL
Savepoints: NULL
*************************** 5. row ***************************
Engine: PERFORMANCE_SCHEMA
Support: YES
Comment: Performance Schema
Transactions: NO
XA: NO
Savepoints: NO
*************************** 6. row ***************************
Engine: MyISAM
Support: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 7. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 8. row ***************************
Engine: BLACKHOLE
Support: YES
Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
XA: NO
Savepoints: NO
*************************** 9. row ***************************
Engine: ARCHIVE
Support: YES
Comment: Archive storage engine
Transactions: NO
XA: NO
Savepoints: NO
9 rows in set (0.00 sec)
MySQL supports nine storage engines. My current version of MySQL is 8.0.22, which supports eight. The support situation is different for different versions.
4. About MySQL's commonly used storage engines
MyISAM storage engine:
它管理的表具有以下特征:
使用三个文件表示每个表:
格式文件 - 存储表结构的定义(mytable.frm)
数据文件 - 存储表行的内容(mytable.MYD)
索引文件 - 存储表上索引(mytable.MYI):索引是一本书的目录,缩小扫描范围,提高查询效率的一种机制。
可以被转换为压缩、只读表来节省空间
对于一张表来说,只要是有主键,或者加有unique约束的字段上会自动创建索引
MyISAM存储引擎特点:
可被转换为压缩、只读表来节省空间
这是这种存储引擎的优势!!!!
MyISAM不支持事务机制,安全性低。
InnoDB storage engine
这是MySQL默认的存储引擎,同时也是一个重量级的存储引擎
InnoDB存储引擎支持事务,支持数据库崩溃后自动恢复机制
InnoDB存储引擎最主要的特点是:非常安全!
它管理的表具有下列主要特征:
每个InnoDB表在数据库目录中以.frm格式文件表示
InnoDB表空间tablespace被用于存储表的内容(表空间是一个逻辑名称,表空间存储数据 + 索引)
提供一组用来记录事务性活动的日志文件
用COMMIT(提交)、SAVEPOINT及ROLLBACK(回滚)支持事务处理
提供全ACID兼容
在MySQL服务器崩溃后提供自动恢复
多版本(MVCC)和行级锁定
支持外键及引用的完整性,包括级联删除和更新
InnoDB最大的特点就是支持事务:
以保证数据的安全!效率不是很高,并且也不能压缩,不能转换为只读,不能很好的节省存储空间。
MEMORY storage engine
使用MEMORY存储引擎的表,其数据存储在内存中,且行的长度固定
这两个特点使得MEMORY存储引擎非常快。
MEMORY存储引擎管理的表具有下列特征:
在数据库目录内,每个表均以.frm格式的文件表示
表数据及索引被存储在内存中(目的就是快,查询快!)
表级锁机制
不能包含TEXT和BLOB字段
MEMORY存储引擎以前被称为HEAP引擎。
MEMORY存储引擎优点:查询效率是最高的,不需要和硬盘交互
MEMORY存储引擎缺点:不安全,关机之后数据消失,因为数据和索引都是在内存当中。
Affairs [Key points ***** requires understanding and mastering]
1. What is a transaction?
一个事务其实就是一个完整的业务逻辑,是一个最小的工作单元,不可再分。
什么是一个完整的业务逻辑?
如:
假设转账,从A账户向B账户转账10000元
将A账户的钱减去10000元(update语句)
将B账户的钱加上10000元(update语句)
这就是一个完整的业务逻辑
以上的操作是一个最小的工作单元,要么同时成功,要么同时失败,不可再分。
这两个update语句要求必须同时成功或者同时失败,这样才能保证钱是正确的。
2. Only DML statements can have transactions, and other statements have nothing to do with transactions! ! !
insert
delete
update
只有以上三个语句和事务有关系,其他都没有关系。
因为只有以上的三个语句是对数据库表中数据进行增、删、改的。
只要你的操作一旦涉及到数据的增、删、改,那么就一定要考虑安全问题
数据安全第一位!!!
3. Assuming that all businesses can be completed with just one DML statement, is there a need for a transaction mechanism?
正是因为做某件事的时候,需要多条DML语句共同联合起来才能完成,所以需要事务的存在,如果任何一件复杂的事儿都能一条DML语句搞定,那么事务则没有存在的价值了。
到底什么是事务呢?
本质上,一个事务其实就是多条DML语句同时成功,或者同时失败!
事务:就是批量的DML语句同时成功,或者同时失败!
4. How does the transaction succeed or fail at the same time for multiple DML statements?
InnoDB存储引擎:提供一组用来记录事务性活动的日志文件
例如:
事务开启了
insert
insert
insert
delete
update
update
update
事务结束了
在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中。
在事务的执行过程中,我们可以提交事务,也可以回滚事务。
提交事务:
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。
提交事务标志着:事务的结束,并且是一种全部成功的结束。
回滚事务:
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件
回滚事务标志着:事务的结束,并且是一种全部失败的结束。
5. How to commit the transaction and how to roll back the transaction
Commit the transaction: commit;
Rollback transaction: rollback; (rollback always can only be rolled back to the last commit point)
The corresponding English word for transaction is: transaction
What is the default transaction behavior in MySQL?
MySQL supports automatic transaction commit by default. (Automatic submission)
What is automatic submission?
Every time a DML statement is executed, submit it once!
How to turn off the automatic submission mechanism of MySQL?
First execute this command: start transaction;
Demonstrate rollback transaction:
mysql> select * from emp2;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from emp2;
Query OK, 14 rows affected (0.17 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.14 sec)
mysql> select * from emp2;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)
mysql> delete from emp2;
Query OK, 3 rows affected (0.18 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> select * from emp2;
+-------+-------+------+------+------------+---------+----------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+-------+------+------+------------+---------+----------+--------+
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
+-------+-------+------+------+------------+---------+----------+--------+
4 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.10 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
Demonstrate manual commit transaction
mysql> select * from emp2;
Empty set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> insert into emp2 values(1,'ALEX','CEO',7839,'1980-02-18',4000,10000,12);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.03 sec)
mysql> select * from emp2;
+-------+-------+------+------+------------+---------+----------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+-------+------+------+------------+---------+----------+--------+
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
+-------+-------+------+------+------------+---------+----------+--------+
4 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from emp2;
+-------+-------+------+------+------------+---------+----------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+-------+------+------+------------+---------+----------+--------+
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
| 1 | ALEX | CEO | 7839 | 1980-02-18 | 4000.00 | 10000.00 | 12 |
+-------+-------+------+------+------------+---------+----------+--------+
4 rows in set (0.00 sec)
At this point, you can see that the rollback can only be rolled back to the point of the last submission!
6. The transaction includes four characteristics
A:原子性
说明事务是最小的工作单元,不可再分。
B:一致性
所有的事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。
C:隔离性
A事务和B事务之间具有一定的隔离。
如:教室A和教室B之间有一道墙,这道墙就是隔离性。
A事务在操作一张表的时候,另一个事务B也操作这张表会怎么样?
D:持久性
事务最终结束的一个保障,事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上!
7. Focus on the isolation of transactions! ! !
There is a wall between classroom A and classroom B. This wall can be very thick or very thin. This is the isolation level of affairs.
The thicker the wall, the higher the isolation level
What are the isolation levels between transactions and transactions? (4 levels)
读未提交:read uncommitted(最低的隔离级别)
什么是读未提交?
事务A可以读取到事务B未提交的数据
这种隔离级别存在的问题就是:
脏读现象(Dirty Read)
我们称读到了脏数据
这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是二档起步!
读已提交:read committed
什么是读已提交?
事务A只能读取到事务B提交之后的数据
这种隔离级别解决了什么问题?
解决了脏读的现象
这种隔离级别存在什么问题?
不可重复读取数据
什么是不可重复读取数据呢?
在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4,等位不可重复读取。
这种隔离级别是比较真实的数据,每一次读到的数据是绝对的真实。
oracle数据库默认的隔离级别是:read committed
可重复读:repeatable read (提交之后也读不到,永远读取的都是刚开启事务时的数据)
什么是可重复读取?
事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的,即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变,这就是可重复读。
可重复读解决了什么问题?
解决了不可重复读取数据
可重复读存在的问题是什么?
可能会出现幻读。
每一次读取到的数据都是幻象,不够真实!
如:早晨9点开启了事务,只要事务不结束,到晚上9点,读取到的数据还是那样!读到的是假象,不够绝对的真实。
MySQL中默认的事务隔离级别就是这个!!!!!
序列化/串行化:serializable(最高的隔离级别)
这是最高隔离级别,效率最低,解决了所有的问题。
这种隔离级别表示事务排队,不能并发!
synchronized,线程同步(事务同步)
每一次读取到的数据都是最真实的,并且效率是最低的!
8. Verify various isolation levels
View the isolation level: select @@tx_isolation; (select @@global.transaction_isolation;)
Use select @@tx_isolation; when viewing the isolation level of the transaction, if an error is reported (Unknown system variable'tx_isolation'), replace it with select @@global.transaction_isolation;
Table being tested: emp2
verification: read uncommitted
先修改事务的隔离级别为:read uncommitted
set global transaction isolation level read uncommitted;
Then open two terminals and test the read.
After the rollback is not submitted , the data found in the other table is also empty.
Verification: read committed
Table being tested: user
先修改事务的隔离级别为:read committed
set global transaction isolation level read committed;
Verification: repeatable read
先修改事务的隔离级别为:repeatable read
set global transaction isolation level repeatable read;
As shown in the figure: After both parties open the transaction, no matter how the transaction on the right terminal modifies, submits or even deletes the data in the table, the transaction on the left terminal still finds the same data.
Verification: serializable
先修改事务的隔离级别为:serializable
set global transaction isolation level serializable;
It can be seen that the transaction on the right terminal cannot view the data in the table, the cursor keeps flashing, and the data cannot be viewed. When the transaction on the left terminal is submitted, the transaction on the right will be executed successfully!