關系數據庫設計之時是要遵守一定的規則的。尤其是數據庫設計范式 現簡單介紹1NF(第一范式),2NF(第二范式),3NF(第三范式)和BCNF,另有第四范式和第五范式留到以后再介紹。
在你設計數據庫之時,若能符合這幾個范式,你就是數據庫設計的高手。
第一范式(1NF)
在關系模式R中的每一個具體關系r中,如果每個屬性值 都是不可再分的最小數據單位,則稱R是第一范式的關系。
例:如職工號,姓名,電話號碼組成一個表(一個人可能有一個辦公室電話 和一個家里電話號碼) 規范成為1NF有三種方法:一是重復存儲職工號和姓名。這樣,關鍵字只能是電話號碼。二是職工號為關鍵字,電話號碼分為單位電話和住宅電話兩個屬性三是職工號為關鍵字,但強制每條記錄只能有一個電話號碼。以上三個方法,第一種方法最不可取,按實際情況選取后兩種情況。
第二范式(2NF)
如果關系模式R(U,F)中的所有非主屬性都完全依賴于任意一個候選關鍵字,則稱關系R 是屬于第二范式的。例:選課關系 SCI(SNO,CNO,GRADE,CREDIT)其中SNO為學號, CNO為課程號,GRADEGE 為成績,CREDIT 為學分。由以上條件,關鍵字為組合關鍵字(SNO,CNO) 在應用中使用以上關系模式有以下問題:
原因:非關鍵字屬性CREDIT僅函數依賴于CNO,也就是CREDIT部分依賴組合關鍵字(SNO,CNO)而不是完全依賴。解決方法:分成兩個關系模式 SC1(SNO,CNO,GRADE),C2(CNO,CREDIT)。新關系包括兩個關系模式,它們之間通過SC1中的外關鍵字CNO相聯系,需要時再進行自然聯接,恢復了原來的關系。
第三范式(3NF)
如果關系模式R(U,F)中的所有非主屬性對任何候選關鍵字都不存在傳遞信賴,則稱關系R是屬于第三范式的。
例:如S1(SNO,SNAME,DNO,DNAME,) 各屬性分別代表學號, 姓名,所在系,系名稱,系地址。關鍵字SNO決定各個屬性。由于是單個關鍵字,沒有部分依賴的問題,肯定是2NF。但這關系肯定有大量的冗余,有關學生所在的幾個屬性DNO,DNAME,將重復存儲,插入,刪除和修改時也將產生類似以上例的情況。
原因:關系中存在傳遞依賴造成的。即SNO -> DNO(而DNO -> SNO卻不存在),DNO -> , 因此關鍵字SNO 對 函數決定是通過傳遞依賴 SNO -> 實現的。也就是說,SNO不直接決定非主屬性。
解決目的:每個關系模式中不能留有傳遞依賴。解決方法:分為兩個關系 S(SNO,SNAME,DNO),D(DNO,DNAME,)
注意:關系S中不能沒有外關鍵字DNO。否則兩個關系之間失去聯系。
BCNF:如果關系模式R(U,F)的所有屬性(包括主屬性和非主屬性)都不傳遞依賴于R的任何候選關鍵字,那么稱關系R是屬于BCNF的。或是關系模式R,如果每個決定因素都包含關鍵字(而不是被關鍵字所包含),則BCNF的關系模式。例:配件管理關系模式 WPE(WNO,PNO,ENO,QNT)分別表倉庫號,配件號,職工號,數量。有以下條件 a.一個倉庫有多個職工。b.一個職工僅在一個倉庫工作。c.每個倉庫里一種型號的配件由專人負責,但一個人可以管理幾種配件。d.同一種型號的配件可以分放在幾個倉庫中。分析:
因為一個職工僅在一個倉庫工作,有ENO -> WNO。由于每個倉庫里的一種配件由專人負責,而一個職工僅在一個倉庫工作,有 (WNO,PNO)-> QNT。找一下候選關鍵字,因為(WNO,PNO) -> QNT,(WNO,PNO)-> ENO ,因此 (WNO,PNO)可以決定整個元組,是一個候選關鍵字。根據ENO->WNO,(ENO,PNO)->QNT,故(ENO,PNO)也能決定整個元組,為另一個候選關鍵字。屬性ENO,WNO,PNO 均為主屬性,只有一個非主屬性QNT。它對任何一個候選關鍵字都是完全函數依賴的,并且是直接依賴,所以該關系模式是3NF。分析一下主屬性。因為ENO->WNO,主屬性ENO是WNO的決定因素,但是它本身不是關鍵字,只是組合關鍵字的一部分。這就造成主屬性WNO對另外一個候選關鍵字(ENO,PNO)的部 分依賴,因為(ENO,PNO)-> ENO但反過來不成立,而PNO->WNO,故(ENO,PNO)-> WNO 是傳遞依賴。雖然沒有非主屬性對候選關鍵字的傳遞依賴,但存在主屬性對候選關鍵字的傳遞依賴,同樣也會帶來麻煩。如一個新職工分配到倉庫工作,但暫時處于實習階段,沒有獨立負責對某些配件的管理任務。由于缺少關鍵字的一部分PNO而無法插入到該關系中去。又如某個人改成不管配件了去負責安全,則在刪除配件的同時該職工也會被刪除。
如此例中,由于分解,函數依賴(WNO,PNO)-> ENO 丟失了, 因而對原來的語義有所破壞。沒有體現出每個倉庫里一種部件由專人負責。有可能出現 一部件由兩個人或兩個以上的人來同時管理。因此,分解之后的關系模式降低了部分完整性約束。一個關系分解成多個關系,要使得分解有意義,起碼的要求是分解后不丟失原來的信息。這些信息不僅包括數據本身,而且包括由函數依賴所表示的數據之間的相互制約。進行分解的目標是達到更高一級的規范化程度,但是分解的同時必須考慮兩個問題:無損聯接性和保持函數依賴。有時往往不可能做到既有無損聯接性,又完全保持函數依賴。需要根據需要進行權衡。
1NF直到BCNF的四種范式之間有如下關系:BCNF包含了3NF包含2NF包含1NF
小結:
目的:規范化目的是使結構更合理,消除存儲異常,使數據冗余盡量小,便于插入、刪除和更新
原則:遵從概念單一化 "一事一地"原則,即一個關系模式描述一個實體或實體間的一種聯系。規范的實質就是概念的單一化。
方法:將關系模式投影分解成兩個或兩個以上的關系模式。要求:分解后的關系模式集合應當與原關系模式"等價",即經過自然聯接可以恢復原關系而不丟失信息,并保持屬性間合理的聯系。
注意:一個關系模式結這分解可以得到不同關系模式集合,也就是說分解方法不是唯一的。最小冗余的要求必須以分解后的數據庫能夠表達原來數據庫所有信息為前提來實現。其根本目標是節省存儲空間,避免數據不一致性,提高對關系的操作效率,同時滿足應用需求。實際上,并不一定要求全部模式都達到BCNF不可。有時故意保留部分冗余可能更方便數據查詢。尤其對于那些更新頻度不高,查詢頻度極高的數據庫系統更是如此。在關系數據庫中,除了函數依賴之外還有多值依賴,聯接依賴的問題,從而提出了第四范式,第五范式等更高一級的規范化要求。在此,以后再談。
各位朋友,你看過后有何感想,其實,任何一本數據庫基礎理論的書都會講這些東西,考慮到很多網友是半途出家,來做數據庫。特找一本書大抄特抄一把,各位有什么問題,也別問我了,自已去找一本關系數據庫理論的書去看吧,說不定,對各位大有幫助。說是說以上是基礎理論的東西,請大家想想,你在做數據庫設計的時候有沒有考慮過遵過以上幾個范式呢,有沒有在數據庫設計做得不好之時,想一想,對比以上所講,到底是違反了第幾個范式呢?我見過的數據庫設計,很少有人做到很符合以上幾個范式的,一般說來,第一范式大家都可以遵守,完全遵守第二第三范式的人很少了,遵守的人一定就是設計數據庫的高手了,BCNF的范式出現機會較少,而且會破壞完整性,你可以在做設計之時不考慮它,當然在ORACLE中可通過觸發器解決其缺點。以后我們共同做設計之時,也希望大家遵守以上幾個范式。
詳解身份證驗證規則
今天來說說身份證驗證規則到底是怎么驗證的,原理是什么,希望看完本篇你能正確的去理解身份證驗證背后的規則。
身份證號碼的編碼規則
身份證號碼共18位,由17位本體碼和1位校驗碼組成。
身份證最后一位是根據前面十七位數字碼,按照ISO 7064:1983.MOD 11-2校驗碼計算出來的檢驗碼。作為尾號的校驗碼,是由號碼編制單位按統一的公式計算出來的,如果某人的尾號是0-9,都不會出現X,但如果尾號是10,那么就得用X來代替,因為如果用10做尾號,那么此人的身份證就變成了19位,而19位的號碼違反了國家標準,并且我國的計算機應用系統也不承認19位的身份證號碼。Ⅹ是羅馬數字的10,用X來代替10,可以保證公民的身份證符合國家標準。
前6位是地址碼,表示登記戶口時所在地的行政區劃代碼,依照《中華人民共和國行政區劃代碼》國家標準(GB/T2260)的規定執行;7到14位是出生年月日,采用格式;15到17位是順序碼,表示在同一地址碼所標識的區域范圍內,對同年、同月、同日出生的人編訂的順序號,順序碼的奇數分配給男性,偶數分配給女性,即第17位奇數表示男性, 偶數表示女性;
第18位是校驗碼,采用ISO 7064:1983, MOD 11-2校驗字符系統,計算規則下一章節說明。
一代身份證與二代身份證的區別在于:
一代身份證是15位,二代身份證是18位;一代身份證出生年月日采用YYMMDD格式,二代身份證出生年月日采用格式;一代身份證無校驗碼,二代身份證有校驗碼。校驗碼計算規則
身份證號碼中各個位置上的號碼字符值應滿足下列公式的校驗:
下面通過兩種方法用某個真實的男性身份證號(5 3 3 2 2 3 1 9 6 3 0 1 0 5 0 9 1 7)來進行通俗易懂的說明身份證驗證規則。
方法一(余數對應法)
將前面的身份證號碼17位數分別乘以不同的系數。從第一位到第十七位的系數分別為:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2;將這17位數字和系數相乘的結果相加;用加出來的和除以11,看余數是多少;余數只可能有0 1 2 3 4 5 6 7 8 9 10這11個數字。其分別對應的最后一位身份證的號碼為1 0 X 9 8 7 6 5 4 3 2;
方法二(十八位加權余一法)
按照18位來計算,第一位數的權重是07,第二位是09(見下表)序號從右向左,只要最后的加權和除以11,余數只要是1,那么身份證號碼就是正確的。
注意:如果身份證號碼第18位是X,那么就按10計算。
其中5 X 7=35,3 X 9=27,3 X 10=30,其余以此類推,
加權求和=35+27+30…..2+7=265;265 % 11其余數是1,所以這個號碼是正確的。
用JS實現二代身份證的驗證
理解了原理和校驗規則開始下手敲起來:
<script type="text/javascript">
/**
* 以下身份證驗證適用于18位的二代身份證號碼,身份證通常是由17位本體碼和1位校驗碼組成。
**/
function validateIdCard(idCard) {
//15位和18位身份證號碼的正則表達式
var regIdCard = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
//如果通過該驗證,說明身份證格式正確,但準確性還需計算
if (regIdCard.test(idCard)) {
if (idCard.length == 18) {
var idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); //將前17位加權因子保存在數組里
var idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); //這是除以11后,可能產生的11位余數、驗證碼,也保存成數組,10代表X
var idCardWiSum = 0; //用來保存前17位各自乖以加權因子后的總和
for (var i = 0; i < 17; i++) {
idCardWiSum += idCard.substring(i, i + 1) * idCardWi[i];
}
var idCardMod = idCardWiSum % 11;//計算出校驗碼所在數組的位置
var idCardLast = idCard.substring(17);//得到最后一位身份證號碼
//如果等于2,則說明校驗碼是10,身份證號碼最后一位應該是X
if (idCardMod == 2) {

if (idCardLast == "X" || idCardLast == "x") {
return "身份證號碼驗證通過!";
} else {
return "您輸入的身份證號碼有誤!";
}
} else {
//用計算出的驗證碼與最后一位身份證號碼匹配,如果一致,說明通過,否則是無效的身份證號碼
if (idCardLast == idCardY[idCardMod]) {
return "身份證號碼驗證通過!";
} else {
return "您輸入的身份證號碼有誤!";
}
}
}
} else {
return "您輸入的身份證格式不正確!";
}
}
var inputs =validateIdCard(prompt());
var ids = document.getElementById("ids").innerHTML=inputs;
</script>
參考資料
*請認真填寫需求信息,我們會在24小時內與您取得聯系。