oracle数据库设计总结|三大范式
一、实体与表对应关系
表<=>实体,字段<=>属性。
二、表与表的关系(实体间的关系):一对一、一对多、多对多
一对一:一条记录只对应其他表中的一条记录有关系
学生基本信息表t_student,成绩表t_studentScore含有一个外键studentId。基本信息表中的studentId和成绩表中的studentId就是一对一的关系。
一对多:A表一条记录对应B表中多条记录有关系,B表的记录不被A表记录共享(有关系)。
班级表和学生表,一个班级有多个学生,对班级来说就是一对多的关系。
多对多:A表一条记录和B表多条记录有关系,B表的一条记录也和A表的多条记录有关系(互相共享)。
学生表和科目表,学生可以选择多个科目,每个科目可以被多个学生选择。
三、基本表的完整性
(1)原子性。字段是不可再分解的。
(2)原始性。记录是原始数据(基础数据)的记录。
(3)稳定性。结构是相对稳定的,表中的记录是要长期保存的。
(4)演绎性。由基本表与代码表中的数据,可以派生出所有的输出数据。
四、其他常用表
1.中间表
中间表是针对多对多关系的。就比如做公交查询系统,里面有两个表,分别是车站表t_busstation、线路表t_road,根据常识,一个站有多个线路经过,而每个线路又有多个车站,怎么才能将两个表联系起来呢,如果是一对一,一对多,我们一个表, 两个表就可以将他们实现了。但是多对多呢,这样我们就必须借助中间表用来连接两个表。一般中间表只有一个自增主键+两个表的主键。中间表是没有属性的因为它不是一个基本表。
2.临时表
临时表是那些以#号开头为名字的数据表,它主要是用来存放临时数据的,当用户断开连接但没有清除临时表里的数据时,系统会自动把临时表里的数据清空。临时表是放在系统数据库 tempdb中的,而不是当前数据库。
临时表分两种:本地临时表和全局临时表。
a.本地临时表
本地临时表是以#开头的,只对当前的数据库用户可见,而其他的用户是不可见的。当数据库实例断开后当然也就丢失了数据了,不管是显式清空还是系统回收。
b.全局临时表
以“##”开头的,而且是对所有的用户都是可见,当你断开数据库实例连接时,只要还有别的系统项目在引用它,连着数据库,那么数据就存在,只有当别的系统也全部断开连接时,系统才会清除全局临时表的数据。
建立临时表的语句:
本地临时表:
create table #student ( studentID int , studentName nvarchar (40), classID int )
全局临时表:
create table ##student ( studentID int , studentName nvarchar (40). classID int )
也可以用SQL语句完成:
select * from employee into #student
五、三大范式
第一范式:如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式.比如一个工人的基本信息表,里面有工人的工号,性别,年龄,这些属性都是不可分割的,所以这个表就符合了第一范式。
第二范式: 就是在第一范式的基础上延伸,使之表里的每个字段都与主键发生关系。假如一个关系满足第一范式,并且除了主键以外的其它字段,都依赖于该主键,则满足第二范式.
例如:订单表(订单编号、产品编号、定购日期、价格、……),"订单编号"为主键,"产品编号"和主键列没有直接的关系,即"产品编号"列不依赖于主键列,这个列我们就可以把它删除。
第三范式:在第二范式的基础上更进一步,也就是为了实现表里的列都与主键列直接相关,不是间接相关。这个我们可以用“Armstrong 公理”中的传递规则来推理。
定义:
设U是关系模式R 的属性集,F 是R 上成立的只涉及U 中属性的函数依赖集。若X→Y 和 Y→Z在R 上成立,则X →Z 在R 上成立。因此我们就来看在网上搜索到的例子:例如:订单表(订单编号,定购日期,顾客编号,顾客姓名,……),初看该表没有问题,满足第二范式,每列都和主键列"订单编号"相关,再细看你会发现"顾客姓名"和"顾客编号"相关,"顾客编号"和"订单编号"又相关,最后经过传递依赖,"顾客姓名"也和"订单编号"相关。为了满足第三范式,应去掉"顾客姓名"列,放入客户表中。
这里其实就是为了说明数据库的表里步要出现冗余,在顾客表里已经有了"顾客姓名"了,而在订单表里就别出现了,而直接根据顾客编号相关联就可以,否则造成资源浪费。
三大范式延伸:
第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
其实在设计数据库的时候我们最多的要遵循的就是第三范式,但是并不是越满足第三范式数据库就设计的越完美,这种错误是错误的。有时候增加点冗余相反的会提高访问速率,因此在实际的设计过程中应降低对范式的要求。
以前对数据冗余并不是很了解,在百度知道里的定义是这样的:在一个数据集合中重复的数据称为数据冗余. 但是不是说我们表的主键在其他表里重复出现就是冗余,这不是,而是为了连接两个表。只有非键字段就是既不是主键外键等约束的键如果重复出现,就会形成数据冗余。数据冗余也包括重复性冗余和派生冗余。比如工人表里有"基本工资","奖金"两列,然后还有一个"总工资"的列,这个总工资就是派生冗余。低级的重复性冗余一定要避免,杜绝,但是像派生冗余还是提倡的因为它能提高访问的效率。
六、数据库设计中具体要注意的几点;
1.凡是用户输入的不能作为主键;
这点大概都知道,主键是唯一的,一般不能让客户做任何操作;
2.凡是有业务意义的不能作为主键;
既然是具有业务意义,客户随时都有可能提出这个业务,要求修改业务,也会有变动的可能!
3.除非确定是有必要的字段,其他都允许为空;
设计数据库时,约束简单点最好,约束多则在系统中开发时要注意的就多,开发效率相对会底,因为系统是可以通过验证辅助完成这些约束的!
4.不能缺少时间或日期字段;
有时间是永远前进,时间的用处很多,打个很简单的比方,在用户表中我们有一个用户创建的时间,在吧项目交个客户后使用一段时间,客户提出新的需求,
比如说:要搞一个周年庆活动,每个满5个月的用户都奖励200代金卷,等等。在这时我们如国有时间字段,那就很容易加上这个业务,但要是没有呢?
将会如何?修改数据库?公司的利益会受到严重的打击;
5. 业务的时效(时间有效)性;
6.数据的采集宁滥毋缺
这点非常重要,这就是数据库设计者的后瞻能力了,也就是说我们能在用户还没有提出一些新的需求是,已经把数据都采集好了,就等客户提出需求
很轻松的搞定一些业务;有了数据什么都不怕;但有些人也会问,我们前期就把没有用到的数据存进去,后期可以利用也就罢了,如果没有利用到呢?
是不是很浪费空间;其实这个问题,我可以这样回答,绝大多数公司在很多方面都是以空间换取时间的;(相信大家都明白!比如在web中使用的AJAX技术)
7.外键字段需要维护或变更,就需要表来维护,如果字段简单,不需要经常变更的,可以直接是程序维护;
总结
数据库设计就是根据业务系统的具体需要,结合我们所选用的DBMS(数据库管理系统),为这个业务系统构造出最优的数据存储模型,并建立好数据库中的表结构及表与表之间的关联关系的过程。使之能有效的对应用系统中的数据进行存储,并可以高效的对已经存储的数据进行访问。
后面会分享更多关于devops和DBA内容,感兴趣的朋友可以关注下~