day01
数据库的分类:关系型数据库和非关系型数据库
关系型数据库是将复杂的数据结构用较为简单的二维表来表示,由二维表及其之间的联系所组成的一个数据组。
优点:
-
易于维护:使用二维表的表结构,格式一致;
-
使用方便:SQL语言通用,关系型数据库都可以使用SQL进行操作;
-
复杂操作:可用于一个表以及多个表之间非常复杂的查询。
缺点:
-
读写性能比较差,尤其是海量数据的高效率读写;
-
固定的表结构,灵活度稍欠;
-
高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
非关系型数据库也称之为NoSQL(Not Only SQL)数据库,是一种数据结构化存储方法的集合,可以是文档或者键值对等。
优点:
-
格式灵活:存储数据的格式可以是key, value形式, 文档形式, 图片形式等等.
-
使用灵活,应用场景广泛,而关系型数据库则只支持基础的类型
-
速度快:使用内存存储数据,而关系型数据库只能使用硬盘
-
高扩展性
缺点:
-
不提供sql支持,学习和使用成本较高
-
数据结构相对复杂,复杂查询方面稍欠
-
只适合存储一些较为简单的数据,对于需要进行较复杂查询的数据,关系型数据库显的更为合适
-
不适合持久存储海量数据
命令窗口连接mysql数据库
SQL中常见的数据类型
1.整数类型:
int(长度限制):
长度限制可指定也可不指定
指定了长度限制,超过指定的限制,自动扩充
2.浮点类型:
double(m,n):
长度限制需要指定
指定了长度限制,不可以超过指定的限制
m整体的长度
n小数的长度
3.字符类型:
char(长度限制):
长度限制需要指定
指定了长度限制,不可以超过指定的限制
直接分配指定的空间
varchar(长度限制)
长度限制需要指定
指定了长度限制,不可以超过指定的限制
根据内容动态分配空间
4.日期与时间类型:
date:日期
datetime:日期+时间
timestamp:日期+时间
SQL分类
DQL(数据查询语言): DQL主要用于数据的查询,其基本结构是使用SELECT子句,凡是select语句都是DQL。FROM子句和WHERE子句的组合来查询一条或多条数据。 例如: select from where order by having。
DML(数据操作语言):insert delete update,对表当中的数据进行增删改。
DDL(数据定义语言):create drop alter,对是数据库对象(数据库、表、索引、视图)进行创建, 修改和删除操作。 TCL(事务控制语言):TCL用于数据库的事务管理。 start transaction: 开启事务 commit提交事务,rollback回滚事务。(TCL中的T是Transaction)
DCL(数据控制语言): DCL用来授予或回收访问数据库的权限。 grant授权、revoke撤销权限等。
注意:数据操作语言DML(insert,update,delete)针对的是表中数据;而数据定义语言DDL(create,alter,drop)针对数据库对象,比如database,表table,索引index,视图view,存储过程procedure。
DDL(数据定义语言)操作库,表
操作库
1.查看所有库 :show databases;
2.创建新的库:create databse zqwl;
3.删除库:drop database zqwl;
4.选择某个库:use zqwl;
操作表
1.查看所有表:show tables;
2.创建表:create table 表名(
字段名(列名) 数据类型,
字段名(列名) 数据类型,
...
)
注意:
字段后还有其他字段,必须有 ,
最后一个字段后不允许有 ,
表名,字段名多个单词,多个单词之间使用 _ 连接
3.查看表结构:desc student;
4.查看建表语句:show create table student;
5.删除表:drop table student;
6.修改表信息:1.修改表名:rename table student to stu; 2.修改表中字段的类型:alter table stu modify sex varchar(5); 3.修改表中字段的名字:alter table stu change enrollment_date e_date date;
7.添加新的字段
alter table stu add bir date; -- 默认添加到最后位置
alter table stu add count int first; -- 添加到第一个位置
alter table stu add test char(3) after sname; -- 添加到指定字段的后边
DML数据操作语言
1.添加数据
insert into 表名(字段名,字段名,...) values(值,值,...);
注意:
1.值的个数和字段个数相同
2.值的类型和字段类型相同
3.值的范围不能超过指定的范围
4.字符类型,可以使用 '' 或 ""
5.日期类型可以使用字符类型,'yyyy-MM-dd' "yyyy-MM-dd"
日期函数
6.为所有的字段添加值,字段名可以省略不写
7.添加部分字段,字段不可以省略,必须手动指定为哪些字段添加值
2.修改数据
update 表名 set 字段名=新值, 字段名=新值, ... where 条件
注意:
1.修改时一定要添加条件,否则修改全部
2.条件
字段名=值(常用)
字段名>值
字段名<值
...
3.删除数据
delete from 表名 where 条件;
注意:
1.删除时一定加条件,否则删除全部数据。
删除全部数据:
1.delete from 表名; 一条一条删除
2.truncate table 表名; 复制表结构,创建新表。原表直接删除。
char和varchar区别
1.char的长度固定,即每条数据占用等长字节空间;适合用于身份证,手机号等定长。
2.varchar长度可变,可以设置最大长度,varchar类型能够根据字符串的实际长度来动态改变所占字节的大小,所以不能明确该字段具体需要多少字符时推荐使用varchar类型,这样可以大大地节约磁盘空间,提高存储效率。
3.char和varchar表示的是字符个数,而不是字节数。.txt不设置长度,当不知道属性的最大长度时,适合用text。
4.按照查询速度:char最快,varchar次之,text最慢。
day02
约束
表的约束:为表中的字段添加约束,表中数据的完成性和正确性。
一张表中允许出现多个不同的约束,
一个字段允许使用多个约束。
1.主键约束
非空+唯一(值不允许为空且不能重复)
primary key
注意:
表中都会创建一个例如:id的字段,id字段作为主键,可以和业务需求没有关联,
主键为程序或数据库使用的。
一张表中只能有一个主键。
主键自增 auto_increment
没有指定主键值,指定为null,default,使用自增策略
指定了主键值,使用指定的主键值
2.非空约束
值不允许为空
not null
一个表中可以出现多个非空约束
3.唯一约束
值不允许重复
unique
一个表中可以出现多个唯一约束
4.默认值约束
添加时没有指定值,使用默认值
default '值'
一个表中可以出现多个默认值约束
注意:
1.值为null,默认值不生效,使用null
2.值为default,默认值生效,使用默认值
3.不指定默认值约束的字段,默认值生效,使用默认值
5.检查约束(MySQL8新增)
检查值是够符合要求
check(字段名=值 or 字段名=值)
check(字段名>值 and 字段名<值)
...
DQL数据查询语言,SQL中的函数
1.单行函数:对一行中的数据进行操作,操作多少行返回多少行。
1.字符串函数
2.数值函数
3.日期与时间函数
4.流程控制函数
5.其他函数
2.多行函数:对一列中的数据进行操作,最终返回一个结果。
实操示例
select * from emp;//查看整张表。
select eid, ename from emp;
select ename "员工姓名" from emp;
select eid "编号" , ename "姓名", sex "性别",salary "薪资",hire_date "入职日期",dept_name "部门名称" from emp;
select dept_name "部门名称" from emp;
select distinct dept_name "部门名称" from emp;
select ename "员工姓名",salary "原薪资",salary+1000 "现薪资" from emp;
select * from emp where ename="黄蓉";
select * from emp where salary=5000;
select * from emp where salary !=5000;//查询薪水价格不是5000的所有员工信息
select * from emp where salary <>5000;
select * from emp where salary between 5000 and 10000;//查询薪水价格在5000到10000之间的员工信息
select * from emp where salary in (3600,7200,20000);//查询薪水价格是3600或7200或者20000的员工信息
select * from emp where ename like "%八%";//查询含有'八'字的员工信息
select * from emp where ename like "孙%";//查询以'孙'字开头的员工信息
select * from emp where ename like "_兔%";//查询第二个字为'兔'的员工信息
select * from emp where dept_name is null;//查询没有部门的员工信息
select * from emp where dept_name is not null;//查询有部门的员工信息
select * from emp order by salary;//默认升序
select * from emp order by salary desc;//默认降序
select * from emp order by salary, hire_date desc;//salary按升序排列,hire_date按降序排列
select concat("编号:",eid),concat("姓名:",ename),concat("性别:",sex) from emp;//查询emp表所有数据, 将eid, ename, sex显示格式为 编号: x 姓名: xx 性别: x
select eid,insert(ename,2,1,"某"),sex from emp;//将ename第二个字符全部替换为“某”
select eid,ename,length(ename),sex from emp;//显示ename长度
select eid,ename,upper(ename),sex from emp;//将ename,有英文的全部大写
select eid,ename,lower(ename),sex from emp;//将ename,有英文的全部小写
select eid,ename,substring(ename,1,1),sex from emp;//查询表中的数据,ename只显示姓
select ABS(-10);//返回绝对值
select ceil(1.2);//返回大于num的最小整数(向上取整)
select abs(-1), ceil(3.2), floor(3.7), round(3.5), mod(10,3), pi(), pow(2,5), sqrt(25);
select curdate(), curtime(), now(), sleep(2), sysdate();
select eid ,ename,salary,if (salary>=10000,"高工资","低工资") from emp;//#1 查询emp表所有数据, 薪资 >= 10000 高工资 其他 低工资
select eid,ename,salary,salary*12+30000"年薪" from emp;//查询emp表所有数据, 计算出员工的年薪 薪资*12 加年终奖(每人30k),需要考虑null。
select eid,ename,salary,ifnull(salary,0)*12+30000"年薪"from emp;
select eid,ename,salary,case when salary>=15000 then "优秀" when salary>=9000 then "坚持住" when salary>=5000 then "加油哟" when salary>=3000 then "加把劲" else "努力奋斗吧骚年" end from emp;
select database(),user(),version(),inet_aton("192.168.10.1"),inet_ntoa(3232238081);
select count(eid) from emp;//查询员工的总数
select count(*) from emp;
select count(1) from emp;
//查看员工总薪水、最高薪水、最小薪水、薪水的平均值, 显示为总薪水
select sum(salary),max(salary),min(salary),avg(salary) from emp;
//查询薪水大于4000员工的个数
select count(ename)from emp where salary>4000;
//查询部门为'教学部'的所有员工的个数
select count(1) from emp where dept_name="教学部";
//查询部门为'市场部'所有员工的平均薪水
select avg(salary) from emp where dept_name="市场部";
//查询部门的个数
select count(distinct dept_name) from emp;
//查询每个部门的名称
select dept_name from emp group by dept_name
//查询每个部门名称及部门的平均薪资
select dept_name,avg(salary) from emp group by dept_name;
//查询每个部门名称及部门的平均薪资, 部门名称不能为空
select dept_name,avg(salary) from emp where dept_name is not null group by dept_name;
//查询每个部门名称及部门的平均薪资 , 只显示平均工资在4000以上的
select dept_name,avg(salary) from emp group by dept_name having avg(salary)>4000;
//统计每个部门中的最小工资, 列出最小工资小于4000的部门名称及最小薪资
select dept_name,min(salary) from emp group by dept_name having min(salary)<4000;
//统计平均工资大于6000的部门名称
select dept_name,avg(salary) from emp group by dept_name having avg(salary)>6000;
//统计人数小于4个人部门的平均工资
select dept_name,avg(salary),count(1) from emp group by dept_name having count(1)<4;
//统计每个部门最高工资, 排除最高工资小于10000的部门
select dept_name,max(salary) from emp group by dept_name having max(salary)>=10000;
//查询emp表中 从第4条开始, 查询6条
select * from emp limit 3,6;
//查询emp表中的前5条数据
select * from emp limit 5;
面试题
把上面这个表格数据转换成下面这个表格样式(行列转换)
SQL执行流程
组件介绍
-
连接管理与安全验证:MySQL有连接池(Connection Pool)管理客户端的连接。客户端连接后会验证用户名、密码、主机信息等
-
缓存(Cache&Buffer):缓存中存储了SQL命令的HASH,直接比对SQL命令的HASH和缓存中key是否对应,如果对应,直接返回结果,不再执行其他操作。由于缓存的是SQL的HASH,所以根据Hash特性SQL中空格等内容必须完全一样。缓存里面包含表缓存、记录缓存、权限缓存等。查询语句执行完成后会把查询结果缓存到缓存中。在MySQL中查询缓存默认不开启。考虑到查询缓存性能瓶颈问题,从MySQL8开始已经不支持查询缓存了。
-
解析器(Parser)主要作用是解析SQL命令。将SQL命令分解成数据结构(解析树),后续的操作都是基于这个结构的。如果在分解过程中遇到错误,出现SQL解析错误。解析时主要检查SQL中关键字,检查关键字是否正确、SQL中关键字顺序是否正确、引号是否对应是否正确等。
-
预处理器:根据解析器的解析树,进一步检查表是否存在、列是否存在、名字和别名是否有歧义等。
-
优化器(Optimizer):根据官网说明在执行SQL查询时会根据开销自动选择最优查询方案。采用“选择-投影-连接”的策略。先选择where中的行数。同时先选择要选择的列,而不是全部列,最后把内容合并到一起。
-
执行器:包含执行SQL命令。获取返回结果。生成执行计划等。
-
存储引擎:访问物理文件的媒介
执行流程说明
-
客户端向服务器端发送SQL命令和连接参数
-
服务器端连接模块连接并验证
-
缓存模块解析SQL为Hash并与缓存中Hash表对应。如果有结果直接返回结果,如果没有对应继续向下执行。如果是MySQL 8 是没有查询缓存的。
-
解析器解析SQL为解析树,检查关键字相关问题,如果出现错误,报SQL解析错误。如果正确,继续执行
-
预处理器对解析树继续处理检查表、列别名等,处理成功后生成新的解析树。
-
优化器根据开销自动选择最优执行计划,生成执行计划
-
执行器执行执行计划,访问存储引擎接口
-
存储引擎访问物理文件并返回结果
-
如果开启查询缓存,缓存管理器把结果放入到查询缓存中。
-
返回结果给客户端
day03
外键约束
外键指的是在主表中与从表的主键对应的的那个字段, 如员工表的dep_id, 就是外键。 使用外键约束可以让两张表之间产生一个对应关系, 从而保证主从表数据的完整性。
外键约束注意事项
1) 从表的外键类型必须和主表的主键类型保持一致
2) 添加从表数据时
从表中添加的外键值, 必须在主表的主键中存在
3) 删除和变更数据主表数据时
先删除从表中的数据或将外键设置为null, 再删除主表中的数据
4) 通过navicat设置外键约的束变更和删除的级联操作
笛卡尔积
多表之间的连接方式
1.内连接:通过条件匹配两张表中的数据,能匹配就显示,不能匹配不显示。
SQL92:select 字段,... from 表1,表2 where 条件;
SQL99:elect 字段,... from 表1 [inner] join 表2 on 条件;
实现:
1.不同的表进行内连接
2.同一张表(自连接)进行内连接
3.判断条件为等值判断,等值内连接
SQL92:select 字段,... from 表1,表2 where 字段1=字段2;
SQL99:select 字段,... from 表1 join 表2 on 字段1=字段2;
4.判断条件为非等值判断,非等值内连接
SQL92:select 字段,... from 表1,表2 where 字段1 between 字段2 and 字段3;
SQL99:select 字段,... from 表1 join 表2 on 字段1 between 字段2 and 字段3;
2.外连接:
1.左外连接:以左表为主,左表中的数据全部显示,右表没有匹配的数据以null填充。
select 字段,... from 表1 left [outter] join 表2 on 条件;
实现:
1.不同的表进行左外连接
2.同一张表(自连接)进行左外连接
3.判断条件为等值判断,等值左外连接
SQL99:select 字段,... from 表1 left join 表2 on 字段1=字段2;
4.判断条件为非等值判断,非等值左外连接
SQL99:select 字段,... from 表1 left join 表2 on 字段1 between 字段2 and 字段3;
2.右外连接:以右表为主,右表中的数据全部显示,左表没有匹配的数据以null填充。
select 字段,... from 表1 right [outter] join 表2 on 条件;
实现:
1.不同的表进行右外连接
2.同一张表(自连接)进行右外连接
3.判断条件为等值判断,等值右外连接
SQL99:select 字段,... from 表1 right join 表2 on 字段1=字段2;
4.判断条件为非等值判断,非等值右外连接
SQL99:select 字段,... from 表1 right join 表2 on 字段1 between 字段2 and 字段3;
3.MySQL不支持全外连接
左右表中数据都展示,没有匹配填充null
左外连接
union
右外连接
将左外连接的结果和右外连接的结果进行合并,合并时去重。
各个关键字执行顺序
day04
子查询
单行子查询
多行子查询
TCL事务控制语言
事务控制:TCL
事务由1条或多条sql组成,事务中的sql要么全部成功,要么全部失败。
成功:事务提交(将数据永久存储,数据存储到本地磁盘中)
失败:事务回滚(将事务中完成的操作恢复到开启事务时数据的状态)
MySQL的事务:
1.默认:自动提交。
2.手动控制事务
1.开启事务(不再使用自动提交) start trsaction | begin
2.执行sql
3.事务结束
成功:事务手动提交 commit
失败:事务回滚
手动回滚 rollback
出现宕机等原因,自动回滚
事务的四大特性
mysql并发访问会存在的问题
设置隔离级别可防止并发产生的问题
注意事项:
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
MVCC多版本控制机制,读取时采用快照读,读取的内容来源于快照,解决不可重复读,幻读。
多次读取过程中例如变更全部数据,读取最新的数据,造成幻读
查看隔离级别和设置隔离级别
索引
索引在数据库底层有两种结构:BTREE和HASH。默认使用的是BTREE,mysql索引采用的是B+Tree,比b-tree底层多了个叶子节点用指针连接,这样就可以进行范围查询。
相比B-树,B+树进行范围查找时,只需要查找定位两个节点的索引值,然后利用叶子节点的指针进行遍历即可。而B-树需要遍历范围内所有的节点和数据,显然B+Tree效率高。
Hash结构
优点:Hash底层实现是由Hash表来实现的,是根据键值 <key,value> 存储数据的结构。非常适合根据key查找value值,也就是单个key查询,或者说等值查询。
缺点:
1) 哈希表是把索引字段映射成对应的哈希码然后再存放在对应的位置,这样的话,如果我们要进行模糊查找的话,显然哈希表这种结构是不支持的,只能遍历这个表
2) 适合于精确的查找,也不适合范围查询
b-tree结构
-
索引值和data(数据)分布在整棵树结构中
-
每个节点可以存放多个索引值以及对应的data(数据)
-
树节点中的多个索引值从左到右升序排列
缺点:
所有的节点都存放数据,数据会占用空间,导致存放的索引变少。
b+tree结构
-
非叶子节点不存储data数据,只存储索引值,这样便于存储更多的索引值
-
叶子节点包含了所有的索引值和data数据
-
叶子节点用指针连接,提高区间的访问性能
索引的优点
为什么要创建索引?这是因为,创建索引可以大大提高系统的查询性能。
-
通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
-
可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
-
可以加速表和表之间的连接,特别是在实现数据的完整性方面特别有意义。
-
在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
-
通过使用索引,可以在查询的过程中 ,使用查询优化器,提高系统的性能。
索引的缺点
也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。
虽然,索引有许多优点, 但是,为表中的每一个列都增加索引,是非常不明智的。 这是因为,增加索引也有许多不利的一个方面:
-
创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
-
索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间。如果要建立聚簇索引,那么需要的空间就会更大。
-
当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
什么样的字段适合做索引
-
在经常需要搜索的列上,可以加快搜索的速度;
-
在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
-
在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
-
在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
-
在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
-
在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度
什么样的字段不适合做索引
同样,对于有些列不应该创建索引。一般来说,不应该创建索引的这些列具有下述特点:
-
对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
-
对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
-
对于那些定义为text,image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
-
当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
索引分类
1.单列索引
1.主键索引:添加了主键约束,自动创建主键索引。
唯一 + 非空
2.唯一索引:添加了唯一约束,自动创建索引索引。手动添加唯一索引。
唯一 可以为null
3.普通索引:建立在非主键约束,外键约束,唯一约束的列上。
不唯一 可以为null
2.组合索引 | 联合索引
为多个列建立索引。
(col1,col2) -> col1 建立索引 col1,col2 建立索引
使用时必须满足最左前缀原则。
3.全文索引
你站在这里不要动,我去给你买几个橘子。
你站 站在 在这 这里 里不 ...
注意事项:
1.默认按照空格拆词,拆出的字符至少3个才生效,对中不友好。
2.手动指定拆词器,with parser ngram,按照指定的字符个数进行拆词。
中文拆词器
count(*),count(列),count(1)的区别(面试题)
对于InnoDB引擎count(*)和count(1)没有性能的区别,都是自动寻找主键列或唯一索引且非空约束。统计的时候都是统计包含null的行,所以效果都是返回表中数据的行数。 而count(列) 统计列中包含多少行数据,不包含NULL值。
索引优化
视图
什么是视图
-
视图是一种虚拟表
-
视图建立在已有表的基础上,视图建立依赖的这些表称为基表
-
向视图提供数据内容的语句为 SELECT 语句,可以将视图理解为存储起来的 SELECT 语句
-
视图向用户提供基表数据的另一种表现形式
视图作用
简化复杂的查询
-
视图本身就是一条查询SQL,我们可以将一次复杂的查询构建成一张视图,用户只要查询视图就可以获取想要得到的信息(不需要再编写复杂的SQL),可以理解为查询视图就相当于将创建视图的SQL再次执行一次
-
视图主要就是为了简化复杂查询
视图的使用
视图和表的区别
-
视图是建立在表的基础上,表存储数据库中的数据,而视图只是做一个数据的展示
-
通过视图不能改变表中数据(一般情况下视图中的数据都是表中的列 经过计算得到的结果,不允许 更新)
-
删除视图,表不受影响,而删除表,视图不再起作用
DCL数据控制语言
用户管理
MySQL中可创建不同的用户,并分配不同的权限,保证MySQL中数据的安全性
MySQL用户主要包括两种:
-
root用户为超级管理员
拥有MySQL提供的所有权限
-
普通用户:
权限取决于该用户在创建时被赋予的权限有哪些. 没有赋予任何权限,只有可以登录mysql的权限
权限管理
-
MySQL通过权限管理机制可以给不同的用户授予不同的权限,从而确保数据库中数据的安全性
-
只能给存在的用户授权
-
新创建的用户只有登录的权限(USAGE)
角色管理
数据库三范式
概念: 三范式就是设计数据库的规则,是符合某一种设计要求的总结
1) 为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据 库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式
2) 满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的 称为第二范式(2NF) , 其余范式以此类推。一般说来,数据库只需满足第三范式(3NF)就 行了
第一范式
数据库表里面字段都是单一属性的,不可再分,如果数据表中每个字段都是不可再分的最小数据单元(原子性,列不可再分)
第二范式
1) 在第一范式的基础上更进一步,目标是确保表中的每列都和主键相关
第一范式基础上,需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)
2) 一张表只能描述一件事
第三范式
第二范式的基础上,需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。