事务
1.事务的定义
一个事务就是一个完整的业务逻辑。
假设转账,A向B转账1w,则A的账户余额减少1w,B的账户余额加上1w.这就是一个完整的业务逻辑。以上操作是一个最小的工作单元,要么同时成功或者同时失败。
2.只有DML语句才会有事务这一说法,其他都没有
只有update、insert、delete语句和事务相关,其他都没有关系。
主要涉及增删改就必须要考虑到数据的安全性。
3.事务机制的必要性
假设所有的业务,只需要一条DML语句就可以完成,还需要存在事务机制吗?没有
本质上:一个事务就是多条DML语句同时成功或者同时失败。
4事务如何做到同时成功同时失败
InnoDB存储引擎:提供一组用来记录事务性活动的日志文件。
事务开启:
insert、update、delete语句进行操作
事务结束。
在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中。
在事务的执行过程中,可以提交事务和回滚事务。
提交事务:清空事务性活动的日志文件,将数据全部彻底持久化带数据库表中。提交事务标志着事务的结束,并且是一种全部成功的结束。
回滚事务:将之前所有的DML操作全部撤销,并清空事务性活动的日志文件。回滚事务标着事务的结束,且是一种全部失效的结束。
5.怎么提交事务?回滚事务?
COMMIT提交
ROLLBACK回滚
事务对应的英语单词是 transaction。
在mysql中默认的事务行为是什么??在默认情况下mysql支持自动提交事务。(每执行一条DML语句,则提交一次)
怎么将mysql的自动提交机制关闭?先执行命令:start transaction;开启事务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-93yG0uaX-1643365084577)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220127210252480.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ejdqDxt-1643365084582)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220127210309101.png)]
mysql默认的自动提交不符合我们的开发习惯,因为业务通常是多个语句组成的,为了保证数据的安全性,必须要要求同时成功之后在提交,所以不能执行一条就提交一条。
6.事务特性
原子性:事务是最小的工作单元,不可再分。
一致性:所有事务要求,在同一事务当中,所有操作必须同时成功,或者同时失败。
隔离性:a事务与b事务之间具有一定的隔离。a事务与b事务同时操作一张表会怎么??
持久性:事务最终结束的一个保障,事务提交,相当于将没有保存到硬盘上的数据保存到硬盘上。
7.隔离级别
事务与事务之间的隔离级别:
7.1读未提交:read uncommitted(最低级别)
事务a可以读取到事务b未提交的数据。会出现脏读现象。一般不会使用这个级别的隔离。
设置事务隔离级别:set global transaction isolation level read uncommitted;(再推出窗口,之后再重新开启两个事务)
查看事务隔离级别:select @@tx_isolation;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UuOQiDUA-1643365084584)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220127215711902.png)]
1.事务A,B均开启:use bjpowernode
2.事务A,B先后设置:start transaction;
3.事务A中先查看表t_class;
mysql> select * from t_class;
+---------+-----------+
| classno | classname |
+---------+-----------+
| 100 | first |
| 101 | second |
| 102 | third |
+---------+-----------+
3 rows in set (0.01 sec)
4.在事务B中插入数据:insert into t_class values(103,‘firth’);
5.在事务A中再查看t_class:
mysql> select * from t_class;
+---------+-----------+
| classno | classname |
+---------+-----------+
| 100 | first |
| 101 | second |
| 102 | third |
| 103 | firth |
+---------+-----------+
4 rows in set (0.00 sec)
注意此时的事务B还未提交数据,但是事务A已经可以读取。
7.2读已提交:read committed
事务a只能读取到事务b提交之后的数据。
解决了脏读现象。
存在问题?不可重复读取数据。(在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读取到的数据是4条,3不等于4,这称为不可重复读取。)
这种级别的读取到的数据是真实的。oracle数据库默认的就是读已提交。
设置事务隔离级别:set global transaction isolation level read committed;
1.事务A,B均开启:use bjpowernode
2.事务A,B先后设置:start transaction;
3.事务A中先查看表t_class;
mysql> select * from t_class;
+---------+-----------+
| classno | classname |
+---------+-----------+
| 100 | first |
| 101 | second |
| 103 | firth |
| 102 | third |
+---------+-----------+
3 rows in set (0.00 sec)
4.事务B中添加数据:insert into t_class values(104,‘five’);
5.在事务A中再查看t_class:
mysql> select * from t_class;
+---------+-----------+
| classno | classname |
+---------+-----------+
| 100 | first |
| 101 | second |
| 103 | firth |
| 102 | third |
+---------+-----------+
3 rows in set (0.00 sec)
6.事务B提交:commit;
7.事务A再查:insert into t_class values(104,‘five’);
select * from t_class;
+---------+-----------+
| classno | classname |
+---------+-----------+
| 100 | first |
| 101 | second |
| 102 | third |
| 103 | firth |
| 104 | five |
+---------+-----------+
5 rows in set (0.00 sec)
7.3.可重复读: repeatable read
事务a开启之后,不管是多久,每一次在事务a中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是未修改的数据。
可重复读解决了:不可重复读取数据的问题。
存在的问题是:出现幻影读。(每一读取的数据都是幻象,不够真实)
mysql中默认的最高级别隔离。
7.4.序列化/串行化:serializable(最该级别)
最高隔离级别,效率最低,解决所有问题。表示事务排队,不能并发。每一次读取到的数据是真实的。
索引
1.什么是索引?
索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。
一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。
索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制。
对于一本字典来说,查找某个汉字有两种方式:
第一种方式:一页一页挨着找,直到找到为止,这种查找方式属于全字典扫描,效率较低。
第二种方式:先通过目录(索引)去定位一个大概位置,然后直接定位到这个位置,做局域性扫描,缩小扫描范围,快速查找。效率高。
一般的查询时:select * from emp where ename=‘SMITH’;该句会去ename字段上进行扫描,因为查询条件是ename=‘SMITH’。如果ename字段上没有添加索引,或者说没有给ename字段创建索引,mysql会进行全扫描,会将ename字段上的每一个值都比较一遍,效率较低。
添加索引:enameIndex.
MYSQL在查询方面主要就是两种方式:
第一种:全表扫描;
第二种:根据索引检索。
2.索引存储原理
在MYSQL数据库中索引也需要排序,并且这个索引的排序和TreeSet数据结构相同,TreeSet(TreeMap)底层是一个自平衡的二叉树。在MYSQL中索引是一个B-Tree数据结构。
注意:
1.在任何数据库中主键上都会自动添加索引对象。另外在mysql中,一个字段如果有unique约束,也会自动创建索引对象。
2.在任何数据库中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号。
3.在MYSQL中,索引是一个单独的对象,不同的存储引擎以不同的形式存在,在MyISAM存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中索引存储在一个逻辑名称叫做tbalespace中。在MEMORY存储引擎当中索引被存储在内存当中。不管索引存储在哪里,索引在mysql当中都是一个树的形式存在。(自平衡二叉树)
3.主键以及unique字段上都会自动添加索引
什么情况下需要给字段添加索引?
1.数据量庞大
2.该字段经常出现在where字段后面,以条件的形式存在。
3.该字段很少进行DML操作(增删改)
建议不要随便添加索引,所以因也需要维护,太多索引反而会降低系统的性能。一般使用主键查询、unique字段查询,效率比较高。
4.创建、删除索引
创建索引:create index emp_ename_index on emp(ename);给emp表的ename字段添加索引,起名为emp_ename_index。
删除索引:drop index emp_ename_index on emp; 将emp表上的emp_ename_index索引对象删除。
5.查看是否使用索引
explain select * from emp where ename=‘KING’;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lTl4M9Se-1643365084584)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128143411423.png)]
设置索引之后:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anUyiK44-1643365084585)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128143531211.png)]
6.索引失效
第一种:
select * from emp where ename like ‘%T’;
ename上即使添加了索引也不会走索引。为什么?因为模糊匹配中是以%开始
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NldEZeZL-1643365084586)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128144709354.png)]
第二种:
使用or的时候会失效,如果使用or那么要求or两边的条件字段都要有索引,才会走索引。如果其中一边一个字段没有索引,那么另一个字段上的索引也会失效。(因此不建议使用or)
select * from emp where ename =‘KING’ or job=‘MANAGER’;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbFOmczR-1643365084587)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128145917739.png)]
第三种:
使用复合索引的时候,没有使用左侧的列查找,索引失效。
什么是复合索引?两个字段或者更多字段联合起来添加一个索引,叫做复合索引。
create index emp_job_sal_index on emp(job,sal);
select * from emp where job=‘MANAGER’;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nh8jNRhh-1643365084587)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128150237525.png)]
select * from emp where sal=800;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5n7pDFeR-1643365084588)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128150317116.png)]
没有使用索引。
第四种:
索引列参加了运算.
create index emp_sal_index on emp(sal);
select * from emp where sal=800;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-taoVkG7x-1643365084588)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128150627400.png)]
select * from emp where sal+1=800;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JEpmUGkR-1643365084589)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128150718580.png)]
第五种:
在where当中索引列使用了函数。
select * from emp where lower(ename)=‘smith’;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o9FRjw3Z-1643365084590)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128150859333.png)]
…
7.索引类型
索引是数据库优化的重要手段,优化时优先考虑的就是索引。
索引的分类:
单一索引:一个字段上添加索引
复合索引:两个字段或者更多字段上添加索引
主键索引:主键上添加索引
唯一性索引:unique约束字段添加索引
…
注意:唯一性比较弱的字段上添加索引的作用不大。
索引的缺点:
① 创建索引和维护索引需要时间成本,这个成本随着数据量的增加而加大
② 创建索引和维护索引需要空间成本,每一条索引都要占据数据库的物理存储空间,数据量越大,占用空间也越大(数据表占据的是数据库的数据空间)
③ 会降低表的增删改的效率,因为每次增删改索引需要进行动态维护,导致时间变长
视图
1.什么是视图?
view:站在不同的角度去看待同一份数据。
2.创建视图、删除视图
表复制:create table dept2 as select * from dept;
dept2表中的数据:
创建视图对象:create view dept2_view as select * from dept2;
删除试图对象:drop view dept2_view;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m19xtMVH-1643365084590)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20220128152458599.png)]
注意: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> create view dept2_view as select * from dept2;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from dept2_view;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
4 rows in set (0.00 sec)
mysql> insert into dept2_view(deptno,dname,loc) values(60,'SALES','BEIJING');
Query OK, 1 row affected (0.35 sec)
mysql> select * from dept2_view;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
| 60 | SALES | BEIJING |
+--------+------------+----------+
5 rows in set (0.00 sec)
//查询原表数据
mysql> select * from dept2;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
| 60 | SALES | BEIJING |
+--------+------------+----------+
5 rows in set (0.00 sec)
面向视图删除数据:
mysql> delete from dept2_view;
Query OK, 5 rows affected (0.37 sec)
//查询原表数据
mysql> select * from dept2;
Empty set (0.00 sec)
两表连接,创建视图:
create view emp_dept_view as select e.ename,e.sal,d.dname from emp e join dept d on e.deptno=d.deptno;
查询视图:select * from emp_dept_view;
更新视图:update emp_dept_view set sal=1000 where dname=‘ACCOUNTING’;
mysql> create view emp_dept_view as select e.ename,e.sal,d.dname from emp e join dept d on e.deptno=d.deptno;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from emp_dept_view;
+--------+---------+------------+
| ename | sal | dname |
+--------+---------+------------+
| CLARK | 2450.00 | ACCOUNTING |
| KING | 5000.00 | ACCOUNTING |
| MILLER | 1300.00 | ACCOUNTING |
| SMITH | 800.00 | RESEARCH |
| JONES | 2975.00 | RESEARCH |
| SCOTT | 3000.00 | RESEARCH |
| ADAMS | 1100.00 | RESEARCH |
| FORD | 3000.00 | RESEARCH |
| ALLEN | 1600.00 | SALES |
| WARD | 1250.00 | SALES |
| MARTIN | 1250.00 | SALES |
| BLAKE | 2850.00 | SALES |
| TURNER | 1500.00 | SALES |
| JAMES | 950.00 | SALES |
+--------+---------+------------+
14 rows in set (0.00 sec)
mysql> update emp_dept_view set sal=1000 where dname='ACCOUNTING';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
//原表数据被更新
mysql> select * from emp;
+-------+--------+-----------+------+------------+---------+---------+--------+
| 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 | 1000.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 1000.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 | 1000.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)
mysql> select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
4 rows in set (0.00 sec)
mysql> select * from emp_dept_view;
+--------+---------+------------+
| ename | sal | dname |
+--------+---------+------------+
| CLARK | 1000.00 | ACCOUNTING |
| KING | 1000.00 | ACCOUNTING |
| MILLER | 1000.00 | ACCOUNTING |
| SMITH | 800.00 | RESEARCH |
| JONES | 2975.00 | RESEARCH |
| SCOTT | 3000.00 | RESEARCH |
| ADAMS | 1100.00 | RESEARCH |
| FORD | 3000.00 | RESEARCH |
| ALLEN | 1600.00 | SALES |
| WARD | 1250.00 | SALES |
| MARTIN | 1250.00 | SALES |
| BLAKE | 2850.00 | SALES |
| TURNER | 1500.00 | SALES |
| JAMES | 950.00 | SALES |
+--------+---------+------------+
14 rows in set (0.00 sec)
假设有一条非常复杂的SQL语句,而这条SQL语句需要在不同的位置上反复使用。每一次使用这个sql语句的时候都需要重新编写,很麻烦,此时应该怎么做?
可以把这条复杂的SQL语句以视图对象的形式新建,在需要编写这条SQL语句的位置直接使用视图对象,可以大大简化开发,并且利于后期的维护,因为修改的时候只需要修改一个位置就行。
视图对象也是一个文件,在数据中也是以文件的形式存在,存储在硬盘上,不会消失。使用视图的时候可以和使用table一样,视图也可以进行CRUD。
DBA命令
创建新用户:create user xiaoming identified by ‘12345’;
给新用户授权:grant
导出数据:在windoews的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.什么是设计范式?
数据库表的设计依据。
设计关系型数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系型数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。一般来说,数据库只需要满足第三范式就行了。
第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分;
第二范式:建立在第一范式基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖;
第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。
2.第一范式
第一范式(1NF):每一列都是不可分割的原子数据项
如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库满足了第一范式。
学生编号 学生姓名 联系方式 | ||
---|---|---|
1001 张三 1679721627,13716@qq.com | ||
1002 李四 267826186,17621@qq.com | ||
1003 王五 122616367,12131@qq.com |
以上学生表满足第一范式吗?
不满足,第一:没有主键,第二:联系方式可以再分为邮箱地址和电话号码
学生编号(PK) 学生姓名 电话号码 邮箱 | ||
---|---|---|
1001 张三 16797216 13716@qq.com | ||
1002 李四 267826186 17621@qq.com | ||
1003 王五 122616367 12131@qq.com |
3.第二范式
保证一张表只描述一件事情,所有非关键字必须完全依赖主键,不要产生部分依赖
用第二范式的定义描述第二范式,说的是在满足第一范式的基础上,数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖,也即所有非关键字段都完全依赖于任一组候选关键字。
学生编号 学生姓名 教师编号 老师姓名 | ||
---|---|---|
1001 张三 001 王老师 | ||
1002 李四 002 赵老师 | ||
1003 王五 002 赵老师 | ||
1001 张三 002 赵老师 |
该表描述了老师和学生的关系,一个学生可能有多个老师,一个老师可能有多个学生。N:N关系
上表满足第一范式吗?不满足,没有主键
怎么满足第一范式?添加主键
学生编号 + 教师编号(pk) 学生姓名 老师姓名 | |
---|---|
1001 001 张三 王老师 | |
1002 002 李四 赵老师 | |
1003 002 王五 赵老师 | |
1001 002 张三 赵老师 |
学生编号和教师编号联合起来做主键(复合主键),此时该表满足第一范式。
但是不满足第二范式,张三依赖于1001,王老师依赖001,显然产生部分依赖,会导致数据冗余,空间浪费。
改进:使用三张表表示多对多的关系:学生表,教师表,教师学生关系表。
学生编号 (pk) 学生姓名 | ||
---|---|---|
1001 张三 | ||
1002 李四 | ||
1003 王五 |
教师编号(pk) 老师姓名 | |
---|---|
001 王老师 | |
002 赵老师 |
关系表
id(pk) 学生编号(FK) 教师编号(FK) | |
---|---|
1 1001 001 | |
2 1002 002 | |
3 1003 002 | |
4 1001 002 |
多对多怎么设计?多对多,三张表,关系表两外键
4.第三范式
保证每列都和主键直接相关,要求所有非主键字段直接依赖主键,不要产生传递依赖。
第三范式又和第二范式相关,用第三范式的定义描述第三范式就是,数据库表中如果不存在非关键字段任一候选关键字段的传递函数依赖则符合第三范式,所谓传递函数依赖指的是如果存在"A–>B–>C"的决定关系,则C传递函数依赖于A。也就是说表中的字段和主键直接对应不依靠其他中间字段,说白了就是,决定某字段值的必须是主键。
学生编号(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 |
一对多,两张表,多的加外键。
5.总结表的设计
一对多:一对多,两张表,多的加外键
多对多:多对多,三张表,关系表两外键
**一对一:**一对一,外键唯一
在实际情况中可能一张表的字段太多,太庞大,这个时候就需要拆分。
比如:用户信息表包括用户各种信息,建议拆分为两张表,一张用户详细信息便,另一个是登录信息表。
在其中一张表里面加上另一个表的主键做外键。
名 班级编号 (FK) | ||
---|---|---|
1001 张三 01 | ||
1002 李四 02 | ||
1003 王五 03 | ||
1004 赵六 03 |
一对多,两张表,多的加外键。
5.总结表的设计
一对多:一对多,两张表,多的加外键
多对多:多对多,三张表,关系表两外键
**一对一:**一对一,外键唯一
在实际情况中可能一张表的字段太多,太庞大,这个时候就需要拆分。
比如:用户信息表包括用户各种信息,建议拆分为两张表,一张用户详细信息便,另一个是登录信息表。
在其中一张表里面加上另一个表的主键做外键。