数据库设计范式是一个很重要的概念,但是这个重要程度只是适合于参考。使用数据库设计范式,可以让数据表更好的进行数据的保存,因为在合理的设计,如果数据量一大也肯定会存在性能上的问题,所以在开发中,唯一可以称为设计的宝典——设计的时候尽量避免日后的程序出现多表关联查询。
第一范式
所谓的第一范式指的是数据表中的数据列不可再分。例如,现有如下一张表:
CREATE TABLE member( mid NUMBER PRIMARY KEY, name VARCHAR2(200) NOT NULL, contact VARCHAR2(200) )
这个时候设计的就不合理,因为联系方式由多种数据所组成(电话、地址、email、手机、邮政编码等),所以这种设计是不符合第一范式的,现在可以修改设计如下:
CREATE TABLE member( mid NUMBER PRIMARY KEY, name VARCHAR2(200) NOT NULL, address VARCHAR2(200), zipcode VARCHAR2(6), mobile VARCHAR2(20), tel VARCHAR2(20) )
但是在这里有两点需要说明。
1、关于姓名,在国外的表设计姓名也分为姓和名两类,但是在中国就是姓名保存。
2、关于生日,生日有专门的数据类型(DATE),所以不能将其设置为生日年、生日月、生日日;
所谓的不可分割指的是所有的数据类型都是使用数据库提供好的各个数据类型。
第二范式(多对多)
第二范式定义数据表中的非关键字段不存在对任意候选关键字段的部分函数依赖。
第二范式分为两种理解:
1、列之间不应该存在函数关系,现有如下一张表:
CREATE TABLE orders( oid NUMBER PRIMARY KEY, amount NUMBER, price NUMBER, allprice NUMBER )
现在的商品总价(allprice)=商品单价(price)*商品数量(amount),所以存在了函数的依赖关系。
2、通过一个数据表的设计完成一个学生选课系统,如果说现在按照第一范式,则如下设计:
CREATE TABLE studentcourse( stuid NUMBER PRIMARY KEY, stuname VARCHAR2(20) NOT NULL, cname VARCHAR2(50) NOT NULL, credit NUMBER NOT NULL, score NUMBER ) INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (1,’张三’,’java’,3,99); INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (2,’李四’,’java’,3,89); INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (3,’王五’,’java’,3,67); INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (1,’张三’,’C’,1,79); INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (2,’李四’,’C’,1,69);
这种设计符合第一范式,但是不符合第二范式,因为程序会存在如下的错误:
(1)数据重复,学生和课程的数据都处于重复的状态,而且最为严重的是主键的设置问题。
(2)数据更新过多,如果现在一门课程已经有1000人参见的话,则更改一门课程学分的时候,需要修改1000条记录,肯定性能上会有影响。
(3)如果一门课程没有一个学生参加,这门课程就从学校彻底消失了。
如果想要解决此问题,则可以将数据表的设计修改如下:
CREATE TABLE student( stuid NUMBER PRIMARY KEY, stname VARCHAR2(20) NOT NULL ) CREATE TABLE course( cid NUMBER PRIMARY KEY, cname VARCHAR2(50) NOT NULL, credit NUMBER NOT NULL ) CREATE TABLE studentcourse( stuid NUMBER REFERENCES student(stuid), cid NUMBER REFERENCES course(cid), score NUMBER ) INSERT INTO student (stuid,stname) VALUES (1,’张三’); INSERT INTO student (stuid,stname) VALUES (2,’李四’); INSERT INTO student (stuid,stname) VALUES (3,’王五’); INSERT INTO course (cid,cname,credit) VALUES (10,’java’,3); INSERT INTO course (cid,cname,credit) VALUES (11,’c’,1); INSERT INTO course (cid,cname,credit) VALUES (12,’oracle’,2); INSERT INTO (stuid,cid,score) VALUES (1,10,99); INSERT INTO (stuid,cid,score) VALUES (2,10,89); INSERT INTO (stuid,cid,score) VALUES (3,10,67); INSERT INTO (stuid,cid,score) VALUES (1,11,79); INSERT INTO (stuid,cid,score) VALUES (1,11,69); 第三范式(一对多)
例如,一个学校有多个学生,如果用第一范式无法实现,而如果用第二范式则表示多对多的关系,即,一个学校有多个学生,一个学生在多个学校,不符合实际情况。所以此时可以使用第三范式,设计编写如下:
CREATE TABLE school( sid NUMBER PRIMARY KEY, sname VARCHAR2(20) NOT NULL ); CREATE TABLE student( stuid NUMBER PRIMARY KEY, stuname VARCHAR2(20) NOT NULL, sid NUMBER REFERENCES school(sid) );
而在实际的项目之中,第三范式的使用是最多的。
以上三个范式只是作为参考使用,实际项目中需要具体问题具体分析。
数据库的设计工具PowerDesigner
对于数据库设计工具有很多,但是其中最著名的,或者说使用最广泛的就是Sybase PowerDesigner设计工具。