⑤MySQL之约束二

1,事务(Transaction)

1.1,什么是事务?
一个事务是一个完整业务逻辑单元,不可再分。

比如:银行账户转账,从A账户向B账户转账10000,需要执行两条update语句
    update t_act set balance = balance - 10000 where actno = 'act-001';
    update t_act set balance = balance + 10000 where actno = 'act-002';
以上两条DML语句必须同时成功,或同时失败,不允许出现一条成功,一条失败

要想保住以上两条DML语句同时成功或者同时失败,那么就需要使用数据库的“事务机制”。
1.2,和事务相关的语句只有DML语句。(insert delete update)
这三个语句都是和数据库表当中的“数据”相关的,事务的存在是为了保住数据的完整性,安全性。
1.3,假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗?
不需要,但实际情况不是这样的,通常一个“事儿(事务【业务】)”需要多条DML语句共同联合完成。
1.4,事务包括四大特征:ACID
A:原子性:事务是最小的工作单元,不可再分。
C:一致性:事务必须保证多条DML语句同时成功或失败。
I:隔离性:事务A和B之间具有隔离。
D:持久性:说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。
1.5,事务之间的隔离性
事务隔离性存在隔离级别,理论上隔离级别包括4个:
    第一级别:读未提交(read uncommitted)
        对方事务还未提交,我们当前事务可以读取到对方未提交的数据。
        读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。
    第二级别:读已提交(read committed)
        对方事务提交之后的数据我方可以读取到。
        读已提交存在的问题:不可重复读。
    第三级别:可重复读(repeatable read)
        这种隔离级别解决了:不可重复读问题。
        可重复读存在问题:读取到的数据是幻象的
    第四级别:序列化读/串行化读(serializable)
        解决了所有问题,
        存在问题:效率低,事务需要排队。

    oracle数据库默认的隔离级别是:读已提交。
    mysql数据库默认的隔离级别是:可重复读。
1.6,演示事务
mysql事务是默认情况下自动提交的。(只要执行任意一条DML语句则提交一次。)
关闭自动提交:start transaction;

准备一个表
    drop table if exists t_user;
    create table t_user(
        id int primary key auto_increment,
        username varchar(255) unique
    );
---------------------------------------------------------------------------------------------
演示:(插入一条记录,rollback回滚,再次查询还是有一条记录,说明:要执行DML语句就会提交一次。)
    mysql>
        insert into t_user(username) values('e');
        select * from t_user;

        +----+----------+
        | id | username |
        +----+----------+
        |  1 | e        |
        +----+----------+

    mysql>
        rollback;
        select * from t_user;
        +----+----------+
        | id | username |
        +----+----------+
        |  1 | e        |
        +----+----------+
---------------------------------------------------------------------------------------------
演示:使用start transaction;关闭自动提交机制。
    mysql>
        start transaction;
        insert into t_user(username) values('es'),('ls');
        select * from t_user;

        +----+----------+
        | id | username |
        +----+----------+
        |  1 | e        |
        |  2 | es       |
        |  3 | ls       |
        +----+----------+

    mysql>
        rollback;
        select * from t_user;

        +----+----------+
        | id | username |
        +----+----------+
        |  1 | e        |
        +----+----------+
---------------------------------------------------------------------------------------------
演示提交:commit;
    mysql>
        start transaction;
        insert into t_user(username) values('es'),('ls'),('lss');
        select * from t_user;

        +----+----------+
        | id | username |
        +----+----------+
        |  1 | e        |
        |  4 | es       |
        |  5 | ls       |
        |  6 | lss      |
        +----+----------+

    mysql>
        commit;
        rollback;
        select * from t_user;

        +----+----------+
        | id | username |
        +----+----------+
        |  1 | e        |
        |  4 | es       |
        |  5 | ls       |
        |  6 | lss      |
        +----+----------+
1.7,使用事务的隔离级别
设置事务的全局隔离级别:
    set global transaction isolation level 级别;
    set global transaction isolation level read uncommitted;
    set global transaction isolation level read committed;
    set global transaction isolation level repeatable read;
    set global transaction isolation level serializable;
查看事务的全局隔离级别:
    MySQL8.0以前:select @@global.tx_isolation;
    MySQL8.0及以以上版本:select @@global.transaction_isolation

2,索引(是给字段添加索引)

2.1,什么是索引,有什么用?
索引相当于一本书的目录,通过目录可以快速的找到对应的资源
在数据库方面,查询一张表的时候有两种检索方式:
    第一种方式:全表扫描
    第二种方式:根据索引检索(效率高)

索引为什么可以提高检索效率
    根本原因是缩小了扫描范围。

索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引在数据库中的对象,也需要
不断的维护,是有维护成本的。比如:表中的数据经常被修改,这样就不适合添加索引,因为数据
一旦修改,索引需要重新排序,进行维护。
2.2,怎么创建索引对象,怎么删除索引对象?
创建索引对象:create index 索引名称 on 表名(字段名);
删除索引对象:drop index 索引名称 on 表名;
2.3,什么时候给字段添加索引?(满足什么条件)
数据量庞大
该字段很少的DML操作
该字段经常出现在where字句中。
2.4,主键和具有unique约束的字段会自动添加索引。
2.5,查看sql语句的执行计划(执行详情):explain select语句;
mysql> explain select ename,sal from emp where sal = 5000;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   14 |    10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+

给薪资sal字段添加索引
    create index emp_sal_index on emp(sal);

mysql> explain select ename,sal from emp where sal = 5000;
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | emp   | NULL       | ref  | emp_sal_index | emp_sal_index | 9       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+

删除sal字段的索引
    drop index emp_sal_index on emp;
2.6,索引底层采用的数据结构:B + Tree
2.7,索引的实现原理
通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的“物理地址”,最终通过索引检索到
数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率是最高的。
2.8,索引的分类:
单一索引:给单个字段添加索引
复合索引:给多个字段联合起来添加一个索引
主键索引:主键上会自动添加索引
唯一索引:有unique约束的字段会自动添加索引。
...
2.9,索引什么时候失效?
模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的。

3,视图(view)

3.1,什么是视图
站在不同的角度去看数据。
3.2,怎么创建视图,怎么删除视图
复制一张表
create table emp_bak as select * from emp;

创建视图
create view emp_bak_view as select empno,ename,sal from emp_bak;
删除视图
drop view emp_bak_view;

注意:只要DQL语句才能以视图对象的方式创建出来。
3.3,对视图进行增删改查,会影响原表数据。(通过视图影响原表数据,不是直接操作的原表)
可以对视图进行CRUD操作
3.4,面向视图操作
mysql> select * from emp_bak_view;
    +-------+--------+---------+
    | empno | ename  | sal     |
    +-------+--------+---------+
    |  7369 | SMITH  |  800.00 |
    |  7499 | ALLEN  | 1600.00 |
    |  7521 | WARD   | 1250.00 |
    |  7566 | JONES  | 2975.00 |
    |  7654 | MARTIN | 1250.00 |
    |  7698 | BLAKE  | 2850.00 |
    |  7782 | CLARK  | 2450.00 |
    |  7788 | SCOTT  | 3000.00 |
    |  7839 | KING   | 5000.00 |
    |  7844 | TURNER | 1500.00 |
    |  7876 | ADAMS  | 1100.00 |
    |  7900 | JAMES  |  950.00 |
    |  7902 | FORD   | 3000.00 |
    |  7934 | MILLER | 1300.00 |
    +-------+--------+---------+

通过视图修改原表数据
mysql>
    update emp_bak_view set ename = 'hehe',sal = 1 where empno = 7369;
    select * from emp_bak;
    +-------+--------+-----------+------+------------+---------+---------+--------+
    | EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    |  7369 | hehe   | CLERK     | 7902 | 1980-12-17 |    1.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 |
    +-------+--------+-----------+------+------------+---------+---------+--------+

通过视图删除原表数据
mysql>
    delete from emp_bak_view where empno = 7369;
    select * from emp_bak;
    +-------+--------+-----------+------+------------+---------+---------+--------+
    | EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    |  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 |
    +-------+--------+-----------+------+------------+---------+---------+--------+
3.5,视图的作用
视图可以隐藏表的实现细节,保密级别较高的系统,数据库只对外提供相关的视图,java程序员
只对视图对象进行CRUD。

4,DBA命令

4.1,数据导出
导出整个数据库:mysqldump 数据库名称>路径数据库名.sql -uroot -p
导出某一张表:mysqldump 数据库名称 表名>路径数据库名.sql -uroot -p
4.2,数据导入
create database 数据库名称;
use 数据库名称;
source 路径数据库名.sql

5,数据库设计三范式

5.1,什么是设计范式
设计表的依据,按照这三个范式设计的表不会出现数据冗余。
5.2,三范式
第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分。
第二范式:建立在第一范式的基础之上,所有的非主键字段完全依赖主键,不能产生部分依赖。
(多对多,三张表,关系表两个外键)
第三范式:建立在第二范式的基础之上,所有的非主键字段直接依赖主键,不能产生传递依赖。
(一对多,两张表,多的表加外键)

6,悲观锁乐观锁

悲观锁:事务必须排队执行,数据锁住了,不允许并发。(行级锁:select语句后面加:for update)
乐观锁:支持并发,事务不需要排队,只不过需要一个版本号。

上篇:④MySQL之约束一

你可能感兴趣的:(⑤MySQL之约束二)