1.八、数据库设计范式
数据库设计范式实际上很是的重要,可是从实际的开发来看,若是真的所有按照范式去作,则这个程序无法写,包括查询语句也会变得复杂。
在Oracle中的scott用户的所有表,实际上就已经很好的体现了一张设计思路,雇员-部门的关系。
1) 第一范式
例如,如今假设有以下的数据库建立脚本
create table person(
pid number(4) primary key not null,
name varchar2(50),
info varchar(200)
);
插入如下测试数据
insert into person(pid,name,info) values(1111,'张三','1983年11月23日出生,如今的住址是:北京市西城区。。。。。');
实际上对于人员来看,由如下几部分组成:
|-生日:1983年1月23日
|-省市:北京
|-地区:西城区
|-详细的信息:。。。。。
每一个字段不可再分,因此,以上的数据库建立脚本修改以下:
create table person(
pid number(4) primary key not null,
name varchar2(50),
birthday date,
area varchar2(200),
subarea varchar2(200),
address varchar2(200)
);
这种设计看上去每一个字段是不可再分的,可是咱们应该会注意到,在一些网站的注册中,会要求用户分别输入“姓”和“名”,因此,可将上面的设计修改以下:
create table person(
pid number(4) primary key not null,
姓 varchar2(50),
名 varchar2(50),
birthday date,
area varchar2(200),
subarea varchar2(200),
address varchar2(200)
);
因此,在设计表字段的时候,最好保证每一个字段均不能再分。
2) 第二范式
第一范式的要求很是简单,保证每一个字段有意义。可是若是全部的操做都使用第一范式,那么会存在问题:
如今创建一张学生选课表:学号、姓名、年龄、课程名称、成绩、学分
create table selectcourse(
stuno varchar2(50),
stuname varchar2(50),
stuage number,
cname varchar2(50),
grade number,
credit number
);
以上的脚本符合第一范式的要求,可是若是按照第一范式设计的话,会存在问题:
insert into selectcourse values('s001','张三',21,'JAVA',89,0.3);
insert into selectcourse values('s001','李四',20,'JAVA',78,0.3);
insert into selectcourse values('s001','王五',23,'JAVA',80,0.3);
insert into selectcourse values('s001',赵六',22,'JAVA',90,0.3);
从以上的数据库脚本上能够发现,全部的课程信息冗余了,并且还存在如下问题:
|-若是一门课程没有一个学生选择,则此而成就从学校完全消失了
|-课程中自己也应该包含一个课程的编号,可是若是按照以上的设计,则课程编号确定重复
|-若是要更改课程信息,则要更改许多条记录
咱们使用第二范式修改数据库脚本:
|-学生是一个实体--学生表
create table student(
stuno varchar2(50) primary key not null,
stuname varchar2(50),
stuage number
);
|-课程也应该是一个实体--课程表
create table course(
cid number(5) primary key not null,
cname varchar2(50),
credit number
);
|-学生选课信息也是一个实体--学生选课表
create table selectcourse(
stuno varchar2(50),
cid number(5),
grade number,
加入外键关联,由于学生没了,成绩就没了,由于课程没了,成绩就没了
);
以上设计解决了如下问题:
|-学生不选课的时候,课程信息不会消失
|-更新课程的时候直接更新课程表便可
|-全部的关联关系在关系表中体现。
3) 第三范式
在实际开发中,第三范式的使用是最多的。
例如,如今要求设计一张学生表,包含学号、姓名、年龄、所在院校、学院地址、学院电话,此时确定不能使用第一范式,可是如今若是使用的是第二范式呢?
create table student(
stuno varchar2(50) primary key not null,
stuname varchar2(50),
stuage number
);
create table collage(
cid number(4) primary key not null,
cname varchar2(50) not not null,
caddress varchar2(200) not nul,
ctel varchar2(200) not null
);
create table studentcollage(
stuno varchar2(50),
cid number(4),
设置主-外键关系
);
按照上面的设计,一个学生能够同时在多个学院同时上课,多个学院会同时有同一个学生,此时,最好的作法是:一个学院包含多个学生,一个学生属于一个学院,实际上,此设计就彻底相似于部门和雇员表的设计结构。
create table collage(
cid number(4) primary key not null,
cname varchar2(50) not not null,
caddress varchar2(200) not nul,
ctel varchar2(200) not null
);
create table student(
stuno varchar2(50) primary key not null,
stuname varchar2(50),
stuage number,
cid number(4),
创建主-外键关系
);
该设计是一个很明确的一对多的关系设计。
数据库的惟一原则:
|-数据库表的关联查询越少越好,SQL语句的复杂度越低越好。
1.九、数据库设计工具
在实际中数据库也有本身的设计工具,比较经常使用的就是Sybase的PowerDesigner开发工具,此工具能够方便的作各类设计,启动以后,可使用此工具,进行数据库的建模设计。
启动PowerDesigner后,选择新建,Physical Data Model,选择Oracle数据库
下面使用PowerDesigner工具将Oracle中的dept和emp表进行还原
建立表--在工具中进行主-外键的操做--获得关系以后,就能够经过Powerdesigner工具进行数据库脚本的建立了。
1.十、数据库设计分析
1) 要求
设计要求,要求设计一个网上购物程序(使用Powerdesigner创建模型并编写测试数据),有如下的需求
|-管理员能够再后台添加商品,每一个商品属于一个商品组
|-能够对管理员进行分组,对每一组进行分别受权,即一个管理员组能够有多个管理员,一个管理员组有多个权限,一个管理员能够再多个组
|-用户能够本身购买商品,购买商品时要在订单表中添加信息,一个用户能够同时购买多个商品,用户能够选择本身所在的地区进行商品的派送
|-用户能够根据本身的购买积分,对商品进行折扣
2) 实现
根据第一个要求,一个商品属于一个商品组,则此时应该创建一个“一对多”的关系
根据第二个要求,能够对管理员进行分组,须要管理员表、管理员组表、权限表、管理员-管理员组表、管理员组-权限表
管理员和商品表也要存在关系
须要一个用户表,与其产生关系的有地区表、子地区表、订单表、订单详情表、积分表
正常状况下,一份订单确定会按照以上的格式显示,那么请问,这样一来要查询多少张表?
|-用户表(用户姓名、用户电话、用户地址)
|-地区表-子地区表(用户地区)
|-订单表、订单详情表(商品总价、订单日期、邮政编码)
本查询须要同时查询6张表。本程序中的全部代码都是按照标准范式完成的,因此此时出现了以上的问题。
在开发中减小多表查询的方法能够经过冗余数据完成。</pre>
<p> </p>
<pre name="code" >Oracle 笔记
1数据库