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數據庫