数据库入门级学习(4)

接数据库入门级学习(3)

文章目录


一、约束(非常重要)

1.什么是约束

约束对应的英语单词:constraint
在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的完整性、有效性

约束的作用就是为了保证:表中的数据有效

2.约束包括哪些?

非空约束:not null
唯一性约束:unique
主键约束:primary key(简称PK)
外键约束:foreign key(简称FK)
检查约束:check(MySQL不支持,Oracle支持)

重点学习:
not null
unique
primary key
foreign key

插入一个小知识点(用于批量执行)

如果SQL语句过长,可以使用一个后缀为.sql的脚本文件,然后在shell上运行该文件
运行的语句是:source sql文件的绝对路径
xxxx.sql这种文件被称为sql脚本文件
我们执行sql文件时,该文件所有的sql语句会全部执行

2.1非空约束:not null

drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null
);
insert into t_vip(id,name) values(1,‘jisoo’);
insert into t_vip(id,name) values(2,‘涩琪’);

insert into t_vip(id) values(3);//名字为空了,所以不能创建成功

ERROR 1364 (HY000): Field ‘name’ doesn’t have a default value

2.2唯一性约束:unique

唯一性约束unique约束的字段不能重复,但是可以为NULL
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) unique,
email varchar(255)
);
insert into t_vip(id,name,email) values(1,‘jisoo’,‘111’);
insert into t_vip(id,name,email) values(2,‘涩琪’,‘222’);
insert into t_vip(id,name,email) values(3,‘jimin’,‘333’);
select * from t_vip;

insert into t_vip(id,name,email) values(4,‘jimin’,‘444’);//名字与表中已有数据重复
ERROR 1062 (23000): Duplicate entry ‘jimin’ for key ‘t_vip.name’
insert into t_vip(id) values(4);//如图,说明可以插入NULL
在这里插入图片描述

2.3表级约束

表级约束主要是给多个字段联合起来添加约束的

2.3.1新需求:两个字段联合起来具有唯一性?

drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) unique,
email varchar(255)
);
这张表这样创建是不符合我以上“新需求”的。
这样创建表示:name具有唯一性,email具有唯一性。各自唯一

以下这样的数据是符合“新需求”的
insert into t_vip(id,name,email) values(1,‘jisoo’,‘111’);
insert into t_vip(id,name,email) values(2,‘jisoo’,‘222’);
ps:但是如果使用上面的方法创建表格,则这两条数据没办法被都被插入,因为名字出现重复,创建失败

drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255),
email varchar(255),
unique(name,email)
);
insert into t_vip(id,name,email) values(1,‘jisoo’,‘111’);
insert into t_vip(id,name,email) values(2,‘jisoo’,‘222’);
在这里插入图片描述

这样就是name和email联合起来唯一!!!(即两个都相同时才不能创建成功)
约束加在列的后面,这种约束被称为列级约束;约束没有加在列的后面,这种约束被称为表级约束

什么时候使用表级约束?

需要给多个字段联合起来添加某一个约束的时候,需要使用表级约束

2.3.2unique和not null 可以联合约束吗?

drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null unique
);

desc t_vip;
在这里插入图片描述
如图,在MySQL中,如果一个字段同时被not null和unique约束的话,该字段自动变成主键字段(注意,在Oracle中不一样)
insert into t_vip(id,name) values(1,‘jisoo’);
insert into t_vip(id,name) values(2,‘jisoo’);//报错,name不能重复
insert into t_vip(id) values(3);//报错,name不能为NULL

2.4主键约束
2.4.1主键约束的相关术语?

主键约束:就是一种约束
主键字段:该字段上添加了主键约束,这样的字段叫做主键字段
主键值:主键字段中的每一个值

2.4.2什么是主键

主键值是每一行记录的唯一标识
主键值是每一行记录的身份证号

任何一张表都应该有主键,没有主键,表无效

2.4.3主键的特征

not null+unique(主键值不能是NULL,同时不能重复)
简单的来说就是:中国公民,都有身份证号,不能为NULL,中国公民身份证号不能重复。名字可以一样,性别可以相同,但是身份证号不同。
即使是双胞胎,身份证号也是不一样的

2.4.4给主键添加主键

drop table if exists t_vip;
create table t_vip(
id int primary key,
name varchar(255)
);
insert into t_vip(id,name) values(1,‘jisoo’);
insert into t_vip(id,name) values(2,‘涩琪’);

insert into t_vip(id,name) values(2,‘jimin’);
错误:不能重复
ERROR 1062 (23000): Duplicate entry ‘2’ for key ‘t_vip.PRIMARY’
insert into t_vip(name) values(‘jimin’);
//错误,不能为NULL
ERROR 1364 (HY000): Field ‘id’ doesn’t have a default value

2.4.5使用表级约束添加主键约束——复合主键

drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) ,
primary key(id,name)
);
insert into t_vip(id,name) values(1,‘jisoo’);
insert into t_vip(id,name) values(1,‘涩琪’);//这样是可以的,因为名字不一样

在实际开发中不建议使用复合主键,建议使用单一主键 因为主键值存在的意义就是这行记录的身份证号,只要意义达到即可,单一主键可以做到。复合主键比较复杂

2.4.6一张表中的主键约束能有多个吗?

drop table if exists t_vip;
create table t_vip(
id int primary key,
name varchar(255) primary key
);

ERROR 1068 (42000): Multiple primary key defined
结论:一张表只能添加一个主键约束
主键值建议使用:
int
bigint
char等类型
不建议使用:varchar来做主键,主键值一般都是数字并且是定长的

2.4.7主键值的其他类型

自然主键:主键值是一个自然数,与业务没关系
业务主键:主键值和业务紧密联系,例如拿银行卡账号做主键值,这就是业务主键

在实际开发中使用自然逐渐比较多:
因为主键只要做到不重复即可,不需要有意义。业务主键不好,因为主键一旦和业务挂钩,那么当业务发生变动的时候,可能会影响到主键值,所以业务主键不建议使用。尽量使用自然主键

在MySQL中,有一种机制可以帮助我们自动维护一个主键值
auto_increment表示自增,从1开始,以1递增
drop table if exists t_vip;
create table t_vip(
id int primary key auto_increment,
name varchar(255)
);
insert into t_vip(name) values(‘jisoo’);
insert into t_vip(name) values(‘涩琪’);
insert into t_vip(name) values(‘jimin’);
在这里插入图片描述

2.5外键约束(非常重要)
2.5.1外键约束的相关术语

外键约束:一种约束
外键字段:该字段添加了外键约束
外键值:外键字段当中的每一个值

业务背景: 设计数据库表,来描述“班级和学生”的信息
第一种方案:班级和学生存储在一张表
但是这种方案的缺点是:数据冗余,空间浪费

第二种方案:班级一张表、学生一张表
但是分成两张表之后,要通过班级编号建立联系
在这里插入图片描述
当cno字段没有任何约束的时候,可能会导致数据无效。可能会出现一个102,但是102班级不存在
所以为了保证cno字段中的值都是100和101,需要给cno字段添加外键约束
即t_student中的cno字段引用t_class这张表的classno

drop table if exists t_student;
drop table if exists t_class;

mysql> create table t_class{
-> classno int primary key,
-> classname varchar(255)
-> );

mysql> create table t_student(
-> no int primary key auto_increment,
-> name varchar(255),
-> cno int,
-> foreign key(cno) references t_calss(classno)
-> );
//references引用指定表中的字段中数据
注意:
t_class是父表
t_student是子表
删除表、数据的顺序:先删除子再删除父;创建、插入数据则反之

外键值可以为NULL

二、存储引擎(面试常问)

1.什么是存储引擎,有什么用?

存储引擎是MySQL中特有的一个术语,其他数据库中没有。(Oracle中有,但不是叫这个名字
存储引擎是一个表存储/组织数据的方式
不同的存储引擎,表存储数据的方式不同

2.怎么给表添加/指定存储引擎?

可以在建表的时候给表指定存储引擎
在建表的时候可以在最后的小括号的右边使用:
ENGINE:指定存储引擎
CHARSET:指定这张表的字符编码方式
MySQL默认的存储引擎是:InnoDB
MySQL默认的字符编码方式是:utf8
建表时指定存储引擎以及字符编码方式:
mysql> create table t_product(
-> id int primary key,
-> name varchar(255)
-> )engine=InnoDB default charset=gbk;

3.查看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.01 sec)
由上可知,MySQL支持9种存储引擎,版本不同支持情况不同

4.MySQL常用的存储引擎

4.1MyISAM

其管理的表具有以下特征:

使用三个文件表示每个表:
格式文件-存储表结构的定义(mytable.fm)
数据文件-存储表行的内容(mytable.MYD)
索引文件-存储表上索引(mytable.MYI):索引是一本书的目录,缩小扫描范围,提高查询效率

可被转换为压缩、只读表来节省空间(优势)
不支持事务:不能保证数据的安全性。
ps:对于一张表来说,只要是主键 或者加有unique约束的字段上会自动创建索引

4.2InnoDB

这是MySQL默认的存储引擎,同时也是一个重量级的存储引擎
InnoDB支持事务,支持数据库崩溃后自动恢复机制
InnoDB存储引擎最主要的特征是:非常安全

它管理的表具有下列主要特征:
每个InnoDB表在数据库目录中以.frm格式文件表示
InnoDB表空间tablespace被用于存储表的内容(表空间是一个逻辑名称,表空间存储数据+索引)
提供一组用来记录事务性活动的日志文件
用COMMIT(提交)、SAVEPOINT及ROLLBACK(回滚)支持事务处理
提供全ACID兼容
在MySQL服务器崩溃后提供自动恢复
多版本(MVCC)和行级锁定
支持外键及引用的完整性,包括级联删除和更新

InnoDB最大的特点就是支持事务:以保证数据的安全性。但是效率不是很高,并且不能压缩,不能转换为只读,不能很好地节省存储空间。

4.3MEMORY

使用MEMORY存储引擎的表,其数据存储在内容中且行的长度固定,这两个特点使得MEMORY存储引擎非常快。

MEMORY存储引擎管理的表具有下列特征:
在数据库目录中,每个表均以.frm格式的文件表示
表数据及索引被存储在内存中
表级锁机制
不能包含TEXT或BLOB字段

MEMORY存储引擎以前被称为HEAP引擎
MEMORY引擎优点:查询效率最高,不需要和硬盘交互
MEMORY引擎的缺点:不安全,关机之后数据消失,因为数据和索引都是在内存中

三、事务(非常重要*****,必须理解必须掌握)

1.什么是事务

一个事务就是一个完整的业务逻辑

什么是一个完整的业务逻辑?
假设转账,从A账户向B账户转账10000
将A账户减去10000 将B账户加上10000
这就是一个完整的业务逻辑

以上的操作是一个最小的工作单元,要么同时成功或者同时失败,不可再分。

这两个update语句要求必须同时成功或同时失败,这样才能保证钱是正确的

2.只有DML语句才会有事务,其他语句与事务无关

insert
delete
update
只有上面的三个语句和事务有关系,其他都没有关系。
只要相关操作一旦涉及数据的增、删、改,那么就一定要考虑安全问题

数据安全第一位

3.事务机制的意义

假设所有的业务,只要一条DML语句就能完成,还需要有事务机制吗?
正是因为做某件事的时候,需要多条DML语句共同联合起来才能完成,所以需要事务的存在,如果任何一件复杂的事只需要一条DML语句就能完成,那么事务就没有存在的意义

事务其实就是多条DML语句同时成功或者同时失败

4.事务是怎么做到多条DML语句同时成功或和同时失败

InnoDB存储引擎:提供一组用来记录事务性活动的日志文件
在事物的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中
在事务的执行过程中,可以提交事务,也可以回滚事务

4.1提交事务

清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中
提交事务标志着事物的结束并且是一种全部成功的结束

4.2回滚事务

将之前所有的DML操作全部撤销并且情况事务性活动的日志文件
回滚事务标志着事物的结束并且是一种全部失败的结束

4.3如何完成提交和回滚事务

提交事务:commit;
回滚事务:rollback ;
回滚永远都是只能回滚到上一次的提交点

事务的英语单词是:transaction
MySQL默认情况下是支持自动提交事务的
自动提交就是每执行一条DML语句则提交一次

关闭MySQL的自动提交机制:
执行该命令:start transaction;

这种自动提交实际上是不符合我们的开发习惯的,因为一个业务通常是需要多条DML语句共同执行才能完成的,为了保证数据的安全,必须要求同时成功之后再提交,所以不能执行一条就提交一条。

5.事务的特性

5.1原子性

说明事务时最小的工作单元,不可再分

5.2一致性

所有事物要求,在同一个事务当中,所有操作必须同时成功或者同时失败,以保证数据的一致性

5.3隔离性

A事务和B事务之间具有一定的隔离
教室A和教室B之间有一道墙,这道墙就是隔离性
这道墙可以很厚也可以很薄,这就是事务的隔离级别
这道墙越高表示隔离级别就越高

5.3.1隔离级别

读未提交:read uncommitted(最低的隔离级别)
简单来说就是这个事务还没结束的操作就被其他人读取到了
事务A可以读取到事务B未提交的数据
这种隔离级别存在的问题就是:脏读现象(Dirty Read)
即读到了脏数据
这种隔离级别一般都是理论上大多数的数据库的隔离级别都是二档起步

读已提交:read commited
就是rollback和commit之后才可以读到数据的更新 事务A只能读取到事务B提交之后的数据
这种隔离级别解决了脏读现象
这种隔离级别存在的问题是:不可重复读取数据
不可重复读取数据就是,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4(即不能动态读取事务B
即你读的时候他还没提交,后来他提交了你再读就不一样了(前后不一致)
这种隔离级别是比较真实的数据,每一次读到的数据是绝对真实的
Oracle数据库默认的隔离级别就是这个

可重复读:repeatable read
就是读取的一直都是没有被提交的数据?
事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务A将数据已经修改并且提交了,事务A读取到的数据还是没有改变,这就是可重复读
可重复读解决的问题是:解决了不可重复读取数据
存在的问题是:会出现幻影读
每一次读取到的数据都是幻想,不够真实
即早晨9点开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样!读到的是假象,不够绝对的真实
MySQL中默认的事务隔离级别就是这个

序列化/串行化:serializable(最高的隔离级别)
效率最低,解决了所有问题
这种隔离级别表示事务排队,不能并发
编程同步(事务同步)
每一次读取到的数据都是最真实的

5.3.2验证各种隔离级别

查看隔离级别:select @@tx_isolation

被测试的表:t_user
验证:read uncommitted
ps:其实两个shell窗口就是两个事务,对其中一个窗口运行下面一条命令
mysql>set global transaction isolation level read uncommitted;
然后退出exit,再重新登录MySQL
ps:这里的bjpowernode是数据库名

在这里插入图片描述

在这里插入图片描述
如图,是在事务B插入数据之前的事务A查询的t_user表
在这里插入图片描述
如图,是在事务B插入数据后且并未提交事务时的事务A查询的t_user表

验证:read committed
mysql> set global transaction isolation level read committed;

在这里插入图片描述在这里插入图片描述
如图,是事务A在事务B还未插入数据之前及插入数据未提交时的t_user表
在这里插入图片描述
如图,是事务A在事务B插入数据并提交时的t_user表

验证:repeatable read
mysql> set global transaction isolation level repeatable read;

在这里插入图片描述

在事务B插入多次并提交时,事务A查询的t_user表仍旧是最初读取的数据并且不变

验证:serializable
mysql> set global transaction isolation level serializable;

在这里插入图片描述

只有在事务A插入完并提交之后,事务B才能查询表格t_user
(即两个事务在排队)

5.4持久性

事务最终结束的一个保障,事务提交就相当于将没有保存到硬盘上的数据保存到硬盘上

四、索引index

1.什么是索引

索引在数据库表的字段上添加的,是为了提高查询效率存在的一种机制
一张表的一个字段可以添加一个索引,多个字段联合起来也可以添加索引
索引相当于一本书的目录,是为了缩小扫描范围二存在的一种机制

对于一本字典来说,查找某个汉字有两种方式
(1)一页一页地找,直到找到为止,这种方式属于全字典扫描
(2)先通过目录(索引)去定位一个大概的位置,然后直接定位到这个位置,做局域性扫描,缩小扫描范围,快速查找,这种查找方式属于通过索引检索,效率较高

select * from t_user where name=‘Iriss77’;
以上这条SQL语句回去name字段上扫描,因为查询条件是name=‘Iriss77’
如果name字段上没有添加索引(目录),或者说是没有给name字段窗机爱你索引,MySQL会进行全扫描,会将name字段上的每一个值都对比一边,效率较低

索引要进行排序,因为只有排序了才会有区间查找(缩小扫描范围)
并且索引的排序和treeset数据结构相同,treeset底层是一个自平衡的二叉树
所以在MySQL中索引是一个B-Tree数据结构,遵循左小右大原则存放,采用中序遍历方式遍历数据

2.索引的实现原理

在任何数据库中竹简上都会自动添加索引对象,另外在MySQL中,一个字段如果有unique约束的话,也会有字段创建索引对象
在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号
在MySQL中,索引是一个单独的对象,不同的存储引擎以不同形式存在,在M有I萨满存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中,索引存储在一个逻辑名称叫做tablespace当中。在MEMORY存储引擎当中,索引被存储在内存当中。 不管索引存储在哪里,索引在MySQL中都是一个树的形式存在(自平衡二叉树:B-Tree)
在这里插入图片描述
其实就是缩小扫描范围,避免全表扫描

3.添加索引的情况

什么条件下,考虑给字段添加索引?
条件1:数据量庞大
条件2:该字段经常出现在where的后面,以条件的形式存在,也就是说这个字段总是被扫描
条件3:该字段很少DML(insert、delete、update) 因为DML之后,索引需要重新排序
建议不随便添加索引,因为索引也是需要维护的,太多的话反而降低系统的性能
建议通过主键查询以及unique约束的字段进行查询,效率比较高

4.对索引的操作

4.1创建索引

例如:给emp表的ename创建索引,名为:emp_ename_index
mysql> create index emp_ename_index on emp(ename);

4.2删除索引

例如:将emp表上的emp_ename_index索引对象删除
mysql> drop index emp_ename_index on emp;

5.查看索引

在MySQL中,怎么查看一个SQL语句是否使用了索引进行检索?
mysql> explain select * from emp where ename=‘KING’;
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±-------------------------------+
| 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 |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±--------------------------------+
扫描14条记录:说明没有使用索引
type=ALL

mysql> create index emp_ename_index on emp(ename);
mysql> explain select * from emp where ename=‘KING’;
±—±------------±------±-----------±-----±----------------±----------------±--------±------±-----±---------±--------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±------±-----------±-----±----------------±----------------±--------±------±-----±---------±---------------------------------+
| 1 | SIMPLE | emp | NULL | ref | emp_ename_index | emp_ename_index | 43 | const | 1 | 100.00 | NULL |
±—±------------±------±-----------±-----±----------------±----------------±--------±------±-----±---------±---------------------------------+

6.索引失效

(1)select * from emp where ename like ‘%T’;
ename上即使添加了索引,也不会走索引
因为模糊匹配当中以%开头
所以尽量避免模糊查询的时候以%开始
这是一种优化的手段/策略

(2)使用or的时候会失效,如果使用or那么要求or两边的条件字段都有索引,才会使用索引。如果其中一边有一个字段没有索引,那么另一个字段上的索引也会实现。所以这就是为什么不建议使用or的原因

(3)使用复合索引的时候,没有使用左侧的列查找,索引失效
复合索引:两个字段或者更多的字段联合起来添加一个索引
例如:create index emp_job_sal_index on emp(job,sal);

(4)在where当中索引列参加了运算,索引失效
(5)在where当中,索引列使用了函数

7.索引的分类

索引是各种数据库进行优化的重要手段
优化的时候优先考虑的因素就是索引
单一索引:一个字段上添加索引
复合索引:两个字段或者更多的字段上添加索引
主键索引:主键上添加索引
唯一性索引:具有unique约束的字段上添加索引

注意:唯一性比较弱的字段上添加索引引用处不大

五、视图

1.什么是视图

view:站在不同的角度上去看待同一份数据

2.对视图对象的操作

表复制:
mysql> create table dept2 as select * from dept;

dept2表中的数据:
select * from dept2;

2.1创建视图

create view dept2_view as select * from dept2;

2.2删除视图

drop view dept2_view;

注意:只有DQL语句才能以view的形式创建
create view view_name as 这里的语句必须是DQL语句

2.3用视图做什么

我们可以面向视图对象进行增删查改,对视图对象的增删查改会导致原表被操作!(视图的特点:通过对视图的操作,会影响到原表数据
//面向视图查询
select * from dept2_view;
在这里插入图片描述

//面向视图插入
insert into dept2_view(deptno,dname,loc) values(60,‘SALES’,‘BEIJING’);

//查询原表数据
select * from dept2;
在这里插入图片描述
//面向视图删除
delete from dept2_view;

//查询原表数据
select * from dept2;

2.4视图对象在实际开发中到底有什么用

方便、简化开发、利于维护
在这里插入图片描述
假设有一条非常复杂的SQL语句,而这条SQL语句需要在不同位置上反复使用
每一次使用这个sql语句的时候都需要重新编写,很长很麻烦
所以可以把这条复杂的SQL语句以视图的形式新建
在需要编写这样SQL语句的位置直接使用视图对象,可以大大简化开发
并且有利于后期的维护,因为修改的时候也需要修改一个位置就行,只需要修改视图对象所映射的SQL语句

我们以后面向视图开发的时候,使用视图的时候可以像使用table一样。可以对视图进行增删查改等操作。视图不是在内存当中,视图对象也是存储在硬盘上的,不会消失

六、数据库设计三范式

1.数据库设计范式

数据库表的设计依据。教你怎么进行数据库表的设计

2.数据库设计范式的种类

3个
第一范式:要求任何一张表必须有主键,没一个字段原子性不可再分
第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖
第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖

三范式是面试官经常问的,所以一定熟记在心

设计数据库表的时候,按照以上的范式进行,可以避免表中数据的冗余、空间的浪费。

2.1第一范式

最核心、最重要的范式,所有表的设计都需要满足
必须有主键,并且每个字段都是原子性不可再分

2.2第二范式

建立在第一范式的基础之上,要求所有非主键字段必须完全依赖主键,不要产生部分依赖
若一张表,其中教师编号和学生编号是复合主键,且在表中张三依赖于学生编号1001,王老师依赖教师编号001,显然产生了部分依赖。

产生部分依赖的缺点:数据冗余,空间浪费(张三重复了、王老师重复了)
解决部分依赖的办法就是创建多个表来表示多对多的关系
多对多,三张表,关系表两个外键

2.3第三范式

建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖
一年三班依赖于班级编号03,03依赖于学生编号(主键)1001
这就是传递依赖
解决办法:多表解决一对多问题
一对多,两张表,多的表加外键

2.4总结

一对多:一对多,两张表,多的表加外键
多对多:多对多,三张表,关系表两个外键
一对一:在实际开发中,可能存在一张表字段太多,太庞大。这个时候要拆分表(关系字段外键+unique)一对一,外键唯一
数据库设计三范式是理论上的
实践与理论是有偏差的
最终目的都是为了满足客户的要求,有的时候会拿冗余换执行速度
因为在sql当中,表和表之间连接次数越多,效率越低(笛卡尔积)
有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的并且对于开发人员来说,sql语句的编写难度也会降低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值