数据库设计范式工具 PowerDesigner
数据库范式非常重要,但从实际开发来看,如果真的全部按照范式去做,则
这个程序没法写,包括查询语句也会变得复杂。
在Oracle中的scott用户的全部表,实际上就已经很好的体现了一种设计思路,
雇员-部门的关系。
第一范式:
数据库表中的字段都是单一属性的,不可再分。这个单一属性由其基本类型构成,
包括整型、实数、字符型、逻辑型、日期型等。
插入以下测试数据:
INSERT INTO person(pid,name,info) VALUES (1111,'张三','1983-11-23出生,现在的住址是朝阳区');
实际上对于人员的信息来看,由以下几部分组成:
生日:1983年11月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 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
加入外键关联,因为学生没了,成绩就没了,因为课程没了,成绩也没了。
) ;
INSERT INTO student(stuno,stuname,stuage)VALUES ('s001','张三','20') ;
INSERT INTO student(stuno,stuname,stuage)VALUES ('s002','李四','20') ;
INSERT INTO student(stuno,stuname,stuage)VALUES ('s003','王五','20') ;
INSERT INTO course(cid,cname,credit)VALUES ('ca','JAVA',3) ;
INSERT INTO course(cid,cname,credit)VALUES ('cb','Oracle',5) ;
INSERT INTO selectcourse(stuno,cid,grade) VALUES ('s001','ca',79.0)
INSERT INTO selectcourse(stuno,cid,grade) VALUES ('s001','ca',77.0)
INSERT INTO selectcourse(stuno,cid,grade) VALUES ('s001','ca',77.0)
以上设计解决了问题:
学生不选课的时候,课程信息不会消失
更新课程的时候直接更新课程表即可
所有的关联关系在关系表中体现。
也就是说现在完成了一个多对多的关系。
第三范式
第三范式在实际开发中用的频率最多。
例如,要求设计一张学生表,包含学号、姓名、年龄、所在院校、学院地址、
学院电话,此时肯定不能使用第一范式,但是现在如果使用的是第二范式呢?
CREATE TABLE student(
stuno VARCHAR2(50) PRIMARY KEY NOT NULL,
stuname VARCHAR2(50) ,
stuage NUMBER
) ;
CREATE TABLE college(
cid NUMBER(4) PRIMARY KEY NOT NULL,
cname VARCHAR2(50) NOT NULL ,
caddress VARCHAR2(200) NOT NULL ,
ctel VARCHAR2(200) NOT NULL
) ;
CREATE TABLE studentcollage(
ctuno VARCHAR2(50) ,
cid NUMBER(4) ,
设置主-外键关系
) ;
按照这种设计,一个学生可以同时在多个学生可以在多个学院同时上课,
多个学院会同时有同一个学生在上课。
此时,最好是:一个学院包含多个学生,一个学生属于一个学院。
实际上,此设计就完全类似于部门和雇员表的设计结构。
CREATE TABLE student(
stuno VARCHAR2(50) PRIMARY KEY NOT NULL,
stuname VARCHAR2(50) ,
stuage NUMBER ,
cid BUMBER(4) ,
建立主-外键关联
) ;
是一个很明确的一对多的关系设计。
以上的三个范式只能算是参考,如果真的按照此种方式设计数据库,则有够累,
数据库设计的唯一原则:
·数据库表的关联查询越少越好,sql语句的复杂度越低越好。