如何深入理解關係型資料庫的三大範式

来源:https://www.cnblogs.com/ziph/archive/2020/06/13/13121500.html
-Advertisement-
Play Games

該文章,GitHub已收錄,歡迎老闆們前來Star! GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual 資料庫範式 一、什麼是資料庫範式 設計關係資料庫時,遵從不同的規範要求,設計出合理的關係型資料庫,這些不同的規範要求被稱為不同的 ...


該文章,GitHub已收錄,歡迎老闆們前來Star!

GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual

資料庫範式


一、什麼是資料庫範式

設計關係資料庫時,遵從不同的規範要求,設計出合理的關係型資料庫,這些不同的規範要求被稱為不同的範式,各種範式呈遞次規範,越高的範式資料庫冗餘越小。

範式來自英文Normal form,簡稱NF。要想設計—個好的關係,必須使關係滿足一定的約束條件,此約束已經形成了規範,分成幾個等級,一級比一級要求得嚴格。滿足這些規範的資料庫是簡潔的、結構明晰的,同時,不會發生插入(insert)、刪除(delete)和更新(update)操作異常。

二、資料庫範式分類

目前關係資料庫有六種範式:第一範式(1NF)、第二範式(2NF)、第三範式(3NF)、巴斯-科德範式(BCNF)、第四範式(4NF)和第五範式(5NF,又稱完美範式)。滿足最低要求的範式是第一範式(1NF)。在第一範式的基礎上進一步滿足更多規範要求的稱為第二範式(2NF),其餘範式以次類推。一般來說,資料庫只需滿足第三範式(3NF)就行了。

三、資料庫三大範式剖析

3.1 第一範式(1NF)

第一範式強調每一列都是不可分割的原子數據項。

說到原子這個詞,肯定有小伙伴就先到了原子性問題,其實這麼想也是沒有錯的。那就讓我帶你們去剖析一下第一範式。

首先,我用Excel表格模擬資料庫中的表,併在表中填入了一些數據。如下:

image-20200613164428707
image-20200613164428707

當你看到這些數據的時候,是否有些數據讓你感到不適?我的答案,是的。當我看到系名/系主任這一列數據的時候感覺這並不合符我們資料庫的設計理念,因為它完全可以拆分為兩個列的。其實每一個人的思想中的已經有了這個範式要求的概念,只是你並不知道這個概念叫做第一範式。

如果有的小伙伴說,這些數據都讓感到不適,那我就在這裡誇上你一句,你很聰明。但是請你跟緊我的思路,我會一步一步的將數據落實到範式中!

表1顯然不遵循第一範式,那我們就把它修改一下,讓其遵循第一範式的要求。

image-20200613164455095
image-20200613164455095

系名/系主任的列拆分成了兩個列系名系主任後,很明顯改數據已經遵循的第一範式的要求。再來看看這張表2,聰明的你是不是第一眼又發現了問題呢?

存在的問題:

  • 存在非常嚴重的數據冗餘,姓名、系名、系主任
  • 添加數據問題:當在數據表中添加一個新系和系主任時,比如:在數據表中添加高主任管理化學系。你會發現添加之後,在一個數據表中就會多出來了高主任和化學系,而這兩個數據並沒有對應哪個學生,顯然這時不合法的數據。
  • 刪除數據問題:如果Jack同學畢業多年了,我們數據表中沒有必要在留Jack相關的數據了,就會想到把Jack相關的刪除掉。當你在表2的表結構中刪除了Jack相關數據,你會發現整個劉主任和管理系以及會計和酒店管理都消失了,難道數據表中沒有這些數據就證明這個學校沒有它們嗎?顯然這更加離譜了!

瞭解了只遵循第一範式帶來的麻煩,我們就需要去看一下第二範式是怎麼定義的,是否能解決第一範式留下來的問題!

3.2 第二範式(2NF)

第二範式在1NF的基礎上,非屬性碼的屬性必須完全依賴於主碼。(在1NF基礎上消除非屬性碼的屬性對主碼的部分函數依賴)

看到第二範式的概念,現在你應該是一個不懂的狀態。那讓我帶你瞭解幾個概念吧,這樣你就會懂了!

函數依賴(完全、部分、傳遞)

函數依賴: A - > B,如果通過A屬性(或屬性組)的值可以確定唯一B屬性的值,則可以成為B依賴於A(- >符號是確定關係)。例如:可以通過學號來確定姓名,可以通過學號和課程來確定該課程的分數等等

  • 完全函數依賴: A - > B,如果A是一個屬性組,則B屬性的確定需要依賴A屬性組中的所有屬性值。例如:分數的確定需要依賴於學號和課程,而學號和課程可以稱為一個屬性組。如果有學號沒有課程,我們只知道是誰的分數,而不知道是那一學科的分數。如果有課程沒有學號,那我們只知道是哪一個學科的分數,而不知道是誰的分數。所以該屬性組的兩個值是必不可少的。這就是完全函數依賴。
  • 部分函數依賴: A - > B,如果A是一個屬性組,則B屬性的確定需要依賴A屬性組中的部分屬性值。例如:如果一個屬性組中有兩個屬性值,它們分別是學號和課程名稱。那姓名的確定只依賴這個屬性組中的學號,於課程名稱無關。簡單來說,依賴於屬性組的中部分成員即可成為部分函數依賴。
  • 傳遞函數依賴: A - > B - > C,傳遞函數依賴就是一個依賴的傳遞關係。通過確定A來確定B,確定了B之後,也就可以確定C,三者的依賴關係就是C依賴於B,B依賴於A。例如:我們可以通過學號來確定這位學生所在的系部,再通過系部來確定系主任是誰。而這個三者的依賴關係就是一種傳遞函數依賴。
候選碼、主屬性碼與非屬性碼
  • 碼: 如果在一張表中,一個屬性或屬性組,被其他所有屬性所完全函數依賴 ,則稱這個屬性(或屬性組)為該表的候選碼,簡稱碼。然而碼又分為主屬性碼和非屬性碼。例如:分數的確定沒有學號和課程是不行的,所以分數完全函數依賴於課程和學號。
  • 主屬性碼: 主屬性碼也叫主碼,即在所有候選碼挑選一個做主碼,這裡相當於是主鍵。例如:分數完全函數依賴於課程和學號。該碼屬性組中的值就有課程、學號和分數,所以我們要在三個候選碼中,挑選一個做主碼,那就可以挑選學號。
  • 非屬性碼: 除主碼屬性組以外的屬性,叫做非屬性碼。例如:在分數完全函數依賴於課程和學號時,其中學號已經讓我們選為主碼。那麼我們就可以確定,除了學號以外的屬性值,其他的屬性值都是非屬性碼。也就是說在這個完全函數依賴關係中,課程和分數是非屬性碼。

當我們瞭解這些概念後,回過頭來再看2NF的概念:在1NF的基礎上,非屬性碼的屬性必須完全依賴於主碼(在1NF基礎上消除非屬性碼的屬性對主碼的部分函數依賴)

我們還使用分數完全函數依賴於學號和課程這個函數依賴關係。此關係中非屬性碼為:課程和分數,主碼為學號。梳理清楚關係後,遵循在1NF基礎上,非屬性碼的屬性必須完全依賴於主碼的第二範式。就需要繼續修改表結構了。遵循1NF和2NF的表結構如下:

image-20200613170300513
image-20200613170300513
image-20200613170326468
image-20200613170326468

正如你所看到的,我們把表2根據1NF和2NF拆分成了表3和表4。這時候你再看表3,表3中的分數就完全函數依賴於表3中的學號和課程。表4中也挑選學號做主碼。雖然解決了數據冗餘問題,但是僅僅這樣還是不夠的,上述問題中其他的兩個問題並沒有得到解決!

存在的問題:

  • 數據刪除問題
  • 數據添加問題

註意: 在第二範式中存在的這兩個問題,就是在第一範式中存在問題的其中兩個並沒有得到解決。

既然第一範式和第二範式都沒有解決這兩個問題,那第三範式幫你解決!

3.3 第三範式(3NF)

第三範式在2NF基礎上,消除傳遞依賴。

說到傳遞依賴,那我們的數據表中還有哪些傳遞依賴呢?這時候你會發現表4中含有傳遞依賴的。表4中的傳遞依賴關係為:姓名 - > 系名 - > 系主任。該傳遞依賴關係為系主任傳遞依賴於姓名。再根據此傳遞依賴關係分析我們添加和刪除問題就漏洞百出了。消除傳遞依賴的辦法還是將表4進行拆分。拆分後的表結構如下:

image-20200613172237233
image-20200613172237233
image-20200613172303711
image-20200613172303711

當我們把表4拆分成表5和表6時,你再來分析添加和刪除問題就會有不一樣的結果。假設在數據表中添加高主任管理的化學系時,該數據只會添加到表6中,不會發生傳遞依賴而影響其他數據。那假設Jack同學畢業了,要將Jack同學的相關數據從表中刪除,這時我們需要刪除表6中的學號3數據和表3中的學號3數據即可,它們也沒有傳遞依賴關係,同樣不會影響到其他數據。

四、範式的表設計

在這裡我詳細講解了資料庫的三大範式,為什麼一般我們只研究三大範式而不去延申至六大範式呢?在上面資料庫範式概念的時候,我也有講過。這裡我還需要強調一下!

資料庫六大範式,一級比一級要求得嚴格。各種範式呈遞次規範,越高的範式資料庫冗餘越小。範式即是對資料庫表設計的約束,約束越多,表設計就越複雜。表數據過於複雜,對於我們後期對資料庫表的維護以及擴展、刪除、備份等種種操作帶來了一定的難度。所以,在實際開發中我們只需要遵循資料庫前面的三大範式即可,不需要額外延申擴展。

註意: 在剖析三大範式的時候,最終版本的表結構就是表3 + 表5 + 表6。我需要在這裡說明一個問題,其實這樣設計表是可以的,但並不是很合理。因為我們在建表的時候是有主鍵和外鍵約束的。這三張表中,第一列的表預設為主鍵,其中主鍵為學號還可以接收,如果主鍵為系名那就占用的空間變大了。在表的級聯查詢中會損耗性能。所以,一般我們在設計表的時候,是需要主外鍵約束的,而其主外鍵基本是都是占用內容空間很小的數字。當你的表結構和需求滿足主鍵遞增時,則可以通過設置auto_increment參數來完成!

這裡如果不瞭解MySQL主外鍵約束的小伙伴,可以參考此文章MySQL基礎來查補缺漏知識點。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近開始接觸websocket,第一次裝的時候,還是遇到了些問題,這裡記錄一下 1.從git下載uWebSockets 地址:https://github.com/uNetworking/uWebSockets git clone https://github.com/uNetworking/uWe ...
  • Linux基礎知識、Shell編程、Linux系統管理、Linux服務管理、MySQL資料庫管理、Linux集群、Linux虛擬化 ...
  • 本文主要闡述了UNIX與Linux發展史、開源軟體簡介、Linux應用領域 ...
  • 單行編輯控制項具有ES_密碼樣式。預設情況下,具有此樣式的編輯控制項為用戶鍵入的每個字元顯示一個星號。 但是,本例使用EM_SETPASSWORDCHAR消息將預設字元從星號更改為加號(+)。以下屏幕截圖顯示用戶輸入密碼後的對話框。 步驟1:創建密碼對話框的實例。 下麵的C++代碼示例使用DealBox ...
  • 最近安裝了datagrip操作達夢資料庫,發現有一個問題:dagagrip無法獲取dbms_output的輸出,在oracle是可以的,但在達夢不行。 於是聯想到一個問題:c語言裡面怎麼獲取dbms_output的輸出? 百度了一下,沒有找到明確的答案,但是找到了jdbc獲取dbms_output輸 ...
  • 安裝達夢windows版資料庫時,會附帶安裝一個資料庫管理工具。這個工具是我知道的,最全面的達夢資料庫可視化數據操作工具。、 除了支持常規的dml操作外,還支持存儲過程開發與調試,同時提供了簡單的操作歷史記錄查詢,sql自動補全,資料庫對象管理等功能。 但用慣了oracle的人,可能還是會更習慣PL ...
  • 文章開始啰嗦兩句,寫到這裡共21篇關於redis的瑣碎知識,沒有過多的寫編程過程中redis的應用,著重寫的是redis命令、客戶端、伺服器以及生產環境搭建用到的主從、哨兵、集群實現原理,如果你真的能看的進去,相信對你在以後用到redis時會有一定的幫助。 寫到現在,redis相關的內容暫時告一段落 ...
  • 《大話資料庫》-SQL語句執行時,底層究竟做了什麼小動作? 前言 大家好,我是Taoye,試圖用玩世不恭過的態度對待生活的Coder。 現如今我們已然進入了大數據時代,無論是業內還是業外的朋友,相信都有聽說過資料庫這個名詞。數據是一個項目的精華,也扮演著為企業創造價值的重要角色,一個較為完善的公司一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...