Oracle笔记(十六)数据库设计范式(一)

2014-11-24 14:50:25 · 作者: · 浏览: 0

Oracle笔记(十六) 数据库设计范式
相关链接:
Oracle笔记(一)Oracle简介及安装
http://www.2cto.com/database/201209/154049.html;
Oracle笔记(二)SQLPlus命令
http://www.2cto.com/database/201209/154051.html;
Oracle笔记(三)Scott用户的表结构
http://www.2cto.com/database/201209/154052.html;
Oracle笔记(四)简单查询、限定查询、数据的排序
http://www.2cto.com/database/201209/154054.html;
Oracle笔记(五)单行函数
http://www.2cto.com/database/201209/154056.html;
Oracle笔记(六)多表查询
http://www.2cto.com/database/201209/154060.html;
Oracle笔记(七)数据更新、事务处理、数据伪列
http://www.2cto.com/database/201209/154062.html;
Oracle笔记(八)复杂查询及总结
http://www.2cto.com/database/201209/154063.html;
Oracle笔记(九)表的创建及管理
http://www.2cto.com/database/201209/154316.html;
Oracle笔记(十)约束
http://www.2cto.com/database/201209/154317.html;
Oracle笔记(十一)建表、更新、查询综合练习
http://www.2cto.com/database/201209/154621.html;
Oracle笔记(十二)集合、序列
http://www.2cto.com/database/201209/154623.html;
Oracle笔记(十四)用户管理
http://www.2cto.com/database/201209/154886.html;
Oracle笔记(十五)数据库备份
http://www.2cto.com/database/201209/154887.html
数据库设计范式是一个很重要的概念,但是这个重要程度只适合于参考。使用数据库设计范式,可以让数据表更好的进行数据的保存,因为再合理的设计,如果数据量一大也肯定会存在性能上的问题。所以在开发之中,唯一可以称为设计的宝典 —— 设计的时候尽量避免日后的程序出现多表关联查询。
www.2cto.com
一、第一范式
所谓的第一范式指的就是数据表中的数据列不可再分。
例如,现在有如下一张数据表:
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)
); www.2cto.com
但是在这里面有两点需要说明:
第一点,关于姓名,在国外的表设计中,姓名也分为姓和名两类,但是在中国就是姓名保存;
第二点,关于生日,生日有专门的数据类型(DATE),所以不能将其设置为生日年,生日月,生日日;
所谓不可分割指的是所有的数据类型都使用数据库提供好的各个数据类型。
二、第二范式:多对多
第二范式:数据表中的非关键字段存在对任一候选关键字段的部分函数依赖;
第二范式分为两种方式理解:
理解一:列之间不应该存在函数关系,现在有如下一个设计:
CREATE TABLE orders (
  oid NUMBER PRIMARY KEY,
  amount NUMBER,
  price NUMBER,
  allprice NUMBER
);
现在的商品总价(allprice)=商品单价(price)*商品数量(amount),所以存在了函数的依赖关系;
理解二:通过一个数据表的设计体现一下,完成一个学生选课系统,如果说现在按照第一范式,则如下: www.2cto.com
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,89);
INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (2,'李四','Java',3,99);
INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (3,'王五','Java',3,78);
INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (1,'张三',' Oracle',1,79); www.2cto.com
INSERT INTO studentcourse (stuid,stuname,cname,credit,score) VALUES (2,'李四','Oracle',1,89);
这种设计符合于第一设计范式,但是不符合于第二范式,因为程序会存在如下的错误:
数据重复:学生和课程的数据都处于重复的状态,而且最为严重的是主键的设置问题;
数据更新过多:如果说现在一门课程已经有了3000人参加的话,则更改一门课程学分的时候需要修改3000条记录,肯定性能上会有影响;
如果一门课程没有一个学生参加,这门课程就从学校彻底消失了;
如果要想解决此问题,则可以将数据表的设计修改如下:
CREATE TABLE student (
  stuid NUMBER PRIMARY KEY,
  stuname VARCHAR2(20) NOT NULL