目录
    
   
    
     2、和事务相关的语句只有:DML语句。(insert delete update)
    
   
    一.存储引擎(了解)
   
    1.什么是存储引擎?存储引擎有什么用?
   
存储引擎这个名字只有在mysql中存在。(Oracle中有对应的机制,但是不叫做存储引擎。Oracle中没有特殊的名字, 就是“表的存储方式”)
mysql支持很多存储引擎,每一个存储引擎都对应了一种不同的存储方式。 每一个存储引擎都有自己的优缺点,需要在合适的时机选择合适的存储引擎。
    2.怎么给表添加常用的引擎
   
查询创建表时使用的引擎
show create table t_student;显示表创建时的信息,外加使用到得引擎信息
| t_student | CREATE TABLE `t_student` (
  `sno` int NOT NULL,
  `sname` varchar(255) DEFAULT NULL,
  `classno` int DEFAULT NULL,
  PRIMARY KEY (`sno`),
  KEY `classno` (`classno`),
  CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 |可以在创建表的最后边“)”的右边指定所用到得字符集和引擎
ENGINE:指定引擎 CHARSET:指定字符集
默认的引擎是:InnoDB 默认的字符集是:utf8mb3
    
     将字符集更换为自己指定的
    
   
 create table t_product(
    id int primary key,
    name varchar(255)
 )engine = InnoDB default charset =gbk;查询
 show create table t_product;
| t_product | CREATE TABLE `t_product` (
  `id` int NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
    3.查看Mysql支持哪些引擎(讲的较粗)
   
命令
show engines \G支持哪些引擎看数据库的版本
Support: YES代表着支持
查看数据库版本
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.28    |
+-----------+
    4.常见的存储引擎
   
    
     MyISAM引擎
    
   
Engine: MyISAM
Support: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
    
    MyISAM这种存储引擎不支持事务。
    
    MyISAM是mysql最常用的存储引擎,但是这种引擎不是默认的。
    
    
     MyISAM采用三个文件组织一张表:
    
    
    xxx.frm(存储格式的文件)
    
    xxx.MYD(存储表中数据的文件)
    
    xxx.MYI(存储表中索引的文件)
    
    优点:可被压缩,节省存储空间。并且可以转换为只读表,提高检索效率。
    
    缺点:不支持事务。
   
    
     小知识点:
    
   
对于一张表来说,有主键或者有unique约束的字段会自动创建索引
    
     mysql当中自带的数据库mysql下的 columns_priv表格使用的就是这个引擎
    
   
mysql> show create table  columns_priv;
    
     InnoDB引擎
    
   
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
    
    优点:支持事务、行级锁、外键,mvvc(多版本)等。这种存储引擎数据的安全得到保障。
    表的结构存储在xxx.frm文件中
    
    数据存储在tablespace这样的表空间中(逻辑概念),无法被压缩,无法转换成只读。
    
    这种InnoDB存储引擎在MySQL数据库崩溃之后提供自动恢复机制。
    
    InnoDB支持级联删除和级联更新。
   
    
     最大特点:
    
   
    支持事务,以保证数据的安全。(下面会将什么是事务)
    
   
    
     MEMORY引擎
    
   
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
    特点:每个表以  .frm 为结尾   表级锁机制
    
    缺点:不支持事务。数据容易丢失。因为所有数据和索引都是存储在内存当中的。
    
    优点:查询速度最快。
    
    以前叫做HEPA引擎。
    
   
    二.事务(Transaction)很重要的章节******
   
    1.什么是事务
   
一个事务是一个完整的业务逻辑单元,要不同时成功要不同时失败,不可再分。
    
     比如:银行账户转账,从A账户向B账户转账10000.需要执行两条update语句:
    
   
    
     从A账户上减去10000元,从b账户上加入10000元
    
   
update t_act set balance = balance - 10000 where actno = 'act-001';
update t_act set balance = balance + 10000 where actno = 'act-002';
    
    以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。
   
要想保证以上的两条DML语句同时成功或者同时失败,那么就需要使用数据库的“事务机制”。
    
    2、和事务相关的语句只有:DML语句。(insert delete update)
   
    
     为什么?
    
   
    因为它们这三个语句都是和数据库表当中的“数据”相关的。
    
    事务的存在是为了保证数据的完整性,安全性。
   
    
    
     假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗?
    
   
不需要事务。
    
    但实际情况不是这样的,通常一个“事儿(事务【业务】)”需要多条DML语句共同联合完成。本质上:事务就是保证多个DML同时成功或着同时失败
   
    3.事务是如何完成多条语句同时成功或失败的
   
    
     InnoDB引擎提供了一组用来记录事务性活动的日志
    
   
事务开始了:
insert
update
insert
事务结束了
在事务执行的过程当中每一条DML语句都会记录到日志当中(保存历史记录)
在事务执行的过程当中,我们可以提交事务,也可以回滚事务
    
     提交事务?
    
   
清空日志当中的记录,将所有的数据放到表当中,永久存储。
提交事务表示事务结束,并且是一种成功的结束。
    
     回滚事务?
    
   
清空日志当中的记录,将事务当中执行的DML命令全部撤回。
表示事务结束,并且是一种失败的结束。
    4.怎么提交事务,怎么回滚事务
   
提交:commit
回滚:rollback
    mysql事务默认情况下是自动提交的。
    
    
     什么是自动提交?
    
   
只要执行任意一条DML语句则提交一次。
    
     怎么关闭自动提交?
    
   
start transaction;
准备表:
drop table if exists t_user;
create table t_user(
id int primary key auto_increment,
username varchar(255)
);    
     演示
    
    :mysql中的事务是支持自动提交的,只要执行一条DML,则提交一次。
   
 mysql> insert into t_user(username) values('zs');
 Query OK, 1 row affected (0.03 sec)
 mysql> select * from t_user;
 +----+----------+
 | id | username |
 +----+----------+
 |  1 | zs       |
 +----+----------+
 1 row in set (0.00 sec)
 mysql> rollback;
 Query OK, 0 rows affected (0.00 sec)
 mysql> select * from t_user;
 +----+----------+
 | id | username |
 +----+----------+
 |  1 | zs       |
 +----+----------+
 1 row in set (0.00 sec)
    
    
     演示:
    
    使用start transaction;关闭自动提交机制。
   
 mysql> start transaction;
 Query OK, 0 rows affected (0.00 sec)
 mysql> insert into t_user(username) values('lisi');
 Query OK, 1 row affected (0.00 sec)
 mysql> select * from t_user;
 +----+----------+
 | id | username |
 +----+----------+
 |  1 | zs       |
 |  2 | lisi     |
 +----+----------+
 2 rows in set (0.00 sec)
 mysql> insert into t_user(username) values('wangwu');
 Query OK, 1 row affected (0.00 sec)
 mysql> select * from t_user;
 +----+----------+
 | id | username |
 +----+----------+
 |  1 | zs       |
 |  2 | lisi     |
 |  3 | wangwu   |
 +----+----------+
 3 rows in set (0.00 sec)
 mysql> rollback;
 Query OK, 0 rows affected (0.02 sec)
 mysql> select * from t_user;
 +----+----------+
 | id | username |
 +----+----------+
 |  1 | zs       |
 +----+----------+
 1 row in set (0.00 sec)从关闭自动提交开始,都是被回滚的DML命令。
    
     案例:
    
    使用start transaction;关闭自动提交机制。在使用commit进行提交
   
  mysql> start transaction;
  Query OK, 0 rows affected (0.00 sec)
  mysql> insert into t_user(username) values('wangwu');
  Query OK, 1 row affected (0.00 sec)
  mysql> insert into t_user(username) values('rose');
  Query OK, 1 row affected (0.00 sec)
  mysql> insert into t_user(username) values('jack');
  Query OK, 1 row affected (0.00 sec)
  mysql> select * from t_user;
  +----+----------+
  | id | username |
  +----+----------+
  |  1 | zs       |
  |  4 | wangwu   |
  |  5 | rose     |
  |  6 | jack     |
  +----+----------+
  4 rows in set (0.00 sec)
  mysql> commit;
  Query OK, 0 rows affected (0.04 sec)
  mysql> select * from t_user;
  +----+----------+
  | id | username |
  +----+----------+
  |  1 | zs       |
  |  4 | wangwu   |
  |  5 | rose     |
  |  6 | jack     |
  +----+----------+
  4 rows in set (0.00 sec)
  mysql> rollback;
  Query OK, 0 rows affected (0.00 sec)
  mysql> select * from t_user;
  +----+----------+
  | id | username |
  +----+----------+
  |  1 | zs       |
  |  4 | wangwu   |
  |  5 | rose     |
  |  6 | jack     |
  +----+----------+
  4 rows in set (0.00 sec) 使用commit之后,日志当中的DML命令清空,所以回滚之后没有变化。
    演示两个事务,假如隔离级别
    
    演示第1级别:读未提交
    
    set global transaction isolation level read uncommitted;
    
    演示第2级别:读已提交
    
    set global transaction isolation level read committed;
    
    演示第3级别:可重复读
    
    set global transaction isolation level repeatable read;
    mysql远程登录:mysql -h192.168.151.18 -uroot -p444
    
   
    
     5.事务的特性
    
   
    
     事务包括四大特性:ACID
    
    
    
     A: 原子性
    
    :事务是最小的工作单元,不可再分。
    
    
     C: 一致性
    
    :事务必须保证多条DML语句同时成功或者同时失败,保证数据的一致性。
    
    
     I:隔离性
    
    :事务A与事务B之间具有隔离,类似于多线程并发访问同一张表。
    
    
     D:持久性
    
    :持久性说的是最终数据必须持久的保存到硬盘文件中。
   
    
    
     6.事务之间的隔离性
    
   
    
     类比:
    
   
事务A和事务B之间的墙可能会很薄也可能会很厚。隔离级别越高,强越厚。
    事务隔离性存在隔离级别,理论上隔离级别包括4个:
    
    
     第一级别:
    
    读未提交(read uncommitted)
    
    事务A可以读取到事务B还未提交的数据。
    
    读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。
   
理论上的级别,显示当中,数据库都是二挡起步的。
    
    
     第二级别:
    
    读已提交(read committed)
    
    对方事务提交之后的数据我方可以读取到。
    
    这种隔离级别解决了: 脏读现象没有了。
    
    读已提交存在的问题是:每一次读到的数据都不一样,不可重复读,读到的数据都是真实的数据。
   
    
    
     第三级别:
    
    可重复读(repeatable read)
    
    这种隔离级别解决了:不可重复读问题。
    
    这种隔离级别存在的问题是:读取到的数据是幻象。
    
    
     第四级别:
    
    序列化读/串行化读(serializable)
    
    解决了所有问题。
    
    效率低。需要事务排队。
    oracle数据库默认的隔离级别是:读已提交。(第二级别)
    
    mysql数据库默认的隔离级别是:可重复读。(第三级别)
   
    
     第一级:
    
    A事务读到B事务未提交的数据,脏读问题。
    
     第二级:
    
    读到已提交的数据,事务还没有结束,就可以读到DML语句添加的数据了,称为不可重复读取,但读到的数据都是真实的。
    
     第三级:
    
    在事务A执行的时候,不管多久,每次事务A读取到的数据都是一致的,尽管事务B将数据已经给修改了,事务A读到的数据依旧没有变化。读到的都是幻想,数据已将变了,但是事务A看不到。
    
     第四级:
    
    事务排队,一次只处理一个事务,但不能并发,但是解决了所有问题。有些挥刀自宫的味道了。
   
    
     还有演示但是太多,懒得写了
    
   
大致就是打开两个cmd窗口,进行双线操作,模仿并发,分别观看四个隔离级别对于数据查询的影响。
    三.索引(index)
   
    1、什么是索引?有什么用?
   
索引就相当于一本书的目录,通过目录可以快速的找到对应的资源。
    
     对于一本字典来说,查找某个汉字有两种方式:
    
    
    
     第一种方式
    
    :一页一页挨着找,直到找到为止,这种查找方式属于全字典扫描。
    
    效率比较低。
    
    
     第二种方式
    
    :先通过目录(索引)去定位一个大概的位置,然后直接定位到这个
    
    位置,做局域性扫描,缩小扫描的范围,快速的查找。这种查找方式属于通过
    
    索引检索,效率较高。
   
    
    
     在数据库方面,查询一张表的时候有两种检索方式:
    
    
    第一种方式:全表扫描
    
    第二种方式:根据索引检索(效率很高)
   
    
     索引为什么可以提高检索效率呢?
    
    
    在实际中,汉语字典前面的目录是排序的,按照a b c d e f….排序,
    
    为什么排序呢?因为只有排序了才会有区间查找这一说!(缩小扫描范围
    
    其实就是扫描某个区间罢了!)其实最根本的原理是缩小了扫描的范围。
   
    在mysql数据库当中索引也是需要排序的,并且这个所以的排序和TreeSet
    
    数据结构相同。TreeSet(TreeMap)底层是一个自平衡的二叉树!在mysql
    
    当中索引是一个B-Tree数据结构。
   
遵循左小又大原则存放。采用中序遍历方式遍历取数据。
    
     索引的原理图
    
   
     
   
    通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的“物理地址”,
    
    最终通过索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率
    
    是最高的。
   
 select ename from emp where ename = 'SMITH';通过索引转换为:
select ename from emp where 物理地址 = 0x3;
    
     索引的使用限制
    
   
索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引也是数据库当中的对象,也需要数据库不断的维护。是有维护成本的。
    
     比如:
    
    表中的数据经常被修改,这样就不适合添加索引,因为数据一旦修改,索引需要重新排序,进行维护
   
添加索引是给某一个字段,或者说某些字段添加索引。
    select ename,sal from emp where ename = 'SMITH';
    
    当ename字段上没有添加索引的时候,以上sql语句会进行全表扫描,扫描ename字段中所有的值。
    
    当ename字段上添加索引的时候,以上sql语句会根据索引扫描,快速定位。
   
    
    2.怎么创建索引对象?怎么删除索引对象?
   
    
     创建索引对象:
    
    
    create index 索引名称 on 表名(字段名);
    
    
     删除索引对象:
    
    
    drop index 索引名称 on 表名;
   
假设有一张用户表:t_user
id(PK)                    name                        每一行记录在硬盘上都有物理存储编号
----------------------------------------------------------------------------------
100                        zhangsan                    0x1111
120                        lisi                        0x2222
99                         wangwu                      0x8888
88                         zhaoliu                     0x9999
101                        jack                        0x6666
55                         lucy                        0x5555
130                        tom                         0x7777
    
     提醒1
    
    :在任何数据库当中主键上都会自动添加索引对象,id字段上自动有索引,
    
    因为id是PK。另外在mysql当中,一个字段上如果有unique约束的话,也会自动
    
    创建索引对象。
   
    
     提醒2
    
    :在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有
    
    一个硬盘的物理存储编号。
   
    
     提醒3
    
    :在mysql当中,索引是一个单独的对象,不同的存储引擎以不同的形式
    
    存在,在MyISAM存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中
    
    索引存储在一个逻辑名称叫做tablespace的当中。在MEMORY存储引擎当中索引
    
    被存储在内存当中。
   
不管索引存储在哪里,索引在mysql当中都是一个树的形式存在。(自平衡二叉树:B-Tree)
    
     创建索引
    
   
mysql> create index emp_ename_index on emp(ename);
    
     删除索引
    
   
mysql> drop index emp_ename_index on emp;
    
    3.什么时候考虑给字段添加索引?(满足什么条件)
   
    
     多查询,少修改的情况下使用
    
   
    数据量庞大。(根据客户的需求,根据线上的环境,提高运行速度)
    
    该字段很少的DML操作。(因为字段进行修改操作,索引也需要维护)
    
    该字段经常出现在where子句中。(经常根据哪个字段查询,提高检索效率)
   
    
    
     注意:
    
    主键和具有unique约束的字段自动会添加索引。
   
    根据主键查询效率较高。尽量根据主键检索。
    
   
    5、查看语句是否使用了索引
   
查看语句是否使用了索引
mysql> explain select ename,sal from emp where sal = 5000;
	+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
	| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
	+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
	|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   14 | Using where |
	+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
看rows记录,进行了多少次扫描,是不是全表扫描。
    
    给薪资sal字段添加索引:
   
create index emp_sal_index on emp(sal);查看搜索的结果:
	
mysql> explain select ename,sal from emp where sal = 5000;
	+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
	| id | select_type | table | type | possible_keys | key           | key_len | ref   | rows | Extra       |
	+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
	|  1 | SIMPLE      | emp   | ref  | emp_sal_index | emp_sal_index | 9       | const |    1 | Using where |
	+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
rows为1,检索效率效果提升显著
    6.索引失效
   
失效的第一种情况:
	select ename from emp where ename like '%A%';
模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的。
  mysql> explain select * from emp where ename like '%T';
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  |  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   14 | Using where |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    
     失效的第2种情况:
    
    
    使用or的时候会失效,如果使用or那么要求or两边的条件字段都要有
    
    索引,才会走索引,如果其中一边有一个字段没有索引,那么另一个
    
    字段上的索引也会实现。所以这就是为什么不建议使用or的原因。
   
  mysql> explain select * from emp where ename = 'KING' or job = 'MANAGER';
  +----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
  | id | select_type | table | type | possible_keys   | key  | key_len | ref  | rows | Extra       |
  +----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
  |  1 | SIMPLE      | emp   | ALL  | emp_ename_index | NULL | NULL    | NULL |   14 | Using where |
  +----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
    
    
     失效的第3种情况:
    
    
    使用复合索引的时候,没有使用左侧的列查找,索引失效
    
    
     什么是复合索引?
    
    
    两个字段,或者更多的字段联合起来添加一个索引,叫做复合索引。
   
左列job成功使用索引,使用sal查询的话索引失效
  create index emp_job_sal_index on emp(job,sal);
  
  mysql> explain select * from emp where job = 'MANAGER';
  +----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+
  | id | select_type | table | type | possible_keys     | key               | key_len | ref   | rows | Extra       |
  +----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+
  |  1 | SIMPLE      | emp   | ref  | emp_job_sal_index | emp_job_sal_index | 30      | const |    3 | Using where |
  +----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+
  mysql> explain select * from emp where sal = 800;
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  |  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   14 | Using where |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    
     失效的第4种情况:
    
    
    在where当中索引列参加了运算,索引失效。
   
  mysql> create index emp_sal_index on emp(sal);
  explain select * from emp where sal = 800;
  +----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
  | id | select_type | table | type | possible_keys | key           | key_len | ref   | rows | Extra       |
  +----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
  |  1 | SIMPLE      | emp   | ref  | emp_sal_index | emp_sal_index | 9       | const |    1 | Using where |
  +----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
//失效
  mysql> explain select * from emp where sal+1 = 800;
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  |  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   14 | Using where |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    
     失效的第5种情况:
    
    
    在where当中索引列使用了函数
    
   
  explain select * from emp where lower(ename) = 'smith';
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
  |  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   14 | Using where |
  +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    7.索引的分类
   
    单一索引:一个字段上添加索引。
    
    复合索引:两个字段或者更多的字段上添加索引。
   
    主键索引:主键上添加索引。
    
    唯一性索引:具有unique约束的字段上添加索引。
    
    …..
   
    
     注意
    
    :唯一性比较弱的字段上添加索引用处不大。
   
    四.视图
   
    1.什么是视图?
   
站在不同的角度去看到数据。(同一张表的数据,通过不同的角度去看待)。
    
    
    2.怎么创建视图?怎么删除视图?
   
创建视图对象:
  create view dept2_view as select * from dept2;删除视图对象:
  drop view dept2_view;
    
     注意:
    
    只有DQL语句才能以view的形式创建。
   
create view view_name as 这里的语句必须是DQL语句;
    3.视图的用途
   
    
     方便,简化开发,安全,利于维护
    
    
    我们可以面向视图对象进行增删改查,对视图对象的增删改查,会导致
    
    原表被操作!(视图的特点:通过对视图的操作,会影响到原表数据。)
   
//面向视图查询
select * from dept2_view; 
// 面向视图插入
insert into dept2_view(deptno,dname,loc) values(60,'SALES', 'BEIJING');
// 查询原表数据
mysql> select * from dept2;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
|     60 | SALES      | BEIJING  |
+--------+------------+----------+
// 面向视图删除
mysql> delete from dept2_view;
// 查询原表数据
mysql> select * from dept2;
Empty set (0.00 sec)
    
     假设有一条非常复杂的SQL语句,而这条SQL语句需要在不同的位置上反复使用。每一次使用这个sql语句的时候都需要重新编写,很长,很麻烦,怎么办?
    
    
    可以把这条复杂的SQL语句以视图对象的形式新建。在需要编写这条SQL语句的位置直接使用视图对象,可以大大简化开发。并且利于后期的维护,因为修改的时候也只需要修改一个位置就行,只需要修改视图对象所映射的SQL语句。
   
    我们以后面向视图开发的时候,使用视图的时候可以像使用table一样。
    
    可以对视图进行增删改查等操作。
   
视图不是在内存当中,视图对象也是存储在硬盘上的,不会消失。
视图可以隐藏表的实现细节。保密级别较高的系统,数据库只对外提供相关的视图,java程序员
    
     再提醒一下:
    
    
    视图对应的语句只能是DQL语句。
   
但是视图对象创建完成之后,可以对视图进行增删改查等操作。
    
    
    4.面向视图操作
   
	mysql> select * from myview;
	+-------+--------+
	| empno | ename  |
	+-------+--------+
	|  7369 | SMITH  |
	|  7499 | ALLEN  |
	|  7521 | WARD   |
	|  7566 | JONES  |
	|  7654 | MARTIN |
	|  7698 | BLAKE  |
	|  7782 | CLARK  |
	|  7788 | SCOTT  |
	|  7839 | KING   |
	|  7844 | TURNER |
	|  7876 | ADAMS  |
	|  7900 | JAMES  |
	|  7902 | FORD   |
	|  7934 | MILLER |
	+-------+--------+
	create table emp_bak as select * from emp;
	create view myview1 as select empno,ename,sal from emp_bak;
	update myview1 set ename='hehe',sal=1 where empno = 7369; // 通过视图修改原表数据。
	delete from myview1 where empno = 7369; // 通过视图删除原表数据。
    五.DBA命令(数据的导入和导出)
   
    重点掌握:
    
    数据的导入和导出(数据的备份)
    
    其它命令了解一下即可。
   
    
     数据导出?
    
    
    注意:在windows的dos命令窗口中:
   
    mysqldump bjpowernode>D:\bjpowernode.sql -uroot -p123456
    
    
     可以导出指定的表吗?
    
   
mysqldump bjpowernode emp>D:\bjpowernode.sql -uroot -p123456
    
     数据导入
    
    
    
     注意:
    
    需要先登录到mysql数据库服务器上。
    
    然后创建数据库:create database bjpowernode;
    
    使用数据库:use bjpowernode
    
    然后初始化数据库:source D:\bjpowernode.sql
   
    六.数据库设计的三范式
   
    1.什么是设计范式?
   
设计表的依据。按照这个三范式设计的表不会出现数据冗余。
    2、三范式都是哪些?
   
第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分。
第二范式:建立在第一范式的基础之上,所有非主键字段完全依赖主键,不能产生部分依赖。
第三范式:建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。
    
     声明:
    
    三范式是面试官经常问的,所以一定要熟记在心!
   
设计数据库表的时候,按照以上的范式进行,可以避免表中数据的冗余,空间的浪费。
    
     第一范式
    
    
    最核心,最重要的范式,所有表的设计都需要满足。
    
    必须有主键,并且每一个字段都是原子性不可再分。
   
学生编号   学生姓名        联系方式
------------------------------------------
1001		张三		zs@gmail.com,1359999999
1002		李四		ls@gmail.com,13699999999
1001		王五		ww@163.net,13488888888
    
     以上是学生表,满足第一范式吗?
    
    
    不满足,第一:没有主键。第二:联系方式可以分为邮箱地址和电话
   
学生编号(pk)      学生姓名	      邮箱地址	     联系电话
----------------------------------------------------
1001				张三		zs@gmail.com	1359999999
1002				李四		ls@gmail.com	13699999999
1003				王五		ww@163.net		13488888888
    
    
     第二范式:
    
    
    建立在第一范式的基础之上,
    
    要求所有非主键字段必须完全依赖主键,不要产生部分依赖。
   
学生编号       学生姓名   教师编号  教师姓名
----------------------------------------------------
1001			张三		001		王老师
1002			李四		002		赵老师
1003			王五		001		王老师
1001			张三		002		赵老师
    
    这张表描述了学生和老师的关系:(1个学生可能有多个老师,1个老师有多个学生)
    
    这是非常典型的:多对多关系!
   
    
     分析以上的表是否满足第一范式?
    
    
    不满足第一范式。
   
    
     怎么满足第一范式呢?
    
   
修改
学生编号+教师编号(pk)		  学生姓名          教师姓名
----------------------------------------------------
1001			001				张三			王老师
1002			002				李四			赵老师
1003			001				王五			王老师
1001			002				张三			赵老师
    学生编号 教师编号,两个字段联合做主键,复合主键(PK: 学生编号+教师编号)
    
    
     经过修改之后,以上的表满足了第一范式。但是满足第二范式吗?
    
    
    不满足,“张三”依赖1001,“王老师”依赖001,显然产生了部分依赖。
    
    
     产生部分依赖有什么缺点?
    
    
    数据冗余了。空间浪费了。“张三”重复了,“王老师”重复了。
   
为了让以上的表满足第二范式,你需要这样设计:
  学生表
  学生编号(pk)		学生名字
  ------------------------------------
  1001					张三
  1002					李四
  1003					王五
  
  教师表
  教师编号(pk)		教师姓名
  --------------------------------------
  001					王老师
  002					赵老师
  学生教师关系表
  id(pk)			学生编号(fk)			教师编号(fk)
  ------------------------------------------------------
  1						1001						001
  2						1002						002
  3						1003						001
  4						1001						002
    
    
     多对多怎么设计?
    
    
    多对多,三张表,关系表两个外键!!!!!!!!!!!!!!!
   
    
     第三范式
    
    
    第三范式建立在第二范式的基础之上
    
    要求所有非主键字典必须直接依赖主键,不要产生传递依赖。
   
学生编号(PK)     学生姓名     班级编号         班级名称
---------------------------------------------------------
  1001                张三        01            一年一班
  1002                李四        02            一年二班
  1003                王五        03            一年三班
  1004                赵六        03            一年三班
    以上表的设计是描述:班级和学生的关系。很显然是1对多关系!
    
    一个教室中有多个学生。
   
    
     分析以上表是否满足第一范式?
    
    
    满足第一范式,有主键。
   
    
     分析以上表是否满足第二范式?
    
    
    满足第二范式,因为主键不是复合主键,没有产生部分依赖。主键是单一主键。
   
    
     分析以上表是否满足第三范式?
    
    
    第三范式要求:不要产生传递依赖!
    
    一年一班依赖01,01依赖1001,产生了传递依赖。
    
    不符合第三范式的要求。产生了数据的冗余。
   
    
     那么应该怎么设计一对多呢?
    
   
  班级表:一
  班级编号(pk)                  班级名称
  ----------------------------------------
  01                                一年一班
  02                                一年二班
  03                                一年三班
  学生表:多
  学生编号(PK)    学生姓名    班级编号(fk)
  -------------------------------------------
  1001                张三            01            
  1002                李四            02            
  1003                王五            03            
  1004                赵六            03   
    
    
     背口诀:
    
    
    一对多,两张表,多的表加外键!!!!!!!!!!!!
   
    
    
     提醒:
    
    在实际的开发中,以满足客户的需求为主,有的时候会拿冗余换执行速度。
    
   
    3.总结
   
    
     一对多:
    
    
    一对多,两张表,多的表加外键!!!!!!!!!!!!
   
    
     多对多:
    
    
    多对多,三张表,关系表两个外键!!!!!!!!!!!!!!!
   
    
     一对一:
    
    
    一对一放到一张表中不就行了吗?为啥还要拆分表?
    
    在实际的开发中,可能存在一张表字段太多,太庞大。这个时候要拆分表。
   
    
    
     一对一怎么设计?
    
    
    没有拆分表之前:一张表
   
    t_user
    id        login_name        login_pwd        real_name        email                address........
    ---------------------------------------------------------------------------
    1            zhangsan        123                张三                zhangsan@xxx
    2            lisi            123                李四                lisi@xxx
    ...    这种庞大的表建议拆分为两张:
    
    
     t_login 登录信息表
    
   
    id(pk)        login_name        login_pwd    
    ---------------------------------
    1                zhangsan        123            
    2                lisi            123   
    
     t_user 用户详细信息表
    
    
   
    id(pk)        real_name        email                address........    login_id(fk+unique)
    -----------------------------------------------------------------------------------------
    100            张三                zhangsan@xxx                                1
    200            李四                lisi@xxx                                    2
    
    口诀:一对一,外键唯一!!!!!!!!!!
   
    4.嘱咐
   
数据库设计三范式是理论上的。
实践和理论有的时候有偏差。
最终的目的都是为了满足客户的需求,有的时候会拿冗余换执行速度。
因为在sql当中,表和表之间连接次数越多,效率越低。(笛卡尔积)
    有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的,
    
    并且对于开发人员来说,sql语句的编写难度也会降低。
   
 
