日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

为什么我不喜欢数据库三范式

發布時間:2023/12/4 数据库 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么我不喜欢数据库三范式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

插曲

最近,一個遠房親戚的小表弟準備選修專業
找到我問:

"哥,現在學數據庫有沒有前途阿?""當然有啊,前途大大的呢""那我現在開始學數據庫,需要先從什么開始呢?""學課程的話,先了解下數據庫三范式,SQL這些吧""SQL我大概知道,數據庫三范式是什么?""阿...三范式就是表的主鍵...唯一性那些東西吧,...嗯,應該就是那些""什么是主鍵?""額.....表弟你不要再問了啦,好好去百度一下行不。""噢...."

掛完電話,我舒了口氣,由于差點暴露自己已經不記得三范式了這個不爭的事實,我悄悄打開了谷歌....

數據庫的這個三范式的概念,相信大多數人都不會陌生,從懵懵懂懂的大學時代就已經普及到教材了(沒記錯的話應該在數據庫系統概論這本教材里)。
還記得那會剛開始找實習的時候,由于自己本事太小,連簡歷都不知道怎么寫好,尤其是擅長技術的部分更是一片空白。
于是乎會找來隔壁幾個學霸的簡歷來做參考,那會兒大家的簡歷上都會赫赫寫著:

熟練掌握數據庫三范式,精通數據庫系統開發語言。

又或者是:
熟悉ER圖制作工具,能實現滿足三范式的數據庫設計

一開始覺得數據庫三范式確實是個好東西,以至于面試的時候技術官沒有提問到三范式的細節,自己感到了驚訝和茫然。
隨著工作經驗逐漸見長,數據庫范式理論在腦海里的強印象漸漸消除。我在想,要么是記憶的衰退,要么就是有些原則已經形成了本能的經驗了。

那么,什么是數據庫的范式?

三范式的定義

這里,不想花太多的篇幅去討論理論性的東西,這些信息一抓一大把。我們就通過一些簡單的例子來體會一下。

1. 第一范式

假設有一張用戶信息表,上面除了用戶編號、姓名之外,還會記錄地址信息:

0001張三廣東省,深圳市
0002李四海南省,海口市

在這里面,地址信息一欄就是不符合第一范式(1NF)的:
第一范式(1NF):數據庫表的每一列都是不可分割的原子項

因此,應該拆分為:

0001張三廣東省深圳市
0002李四海南省海口市

2. 第二范式

以一個訂單表為例,通常在淘寶上下單時會產生包含多個商品的訂單,如下:

o1g1洗衣液23
o1g2吹風機125
o1g3蠶豆5
o2g9被子302
o2g8枕頭69

這里同樣違反了第二范式的定義:
第二范式(2NF):每個表必須有且僅有一個數據元素為主鍵(Primary key),其他屬性需完全依賴于主鍵

第二范式需建立在滿足第一范式的基礎之上

第二范式首先要求的是存在一個唯一的主鍵,在上面的表中,就必須將 訂單號、商品號 作為一個聯合的主鍵才能滿足要求
那么對于第二點要求呢?其他屬性是否依賴于這個主鍵?
在訂單的場景中,我們可以認為這算是合理的,因為商品的價格甚至名稱都可能會發生變化,而在每個訂單中所看到的這些信息都應該是不變的,
誰也不希望看到自己已經支付的訂單中的商品信息突然大降價.. 當然更重要的還是保持訂單總價與商品單價記錄的一致性。
因此這里的記錄可以認為是商品信息在創建訂單時的一個快照。

但是,對于下面的這一場景可能就不合適了:

o1g1洗衣液23家居
o1g2吹風機125電器
o1g3蠶豆5食品
o2g9被子302家居
o2g8枕頭69家居

商品所屬的類別一般是固定的,也就是商品的類別屬性僅僅與商品編號相關,即僅僅是依賴于主鍵的一部分。
這就違反了第二范式中"其他屬性必須完全依賴于主鍵"的規則,因此需要將該屬性分離到商品信息表中。

3. 第三范式

讓我們回到一開始的用戶表,如果在用戶信息表中,同時補充一些城市的信息:

0001張三深圳市科技、創新1300W
0002李四海口市旅游、觀光230W

這樣便違反了第三范式的定義:

第三范式(3NF):數據表中的每一列都和主鍵直接相關,而不能間接相關

同樣,第三范式也需要建立在第二范式的基礎之上

很明顯,這里的城市人口、特色等屬性都僅僅依賴于用戶所在的城市,而不是用戶,只能算間接的關系。
因此最好的做法是將城市相關的屬性分離到一個城市信息表中。

為什么需要范式

數據庫范式為數據庫的設計、開發提供了一個可參考的典范,在許多教學材料中也是作為關鍵的課程內容。
那么范式的提出是為了解決什么問題?

  • 第一范式,要求將列盡可能最小的分割,希望消除某個列存儲多個值的冗余的行為
    比如用戶表中的地址信息,拆分為省、市這種明確的字段,可以按獨立的字段檢索、查詢

  • 第二范式,要求唯一的主鍵,且不存在對主鍵的部分依賴,希望消除表中存在冗余(多余)的列
    比如訂單表中的商品分類、詳情信息,只需要由商品信息表存儲一份即可。

  • 第三范式,要求沒有間接依賴于主鍵的列,即仍然是希望消除表中冗余的列
    比如用戶表中不需要存儲額外的 其所在城市的人口、城市特點等信息。

很明顯,這些范式大都是為了消除冗余而提出的,即盡可能的減少存儲成本。

PS:你懂得三范式,可以幫老板省錢,難怪簡歷上要寫上..

除了本文中提到的三范式之外,實質上還有BCNF范式、第四、第五范式。

借助三范式的理念,你可以設計出很精煉的數據庫表結構。然而現有的項目應用并不會完全遵循范式的理念,原因在于:

  • 性能原因,沒有任何冗余的表設計會產生更多的查詢行為,這意味著會產生更多次的數據庫IO操作。在一些實時交互的系統中,可能會慢得讓人難以忍受。
    當然,你可以使用數據庫的 連接(join) 操作,而事實上數據庫提供 join 也就是為了來緩解這種問題。但一旦用到了分庫分表方案的面前,這個問題就會非常的棘手。

  • 成本結構的變化,數據庫范式是在20世紀提出的,當時的磁盤存儲成本還很高。隨著科技發展,數據存儲的成本已經大幅度縮減,對于采用范式設計(規避冗余)帶來的成本縮減收益已經不那么明顯。

  • 反范式設計

    既然范式是為了消除冗余,那么反范式就是通過增加冗余、聚合的手段來提升性能。比如,為了提升查詢的性能,在CMS的文章表中同時冗余作者的信息。
    當然,除了冗余(存儲多份拷貝) 之外,還有另外的理念,即數據的聚合,或者叫嵌套。這種做法相當于是將多個字段(列)合并存儲到數據庫表的一個列中。

    比如一條訂單數據就可以同時包含許多信息:

    這種靈活的結構幾乎是 NoSQL的專利,比如MongoDB文檔數據庫就可以直接以內嵌數組、對象的形式來實現聚合式存儲,這無疑帶來了極大的靈活性。
    而 MySQL 在5.2.7版本開始支持JSON結構化列,也進入了聚合式存儲的隊伍,與其對標的PostGreSQL 則是9.4版本就已經支持。

    反范式的設計在互聯網項目、開源產品中也非常之常見,比如大名鼎鼎的Discuz 的數據表設計中就存在許多的冗余列、聚合字段。
    一方面,除了能獲得性能的提升之外,數據壓縮、高度靈活擴展(非結構化) 也是反范式設計能獲得青睞的理由。

    當然,這里并非一律反對數據庫范式,理解范式仍然是做好數據庫設計的一門基礎,比如選擇合適的主鍵、清晰的劃分每一列屬性等等。
    在項目中仍然需要根據自身的業務特點在范式和反范式中找到平衡點(通常是兩者的結合)。類似于架構設計中空間換時間的一些做法,這其中涉及到的各種取舍都是需要經過權衡的。

    也可以說這是一門藝術,因為沒有標準答案...


    總結

    以上是生活随笔為你收集整理的为什么我不喜欢数据库三范式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。