1。在一條街上,有5座房子,噴了5種顏色。
2。每個(gè)房子里住著不同國籍的人。
3。每個(gè)人喝著不同的飲料,抽不同品牌的香煙,養(yǎng)不同的寵物。
問題是:誰養(yǎng)魚?
提示:
1、英國人住紅色房子。
2、瑞典人養(yǎng)狗。
3、丹麥人喝茶。
4、綠色房子在白色房子左面。
5、綠色房子主人喝咖啡。
6、抽Pall Mall香煙的人養(yǎng)鳥。
7、黃色房子主人抽Dunhill香煙。
8、住在中間房子的人喝牛奶。
9、挪威人住第一間房。
10、抽Blends香煙的人住在養(yǎng)貓的人隔壁。
11、養(yǎng)馬的人住抽Dunhill香煙的人隔壁。
12、抽Blue Master的人喝啤酒。
13、德國人抽Prince香煙。
14、挪威人住藍(lán)色房子隔壁。
15、抽Blends香煙的人有一個(gè)喝水的鄰居。
**以下內(nèi)容為網(wǎng)上收集后整理而成,如有錯(cuò)誤或描述不準(zhǔn)確的地方或是別的請多指教.
當(dāng)你使用Tomcat作為Web Server的時(shí)候,是不是會(huì)想過這樣的一個(gè)問題:如何利用Tomcat建立多個(gè)Web應(yīng)用 呢?
要實(shí)現(xiàn)這一點(diǎn)是很簡單的,也有多種方法。(以下說明使用%tomcat_home%代表Tomcat安裝目錄)。
一.首先介紹一下Tomcat及server.xml.
Tomcat服務(wù)器是由一系列的可配置的組件構(gòu)成,tomcat的組件可以在%tomcat_home%/conf/server.xml文件中進(jìn)行配置,每個(gè)Tomcat組件和server.xml文件的一種配置元素對應(yīng).
主要分為4類:
1.頂層類元素:包括<Server>和<Service>,他們位于整個(gè)配置文件的頂層.
<Server>元素代表整個(gè)Catalina Servlet 容器,由org.apache.catalin.Server接口定義.<Server>包含一個(gè)或多個(gè)<Service>元素.
<Service>元素由org.apache.catalin.Service 接口定義.<Service>包含一個(gè)<Engine>元素,及一個(gè)或多個(gè)<Connector>元素.多個(gè)<Connector>元素共享一個(gè)<Engine>元素.
2.連接器類元素
連接器類代表了介于客戶與服務(wù)之間的通信接口,負(fù)責(zé)將客戶的請求發(fā)送給服務(wù)器,并將服務(wù)器的響應(yīng)結(jié)果傳遞給客戶.
<Connector>元素由org.apache.catalin.Connector 接口定義.代表了與客戶程序?qū)嶋H交互的組件,它負(fù)責(zé)接收客戶請求,以及向客戶返回響應(yīng)結(jié)果.
3.容器類元素
容器類元素代表處理客戶請求并生成響應(yīng)的組件.包括<Engine> <Host>和<Context>.
<Engine>元素由org.apache.catalin.Engine 接口定義.每個(gè)<Service>只能包含一個(gè)<Engine>元素,<Engine>元素處理在同一個(gè)<Service>中的所有<Connector>元素收到的客戶請求.
<Host>元素由org.apache.catalin.Host 接口定義.一個(gè)<Engine>元素中可以包含多個(gè)<Host>元素.每個(gè)<Host>元素定義了一個(gè)虛擬主機(jī),她可以包含一個(gè)或多個(gè)Web 應(yīng)用.
<Context>元素由org.apache.catalin.Context 接口定義.代表了運(yùn)行在虛擬主機(jī)上的一個(gè)Web 應(yīng)用.一個(gè)<Host>元素可以包含多個(gè)<Context>元素
4.嵌套類元素
嵌套類元素代表了可以加到容器中的組件,如<Logger> <Realm>和<Value>.
關(guān)于server.xml的更多信息,可以參考Tomcat的文檔:/webapps/tomcat-docs/config/index.html
樣例:
<Server>
<Service name="Catalina">
<Connector acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" port="8080" redirectPort="8443" maxSpareThreads="75" maxThreads="150" minSpareThreads="25"/>
<Connector port="8009" protocol="AJP/1.3" protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler" redirectPort="8443"/>
<Engine defaultHost="localhost" name="Catalina">
<Host appBase="webapps" name="localhost">
<Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_log." suffix=".txt" timestamp="true"/>
</Host>
<Logger className="org.apache.catalina.logger.FileLogger" prefix="catalina_log." suffix=".txt" timestamp="true"/>
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
</Engine>
</Service>
</Server>
二.建立多個(gè)Web應(yīng)用方法:
1.通過配置多個(gè)<Context>元素(這是最為普遍的方法)
在<Host>下配置多個(gè)<Context>元素
<Context path="app1" docBase="E:/workspace/app1/WebRoot" debug="0" reloadable="true"></Context>
<Context path="app2" docBase="E:/workspace/app2/WebRoot" debug="0" reloadable="true"></Context>
然后通過 主機(jī)名:端口/應(yīng)用名 訪問,如: http://localhost:8080/app1 或 http://localhost:8080/app2
2.通過配置多個(gè)<Host>元素
在<Engine>下配置多個(gè)<Host>元素
<Host appBase="webapps" name="192.168.1.110">
<Context path="" docBase="E:/workspace/app1/WebRoot" debug="0" reloadable="true"></Context>
</Host>
<Host appBase="webapps" name="192.168.1.114">
<Context path="" docBase="E:/workspace/app2/WebRoot" debug="0" reloadable="true"></Context>
</Host>
然后通過 主機(jī)名:端口 訪問,如: http://192.168.1.110:8080 或 http://192.168.1.114:8080
需要注意的是這樣需要機(jī)器連接到局域網(wǎng)上.
3.通過配置多個(gè)<Service>元素(多端口 多應(yīng)用)
在<Server>下配置多個(gè)<Service>元素
<Service name="Catalina">
<Connector acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" port="8080" redirectPort="8453" maxSpareThreads="75" maxThreads="150" minSpareThreads="25"/>
<Connector port="8019" protocol="AJP/1.3" protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler" redirectPort="8453"/>
<Engine defaultHost="localhost" name="Catalina">
<Host appBase="webapps" name="localhost">
<Context path="" docBase="E:/workspace/app1/WebRoot" debug="0" reloadable="true"></Context>
</Host>
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
</Engine>
</Service>
<Service name="Catalina2">
<Connector acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" port="8090" redirectPort="8453" maxSpareThreads="75" maxThreads="150" minSpareThreads="25"/>
<Connector port="8019" protocol="AJP/1.3" protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler" redirectPort="8453"/>
<Engine defaultHost="localhost" name="Catalina">
<Host appBase="webapps" name="localhost">
<Context path="" docBase="E:/workspace/app2/WebRoot" debug="0" reloadable="true"></Context>
</Host>
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
</Engine>
</Service>
定義了兩個(gè)Service分別是Catalina和Catalina2,偵聽的端口分別是8080和8090
然后通過 主機(jī)名:端口 訪問,如: http://localhost:8080 或 http://localhost:8090
返回?cái)?shù)據(jù)庫總結(jié)目錄
數(shù)據(jù)類型 |
參數(shù) |
描述 |
char(n) |
n=1 to 2000字節(jié) |
定長字符串,n字節(jié)長,如果不指定長度,缺省為1個(gè)字節(jié)長(一個(gè)漢字為2字節(jié)) |
varchar2(n) |
n=1 to 4000字節(jié) |
可變長的字符串,具體定義時(shí)指明最大長度n,
這種數(shù)據(jù)類型可以放數(shù)字、字母以及ASCII碼字符集(或者EBCDIC等數(shù)據(jù)庫系統(tǒng)接受的字符集標(biāo)準(zhǔn))中的所有符號(hào)。
如果數(shù)據(jù)長度沒有達(dá)到最大值n,Oracle 8i會(huì)根據(jù)數(shù)據(jù)大小自動(dòng)調(diào)節(jié)字段長度,
如果你的數(shù)據(jù)前后有空格,Oracle 8i會(huì)自動(dòng)將其刪去。VARCHAR2是最常用的數(shù)據(jù)類型。
可做索引的最大長度3209。 |
number(m,n) |
m=1 to 38
n=-84 to 127 |
可變長的數(shù)值列,允許0、正值及負(fù)值,m是所有有效數(shù)字的位數(shù),n是小數(shù)點(diǎn)以后的位數(shù)。
如:number(5,2),則這個(gè)字段的最大值是99,999,如果數(shù)值超出了位數(shù)限制就會(huì)被截取多余的位數(shù)。
如:number(5,2),但在一行數(shù)據(jù)中的這個(gè)字段輸入575.316,則真正保存到字段中的數(shù)值是575.32。
如:number(3,0),輸入575.316,真正保存的數(shù)據(jù)是575。 |
date |
無 |
從公元前4712年1月1日到公元4712年12月31日的所有合法日期,
Oracle 8i其實(shí)在內(nèi)部是按7個(gè)字節(jié)來保存日期數(shù)據(jù),在定義中還包括小時(shí)、分、秒。
缺省格式為DD-MON-YY,如07-11月-00 表示2000年11月7日。 |
long |
無 |
可變長字符列,最大長度限制是2GB,用于不需要作字符串搜索的長串?dāng)?shù)據(jù),如果要進(jìn)行字符搜索就要用varchar2類型。
long是一種較老的數(shù)據(jù)類型,將來會(huì)逐漸被BLOB、CLOB、NCLOB等大的對象數(shù)據(jù)類型所取代。 |
raw(n) |
n=1 to 2000 |
可變長二進(jìn)制數(shù)據(jù),在具體定義字段的時(shí)候必須指明最大長度n,Oracle 8i用這種格式來保存較小的圖形文件或帶格式的文本文件,如Miceosoft Word文檔。
raw是一種較老的數(shù)據(jù)類型,將來會(huì)逐漸被BLOB、CLOB、NCLOB等大的對象數(shù)據(jù)類型所取代。 |
long raw |
無 |
可變長二進(jìn)制數(shù)據(jù),最大長度是2GB。Oracle 8i用這種格式來保存較大的圖形文件或帶格式的文本文件,如Miceosoft Word文檔,以及音頻、視頻等非文本文件。
在同一張表中不能同時(shí)有l(wèi)ong類型和long raw類型,long raw也是一種較老的數(shù)據(jù)類型,將來會(huì)逐漸被BLOB、CLOB、NCLOB等大的對象數(shù)據(jù)類型所取代。 |
blob
clob
nclob |
無 |
三種大型對象(LOB),用來保存較大的圖形文件或帶格式的文本文件,如Miceosoft Word文檔,以及音頻、視頻等非文本文件,最大長度是4GB。
LOB有幾種類型,取決于你使用的字節(jié)的類型,Oracle 8i實(shí)實(shí)在在地將這些數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫內(nèi)部保存。
可以執(zhí)行讀取、存儲(chǔ)、寫入等特殊操作。 |
bfile |
無 |
在數(shù)據(jù)庫外部保存的大型二進(jìn)制對象文件,最大長度是4GB。
這種外部的LOB類型,通過數(shù)據(jù)庫記錄變化情況,但是數(shù)據(jù)的具體保存是在數(shù)據(jù)庫外部進(jìn)行的。
Oracle 8i可以讀取、查詢BFILE,但是不能寫入。
大小由操作系統(tǒng)決定。 |
返回?cái)?shù)據(jù)庫總結(jié)目錄
表A MySQL 數(shù)據(jù)類型
數(shù)據(jù)類型
|
描述
|
字節(jié)
|
推薦使用
|
SMALLINT
|
整數(shù),從-32000到 +32000范圍
|
2
|
存儲(chǔ)相對比較小的整數(shù)。
比如: 年紀(jì),數(shù)量
|
INT
|
整數(shù),從-2000000000 到 +2000000000 范圍
|
4
|
存儲(chǔ)中等整數(shù)
例如: 距離
|
BIGINT
|
不能用SMALLINT 或 INT描述的超大整數(shù)。
|
8
|
存儲(chǔ)超大的整數(shù)
例如: 科學(xué)/數(shù)學(xué)數(shù)據(jù)
|
FLOAT
|
單精度浮點(diǎn)型數(shù)據(jù)
|
4
|
存儲(chǔ)小數(shù)數(shù)據(jù)
例如:測量,溫度
|
DOUBLE
|
雙精度浮點(diǎn)型數(shù)據(jù)
|
8
|
需要雙精度存儲(chǔ)的小數(shù)數(shù)據(jù)
例如:科學(xué)數(shù)據(jù)
|
DECIMAL
|
用戶自定義精度的浮點(diǎn)型數(shù)據(jù)
|
變量;取決于精度與長度
|
以特別高的精度存儲(chǔ)小數(shù)數(shù)據(jù)。
例如:貨幣數(shù)額,科學(xué)數(shù)據(jù)
|
CHAR
|
固定長度的字符串
|
特定字符串長度(高達(dá)255字符)
|
存儲(chǔ)通常包含預(yù)定義字符串的變量
例如: 定期航線,國家或郵編
|
VARCHAR
|
具有最大限制的可變長度的字符串
|
變量; 1 + 實(shí)際字符串長度 (高達(dá) 255 字符)
|
存儲(chǔ)不同長度的字符串值(高達(dá)一個(gè)特定的最大限度).
例如:名字,密碼,短文標(biāo)簽
|
TEXT
|
沒有最大長度限制的可變長度的字符串
|
Variable; 2 +聽 actual string length
|
存儲(chǔ)大型文本數(shù)據(jù)
例如: 新聞故事,產(chǎn)品描述
|
BLOB
|
二進(jìn)制字符串
|
變量;2 + 實(shí)際字符串長度
|
存儲(chǔ)二進(jìn)制數(shù)據(jù)
例如:圖片,附件,二進(jìn)制文檔
|
DATE
|
以 yyyy-mm-dd格式的日期
|
3
|
存儲(chǔ)日期
例如:生日,產(chǎn)品滿期
|
TIME
|
以 hh:mm:ss格式的時(shí)間
|
3
|
存儲(chǔ)時(shí)間或時(shí)間間隔
例如:報(bào)警聲,兩時(shí)間之間的間隔,任務(wù)開始/結(jié)束時(shí)間
|
DATETIME
|
以yyyy-mm-ddhh:mm:ss格式結(jié)合日期和時(shí)間
|
8
|
存儲(chǔ)包含日期和時(shí)間的數(shù)據(jù)
例如:提醒的人,事件
|
TIMESTAMP
|
以yyyy-mm-ddhh:mm:ss格式結(jié)合日期和時(shí)間
|
4
|
記錄即時(shí)時(shí)間
例如:事件提醒器,“最后進(jìn)入”的時(shí)間標(biāo)記
|
YEAR
|
以 yyyy格式的年份
|
1
|
存儲(chǔ)年份
例如:畢業(yè)年,出生年
|
ENUM
|
一組數(shù)據(jù),用戶可從中選擇其中一個(gè)
|
1或 2個(gè)字節(jié)
|
存儲(chǔ)字符屬性,只能從中選擇之一
例如:布爾量選擇,如性別
|
SET
|
一組數(shù)據(jù),用戶可從中選擇其中0,1或更多。
|
從1到8字節(jié);取決于設(shè)置的大小
|
存儲(chǔ)字符屬性,可從中選擇多個(gè)字符的聯(lián)合。
例如:多選項(xiàng)選擇,比如業(yè)余愛好和興趣。
|
對于一個(gè)完整的列表和詳細(xì)描述,可以查看MySQL manual。你也可以閱讀文章Choosing the Right Type for a Column。
現(xiàn)在的程序員找工作不太容易,而我招聘程序員也不太容易,雙方的需求總是有著很大的差距。來面試的人里面有一半是剛剛畢業(yè)或者剛剛參加XX計(jì)算機(jī)培訓(xùn)出來的,對于Asp.net編程的理解,就是打開Visual studio,新建一個(gè)頁面,拖拖控件,雙擊一個(gè)按鈕寫一下SQL操作的代碼,僅此而已。
以前我在面試的時(shí)候喜歡問他們有沒有學(xué)過設(shè)計(jì)模式,有沒有看過敏捷編程,知不知道測試驅(qū)動(dòng)開發(fā),喜歡上什么樣的網(wǎng)站,知不知道現(xiàn)在互聯(lián)網(wǎng)領(lǐng)域流行什么。后來我就不怎么問了,因?yàn)闆]有一個(gè)人答的出來。當(dāng)然,這些東西對于一個(gè)程序員崗位來說并不是必須的,但是我們是一個(gè)互聯(lián)網(wǎng)公司,而且是個(gè)小型的互聯(lián)網(wǎng)公司。首先你必須要了解這個(gè)行業(yè),才有可能有自己的想法。要了解它,就必須熱愛它。如果只是因?yàn)樽约簩W(xué)了編程這個(gè)東西,而不得不來找一份寫代碼的工作,那么我可以假設(shè),你除了完成我告訴你的功能函數(shù),是不會(huì)為公司提出什么建設(shè)性的意見和想法的。
退一步講,即使你喜歡的并不是互聯(lián)網(wǎng),你也沒想過創(chuàng)業(yè),但是要想做好一份工作,你首先要喜歡這份工作本身。如果你喜歡編程,喜歡寫代碼所帶來的美好的感覺,那么你應(yīng)該時(shí)刻關(guān)注著這個(gè)領(lǐng)域的新的動(dòng)向,和更高層次的要求。我當(dāng)然不是說你應(yīng)該去學(xué)習(xí)所有新出來的技術(shù)和語言,語言其實(shí)并不重要,重要的編程的思想本身。了解設(shè)計(jì)模式的人所做出來的程序架構(gòu),一定比從沒聽說過設(shè)計(jì)模式的人要好的多。雖然我們在實(shí)際工作中也沒有要求一定要使用測試驅(qū)動(dòng)開發(fā)的模式,但是知道這些概念,意味著你喜歡編程這份工作,意味著你時(shí)刻在關(guān)注著這個(gè)行業(yè),而不是只是為了上班的時(shí)候完成老板的任務(wù),下班以后就連看都懶的看電腦一眼。
好的工作狀態(tài)是需要熱情的,更好的工作狀態(tài)是需要激情的。
國內(nèi)都說程序員的工作只能在30歲以前做,這句話有幾個(gè)基本前提:首先,大部分IT公司不夠大,只能以最小的成本解決最根本的需求,人過30,對待遇的要求當(dāng)然不能跟剛出校門的學(xué)生比,而學(xué)生經(jīng)過一段時(shí)間的培訓(xùn),在工作上完全能夠滿足公司的要求,所以,公司不會(huì)養(yǎng)一群年紀(jì)大的程序員。其次,編碼這種工作,本身是無聊之極的,所以公司需要的是有相當(dāng)有創(chuàng)意的員工,敢于打破原有的思考習(xí)慣,以特殊的角度看世界,這一點(diǎn),30歲以上的人是比較難做到的。在同一個(gè)領(lǐng)域做的時(shí)間越長,思維就越容易僵化,越不敢輕易的打破傳統(tǒng)。再者,外人看IT業(yè)都是高薪行業(yè),如果過了30歲事業(yè)還沒有起色,基本他也做不下去了。另外,程序員是個(gè)很累的活,不但是重腦力勞動(dòng),而且是重體力勞動(dòng),過了30歲以后身體狀況下滑,身體也很難承受的住。最后,程序員創(chuàng)業(yè)是最容易的,技術(shù)基本不需要成本,弄臺(tái)服務(wù)器,或者更簡單的租個(gè)空間,自己花一兩個(gè)月的人力成本,一個(gè)網(wǎng)站就起來了,在這個(gè)全民創(chuàng)業(yè)的大環(huán)境下,能忍受誘惑的人,不多。
那么,如果到了30歲,創(chuàng)業(yè)也沒有成功,自己的公司又沒有上市或者被收購,自己還是一個(gè)普普通通的打工者,那怎么辦呢?其實(shí)放遠(yuǎn)了看,大部分人在四五十歲或者一直到退休,也就是拿著兩三千塊錢的工資,一直這樣默默無聞的做下去,而在互聯(lián)網(wǎng)這個(gè)躁動(dòng)的行業(yè),人們似乎已經(jīng)很難接受這種現(xiàn)狀了。因此,你需要提前給自己找好出路。
首先,如果你真的對編程充滿激情,你愿意在某一個(gè)方向深鉆下去,成為該領(lǐng)域數(shù)一數(shù)二的專家,那是最好不過了。中國現(xiàn)在真正缺少的就是這一類人,但是,前提是你可以解決自己的溫飽問題,不用因?yàn)槔习宓母缮娑看螌⒆约旱幕钤诓煌昝赖臓顟B(tài)下丟在一旁。
其次,因?yàn)轫?xiàng)目經(jīng)驗(yàn)的積累,你的能力足以領(lǐng)導(dǎo)多人的團(tuán)隊(duì),進(jìn)行溝通協(xié)調(diào)和管理,那么,你可以做一個(gè)部門經(jīng)理或者項(xiàng)目經(jīng)理,你只需要解決10%最核心的問題,其它的大可以交給團(tuán)隊(duì)里精力充沛的年輕人去做。
再次,如果你覺得自己在編程方面并沒有太高的天分,再做下去也很難達(dá)到下一個(gè)高度,那么你可以轉(zhuǎn)行去做實(shí)施或者銷售。有開發(fā)背景的人做軟件實(shí)施的時(shí)候可以更清晰的看到問題所在,不用跟后面的開發(fā)團(tuán)隊(duì)扯皮,小的問題還可以幫用戶當(dāng)場解決,博得用戶的好感。做銷售也一樣,可以迅速的理解用戶的需求背后隱藏的東西,并在開發(fā)難度和用戶的預(yù)算之間找到平衡點(diǎn),省的簽下了單子回去再被開發(fā)人員罵,功能開發(fā)不出來回來再被客戶罵。
如果你覺得由于某些原因(比如太內(nèi)向),自己連實(shí)施和銷售也做不了,那或許你還可以去某個(gè)中小學(xué)謀個(gè)一官半職,畢竟,你跟那些學(xué)校的老師比起來,有真材實(shí)料的多了。
如果你連這個(gè)也做不了……我也不知道你還能做什么了,也許,網(wǎng)游就是你的精神棲息地。
本文來源:http://ilikes.blog.sohu.com/
返回?cái)?shù)據(jù)庫總結(jié)目錄
關(guān)系數(shù)據(jù)庫設(shè)計(jì)之時(shí)是要遵守一定的規(guī)則的。尤其是數(shù)據(jù)庫范式 現(xiàn)簡單介紹1NF(第一范式),2NF(第二范式),3NF(第三范式)和BCNF,另有第四范式和第五范式留到以后再介紹。 在你設(shè)計(jì)數(shù)據(jù)庫之時(shí),若能符合這幾個(gè)范式,你就是數(shù)據(jù)庫設(shè)計(jì)的高手。
第一范式(1NF):在關(guān)系模式R中的每一個(gè)具體關(guān)系r中,如果每個(gè)屬性值 都是不可再分的最小數(shù)據(jù)單位,則稱R是第一范式的關(guān)系。例:如職工號(hào),姓名,電話號(hào)碼組成一個(gè)表(一個(gè)人可能有一個(gè)辦公室電話 和一個(gè)家里電話號(hào)碼) 規(guī)范成為1NF有三種方法:
一是重復(fù)存儲(chǔ)職工號(hào)和姓名。這樣,關(guān)鍵字只能是電話號(hào)碼。
二是職工號(hào)為關(guān)鍵字,電話號(hào)碼分為單位電話和住宅電話兩個(gè)屬性
三是職工號(hào)為關(guān)鍵字,但強(qiáng)制每條記錄只能有一個(gè)電話號(hào)碼。
以上三個(gè)方法,第一種方法最不可取,按實(shí)際情況選取后兩種情況。
第二范式(2NF):如果關(guān)系模式R(U,F(xiàn))中的所有非主屬性都完全依賴于任意一個(gè)候選關(guān)鍵字,則稱關(guān)系R 是屬于第二范式的。
例:選課關(guān)系 SCI(SNO,CNO,GRADE,CREDIT)其中SNO為學(xué)號(hào), CNO為課程號(hào),GRADEGE 為成績,CREDIT 為學(xué)分。 由以上條件,關(guān)鍵字為組合關(guān)鍵字(SNO,CNO)
在應(yīng)用中使用以上關(guān)系模式有以下問題:
a.數(shù)據(jù)冗余,假設(shè)同一門課由40個(gè)學(xué)生選修,學(xué)分就 重復(fù)40次。
b.更新異常,若調(diào)整了某課程的學(xué)分,相應(yīng)的元組CREDIT值都要更新,有可能會(huì)出現(xiàn)同一門課學(xué)分不同。
c.插入異常,如計(jì)劃開新課,由于沒人選修,沒有學(xué)號(hào)關(guān)鍵字,只能等有人選修才能把課程和學(xué)分存入。
d.刪除異常,若學(xué)生已經(jīng)結(jié)業(yè),從當(dāng)前數(shù)據(jù)庫刪除選修記錄。某些門課程新生尚未選修,則此門課程及學(xué)分記錄無法保存。
原因:非關(guān)鍵字屬性CREDIT僅函數(shù)依賴于CNO,也就是CREDIT部分依賴組合關(guān)鍵字(SNO,CNO)而不是完全依賴。
解決方法:分成兩個(gè)關(guān)系模式 SC1(SNO,CNO,GRADE),C2(CNO,CREDIT)。新關(guān)系包括兩個(gè)關(guān)系模式,它們之間通過SC1中的外關(guān)鍵字CNO相聯(lián)系,需要時(shí)再進(jìn)行自然聯(lián)接,恢復(fù)了原來的關(guān)系
第三范式(3NF):如果關(guān)系模式R(U,F(xiàn))中的所有非主屬性對任何候選關(guān)鍵字都不存在傳遞信賴,則稱關(guān)系R是屬于第三范式的。
例:如S1(SNO,SNAME,DNO,DNAME,LOCATION) 各屬性分別代表學(xué)號(hào),
姓名,所在系,系名稱,系地址。
關(guān)鍵字SNO決定各個(gè)屬性。由于是單個(gè)關(guān)鍵字,沒有部分依賴的問題,肯定是2NF。但這關(guān)系肯定有大量的冗余,有關(guān)學(xué)生所在的幾個(gè)屬性DNO,DNAME,LOCATION將重復(fù)存儲(chǔ),插入,刪除和修改時(shí)也將產(chǎn)生類似以上例的情況。
原因:關(guān)系中存在傳遞依賴造成的。即SNO -> DNO。 而DNO -> SNO卻不存在,DNO -> LOCATION, 因此關(guān)鍵遼 SNO 對 LOCATION 函數(shù)決定是通過傳遞依賴 SNO -> LOCATION 實(shí)現(xiàn)的。也就是說,SNO不直接決定非主屬性LOCATION。
解決目地:每個(gè)關(guān)系模式中不能留有傳遞依賴。
解決方法:分為兩個(gè)關(guān)系 S(SNO,SNAME,DNO),D(DNO,DNAME,LOCATION)
注意:關(guān)系S中不能沒有外關(guān)鍵字DNO。否則兩個(gè)關(guān)系之間失去聯(lián)系。
BCNF:如果關(guān)系模式R(U,F(xiàn))的所有屬性(包括主屬性和非主屬性)都不傳遞依賴于R的任何候選關(guān)鍵字,那么稱關(guān)系R是屬于BCNF的?;蚴顷P(guān)系模式R,如果每個(gè)決定因素都包含關(guān)鍵字(而不是被關(guān)鍵字所包含),則RCNF的關(guān)系模式。
例:配件管理關(guān)系模式 WPE(WNO,PNO,ENO,QNT)分別表倉庫號(hào),配件號(hào),職工號(hào),數(shù)量。有以下條件
a.一個(gè)倉庫有多個(gè)職工。
b.一個(gè)職工僅在一個(gè)倉庫工作。
c.每個(gè)倉庫里一種型號(hào)的配件由專人負(fù)責(zé),但一個(gè)人可以管理幾種配件。
d.同一種型號(hào)的配件可以分放在幾個(gè)倉庫中。
分析:由以上得 PNO 不能確定QNT,由組合屬性(WNO,PNO)來決定,存在函數(shù)依賴(WNO,PNO) -> ENO。由于每個(gè)倉庫里的一種配件由專人負(fù)責(zé),而一個(gè)人可以管理幾種配件,所以有組合屬性(WNO,PNO)才能確定負(fù)責(zé)人,有(WNO,PNO)-> ENO。因?yàn)?一個(gè)職工僅在一個(gè)倉庫工作,有ENO -> WNO。由于每個(gè)倉庫里的一種配件由專人負(fù)責(zé),而一個(gè)職工僅在一個(gè)倉庫工作,有 (ENO,PNO)-> QNT。
找一下候選關(guān)鍵字,因?yàn)椋╓NO,PNO) -> QNT,(WNO,PNO)-> ENO ,因此 (WNO,PNO)可以決定整個(gè)元組,是一個(gè)候選關(guān)鍵字。根據(jù)ENO->WNO,(ENO,PNO)->QNT,故(ENO,PNO)也能決定整個(gè)元組,為另一個(gè)候選關(guān)鍵字。屬性ENO,WNO,PNO 均為主屬性,只有一個(gè)非主屬性QNT。它對任何一個(gè)候選關(guān)鍵字都是完全函數(shù)依賴的,并且是直接依賴,所以該關(guān)系模式是3NF。
分析一下主屬性。因?yàn)镋NO->WNO,主屬性ENO是WNO的決定因素,但是它本身不是關(guān)鍵字,只是組合關(guān)鍵字的一部分。這就造成主屬性WNO對另外一個(gè)候選關(guān)鍵字(ENO,PNO)的部 分依賴,因?yàn)椋‥NO,PNO)-> ENO但反過來不成立,而P->WNO,故(ENO,PNO)-> WNO 也是傳遞依賴。
雖然沒有非主屬性對候選關(guān)鍵遼的傳遞依賴,但存在主屬性對候選關(guān)鍵字的傳遞依賴,同樣也會(huì)帶來麻煩。如一個(gè)新職工分配到倉庫工作,但暫時(shí)處于實(shí)習(xí)階段,沒有獨(dú)立負(fù)責(zé)對某些配件的管理任務(wù)。由于缺少關(guān)鍵字的一部分PNO而無法插入到該關(guān)系中去。又如某個(gè)人改成不管配件了去負(fù)責(zé)安全,則在刪除配件的同時(shí)該職工也會(huì)被刪除。
解決辦法:分成管理EP(ENO,PNO,QNT),關(guān)鍵字是(ENO,PNO)工作EW(ENO,WNO)其關(guān)鍵字是ENO
缺點(diǎn):分解后函數(shù)依賴的保持性較差。如此例中,由于分解,函數(shù)依賴(WNO,PNO)-> ENO 丟失了, 因而對原來的語義有所破壞。沒有體現(xiàn)出每個(gè)倉庫里一種部件由專人負(fù)責(zé)。有可能出現(xiàn) 一部件由兩個(gè)人或兩個(gè)以上的人來同時(shí)管理。因此,分解之后的關(guān)系模式降低了部分完整性約束。
一個(gè)關(guān)系分解成多個(gè)關(guān)系,要使得分解有意義,起碼的要求是分解后不丟失原來的信息。這些信息不僅包括數(shù)據(jù)本身,而且包括由函數(shù)依賴所表示的數(shù)據(jù)之間的相互制約。進(jìn)行分解的目標(biāo)是達(dá)到更高一級(jí)的規(guī)范化程度,但是分解的同時(shí)必須考慮兩個(gè)問題:無損聯(lián)接性和保持函數(shù)依賴。有時(shí)往往不可能做到既有無損聯(lián)接性,又完全保持函數(shù)依賴。需要根據(jù)需要進(jìn)行權(quán)衡。
1NF直到BCNF的四種范式之間有如下關(guān)系:
BCNF包含了3NF包含2NF包含1NF
小結(jié):
目地:規(guī)范化目的是使結(jié)構(gòu)更合理,消除存儲(chǔ)異常,使數(shù)據(jù)冗余盡量小,便于插入、刪除和更新
原則:遵從概念單一化 "一事一地"原則,即一個(gè)關(guān)系模式描述一個(gè)實(shí)體或?qū)嶓w間的一種聯(lián)系。規(guī)范的實(shí)質(zhì)就是概念的單一化。
方法:將關(guān)系模式投影分解成兩個(gè)或兩個(gè)以上的關(guān)系模式。
要求:分解后的關(guān)系模式集合應(yīng)當(dāng)與原關(guān)系模式"等價(jià)",即經(jīng)過自然聯(lián)接可以恢復(fù)原關(guān)系而不丟失信息,并保持屬性間合理的聯(lián)系。
注意:一個(gè)關(guān)系模式結(jié)這分解可以得到不同關(guān)系模式集合,也就是說分解方法不是唯一的。最小冗余的要求必須以分解后的數(shù)據(jù)庫能夠表達(dá)原來數(shù)據(jù)庫所有信息為前提來實(shí)現(xiàn)。其根本目標(biāo)是節(jié)省存儲(chǔ)空間,避免數(shù)據(jù)不一致性,提高對關(guān)系的操作效率,同時(shí)滿足應(yīng)用需求。實(shí)際上,并不一定要求全部模式都達(dá)到BCNF不可。有時(shí)故意保留部分冗余可能更方便數(shù)據(jù)查詢。尤其對于那些更新頻度不高,查詢頻度極高的數(shù)據(jù)庫系統(tǒng)更是如此。
在關(guān)系數(shù)據(jù)庫中,除了函數(shù)依賴之外還有多值依賴,聯(lián)接依賴的問題,從而提出了第四范式,第五范式等更高一級(jí)的規(guī)范化要求。在此,以后再談。
各位朋友,你看過后有何感想,其實(shí),任何一本數(shù)據(jù)庫基礎(chǔ)理論的書都會(huì)講這些東西,考慮到很多網(wǎng)友是半途出家,來做數(shù)據(jù)庫。特找一本書大抄特抄一把,各位有什么問題,也別問我了,自已去找一本關(guān)系數(shù)據(jù)庫理論的書去看吧,說不定,對各位大有幫助。說是說以上是基礎(chǔ)理論的東西,請大家想想,你在做數(shù)據(jù)庫設(shè)計(jì)的時(shí)候有沒有考慮過遵過以上幾個(gè)范式呢,有沒有在數(shù)據(jù)庫設(shè)計(jì)做得不好之時(shí),想一想,對比以上所講,到底是違反了第幾個(gè)范式呢?
我見過的數(shù)據(jù)庫設(shè)計(jì),很少有人做到很符合以上幾個(gè)范式的,一般說來,第一范式大家都可以遵守,完全遵守第二第三范式的人很少了,遵守的人一定就是設(shè)計(jì)數(shù)據(jù)庫的高手了,BCNF的范式出現(xiàn)機(jī)會(huì)較少,而且會(huì)破壞完整性,你可以在做設(shè)計(jì)之時(shí)不考慮它,當(dāng)然在ORACLE中可通過觸發(fā)器解決其缺點(diǎn)。以后我們共同做設(shè)計(jì)之時(shí),也希望大家遵守以上幾個(gè)范式。