資料庫設計必須滿足到第三範式嗎?
老師說必須滿足到第三範式,但是設計這麼活的問題,給這麼死的答案真的對嗎-_-||
第三範式定義
每個非關鍵字列都獨立於其他非關鍵字列,並依賴於關鍵字,第三範式指資料庫中不能存在傳遞函數依賴關係
基本上一個設計良好的資料庫表,應該就是如此的!
凡是不是這樣的表,在使用的時候會特別的彆扭。【以百度百科上的例子做仔細分析】
例:如S1(SNO,SNAME,DNO,DNAME,LOCATION) 各屬性分別代表學號,姓名,所在系,系名稱,系地址。
關鍵字SNO決定各個屬性。由於是單個關鍵字,沒有部分依賴的問題,肯定是2NF。但這關係肯定有大量的冗餘,有關學生所在的幾個屬性DNO,DNAME,LOCATION將重複存儲,插入,刪除和修改時也將產生類似以上例的情況。
實際上這段話說的很對。
如果這樣的表,需要修改【系】相關的信息時候,那個SQL語句,寫起來多彆扭啊。
非常可能會存在這樣的
update s1 set dname = "新名字" where dname = "舊名字"
理想的更新語句應該是這樣的
update depts set dname = "新名字" where d_id = 1
根據系編號來修改系名,而不是根據名字來修改名字。
怎麼做到第三範式? 不需要考慮第三範式的定義。
按對象劃分就好了,學生的屬性歸學生,系的屬性歸系,教師的屬性歸教師,學校的屬性歸學校。設計好了,基本上就是逼近第三範式了。佛曰:欲先入世,必先出世;欲先出世,必先入世如果不想遵循範式,必須先搞明白範式;如果盲從範式,肯定沒搞明白範式
應當先按照範式要求來設計,不然怎麼保證資料庫的正確性呢?
在保證正確的基礎上,不可避免的要針對業務作優化,比如冗餘,比如用程序作約束...
但每一個不符合範式的設計都要有原因。
舉個例子:在沒有孩子的時候討論孩子的眼睛離書太近了。
目前關係資料庫有六種範式:
第一範式(1NF)屬性不可分。是指在關係模型中,對域添加的一個規範要求,所有的域都應該是原子性的,即資料庫表的每一列都是不可分割的原子數據項。
第二範式(2NF)在1NF的基礎上,非碼屬性必須完全依賴於候選碼(在1NF基礎上消除非主屬性對主碼的部分函數依賴)
第三範式(3NF)在1NF基礎上,任何非主屬性不依賴於其它非主屬性(在2NF基礎上消除傳遞依賴)
巴斯-科德範式(BCNF)Boyce-Codd Normal Form(巴斯-科德範式)在1NF基礎上,任何非主屬性不能對主鍵子集依賴(在3NF基礎上消除對主碼子集的依賴)
第四範式(4NF),要求把同一表內的多對多關係刪除。
第五範式(5NF),又稱完美範式,從最終結構重新建立原始結構。
在設計資料庫時,儘可能做到前四個即可。但範式並非硬性要求,而是設計時儘可能遵守的大原則。對於這些範式也沒必要刻意去記,關係型資料庫說到底只是二維的行列組合,參與的資料庫設計多了,設計理念自然成型,會不自覺的去向這些範式中靠攏,設計過程中可以以此為依據校驗自己的設計是否合理,及時修正不當設計。
特殊地方,為了操作方便,在不影響核心業務的情況下,允許小範圍的不遵守範式。平時的多圖片上傳功能,可能只設計一個欄位存儲圖片名稱,這樣欄位值中就會包含多個圖片的名稱,裡面用|或其它符號分隔,這樣屬性值就可分了,也就違反了第一範式——屬性不可分;還有地區表中的,地區編碼欄位也隱含有等級信息;再就是菜單相關表,裡面分等級互相引用等等;嚴格來講這些都是不符合規範的。
在小範圍內,不影響到核心業務流程,為了設計開發的方便,允許一些特殊的設計出現。規範是用來約束設計的,約束的目的是為了最終整體設計的合理性、為了最終項目的穩定性,如果這種全局的規範約束在局部影響到開發實現,可以適當調整,但前提是設計者要有足夠的經驗和能力駕馭住這種不當調整。
以我的理解來說:三範式是理論上的規範,它代表著最合理(或者應該說在適應性最廣泛的前提下抽象出來的最合理)的數據結構,但不一定是最合理的數據模型。 這是因為現實中人們的需求本身不一定是合理,而且是各不相同的,所以映射到資料庫中時也就不會有一個萬能的範式。不論是網站還是app中,都可能出現前後台功能差異等各種情況。 再加上目前伺服器性能和寬頻等資源以及成本等綜合考慮,不符合二、三範式的情況是允許的。但是就像樓上回答的,你首先需要三範式和bc範式應用的意義,在這個基礎上再去根據實際的情況來打破範式。才能設計出最好用的資料庫模型。 最好和最優是針對應用場景來說的,任何數據結構和設計規範都不能脫離實際應用而存在。也就是說適合的才是最好的。
以我遇到的項目為例:假如要做歷史存檔、數據結轉之類的功能上要求冗餘的需求,沒必要且不能三範式,直接存需要的值。類似於快照或者備份
推薦閱讀:
※SQL新手請教一下設計表的問題?
※釘釘數據存儲使用阿里雲的表格存儲,如何設計資料庫?
※mysql分表策略?
※如何配合使用NoSQL和SQL,特別是原子性問題存在的時候?
※從oracle到mysql引發的技術思考,數據如何拆分到多個資料庫?