數據庫范式(Normalization)

一個設計混亂的數據庫就像一個雜亂的房間,用起來非常不方便:東西到處亂放(數據冗余),找件東西要翻遍所有角落(查詢困難),扔掉一把舊椅子時,可能會把搭在上面的唯一一件外套也一起扔了(刪除異常)。

數據庫范式(Normalization) 就是一套“房間整理法則”,指導我們如何合理地組織數據表,以消除冗余、避免上述問題。2NF和3NF是其中最核心、最重要的兩條法則。

初始狀態:亂糟糟的第一范式 (1NF)

假設我們要設計一個系統來記錄學生的選課成績。最直接的想法可能是把所有信息都塞進一張大表里。這張表符合第一范式(1NF),因為每個單元格都只有一個值,并且沒有完全重復的行。但你會發現,它問題重重。

選課成績表 (符合1NF)

學號課程號學生姓名課程名稱授課老師成績
101CS101張三計算機導論王老師92
101MTH202張三高等數學李老師85
102CS101李四計算機導論王老師88
103PHY301王五量子力學趙老師95

我們先來分析這張表的“身份”信息:

  • 主碼 (Primary Key): 要唯一確定一行數據,需要同時知道“哪個學生”和“哪門課”。因為一個學生可以選多門課,一門課也可以被多個學生選。所以,主碼是 (學號, 課程號) 這樣一個組合。
  • 主屬性: 學號, 課程號
  • 非主屬性: 學生姓名, 課程名稱, 授課老師, 成績

這張表雖然能用,但有嚴重的“副作用”(我們稱之為“異常”):

  • 更新異常 (Update Anomaly): 如果學生“張三”改名叫“張大三”,你必須修改所有他出現的行。一旦漏掉一行,數據就不一致了。
  • 插入異常 (Insertion Anomaly): 你無法添加一個新生(比如學號104的“趙六”),除非他至少選了一門課。因為主碼 (學號, 課程號) 要求 課程號 不能為空。
  • 刪除異常 (Deletion Anomaly): 如果“王五”退掉了他唯一選的課(量子力學),那么他所在的整行數據都會被刪除。我們不僅丟失了他的選課記錄,連“王五”這個學生本身的信息也從數據庫里消失了!

如何解決這些問題?答案就是遵循范式法則進行整理。


第一步整理:達到第二范式 (2NF)

2NF的法則

一個表在符合1NF的基礎上,如果所有非主屬性都“完全函數依賴”于主碼,那么它就符合2NF。

  • “完全函數依賴”:聽起來很學術,其實很簡單。意思就是一個非主屬性的值,必須由整個主碼來唯一確定,而不是由主碼的一部分就能確定。
  • 通俗版法則任何一個非主屬性,都不能只依賴于組合主碼的一部分。(這條規則只在主碼是組合碼時才有意義,就像我們這個例子)。
運用2NF法則整理

我們的主碼是 (學號, 課程號)。我們來檢查一下每個非主屬性:

  • 成績: 由什么決定?必須同時知道 學號課程號 才能確定一個唯一的成績。所以,成績 依賴于整個主碼這很好,符合2NF。
  • 學生姓名: 由什么決定?只需要 學號 就能確定。學生的姓名和他選了什么課沒關系。所以,學生姓名 只依賴于主碼的一部分 (學號)。這很糟糕,違反了2NF。
  • 課程名稱授課老師: 由什么決定?只需要 課程號 就能確定。這和哪個學生來選課也沒關系。所以,這兩個屬性也只依賴于主碼的一部分 (課程號)。這也很糟糕,違反了2NF。
解決方法:拆分!

解決辦法就是“分家”。把那些只依賴于部分主碼的信息,拆分出去成立自己的獨立小家庭(新表)。

  1. 只依賴于 學號 的信息,放到新的 學生表 里。
  2. 只依賴于 課程號 的信息,放到新的 課程表 里。
  3. 依賴于 (學號, 課程號) 完整組合的信息,留在瘦身后的 選課表 里。

學生表 (Students)

學號 (主碼)學生姓名
101張三
102李四
103王五

課程表 (Courses)

課程號 (主碼)課程名稱授課老師
CS101計算機導論王老師
MTH202高等數學李老師
PHY301量子力學趙老師

選課表 (Enrollment)

學號 (外碼)課程號 (外碼)成績
101CS10192
101MTH20285
102CS10188
103PHY30195
(這張表的主碼依然是 (學號, 課程號))

現在,我們所有的表都符合2NF了,之前提到的那些異常問題也隨之解決!張三改名,只需改 學生表 一處。新生趙六可以直接添加到 學生表,不用非得選課。


第二步整理:達到第三范式 (3NF)

我們離完美還差一步。仔細看剛剛創建的 課程表,它里面還隱藏著一個問題。

3NF的法則

一個表在符合2NF的基礎上,如果不存在“傳遞函數依賴”,那么它就符合3NF。

  • “傳遞函數依賴”:指的是一個非主屬性,不直接依賴于主碼,而是通過另一個非主屬性間接地依賴于主碼。形成了一個依賴鏈條:主碼 -> 非主屬性A -> 非主屬性B
  • 通俗版法則任何一個非主屬性,都不能依賴于其他非主屬性。
運用3NF法則整理

為了讓問題更明顯,我們在 課程表 里加一列“老師所在院系”。

課程表 (符合2NF,但不符合3NF)

課程號 (主碼)課程名稱授課老師老師所在院系
CS101計算機導論王老師計算機系
MTH202高等數學李老師數學系
CS205數據結構王老師計算機系

我們來檢查主碼 課程號 和非主屬性之間的依賴關系:

  • 課程名稱 直接依賴于 課程號很好
  • 授課老師 直接依賴于 課程號(為簡化,假設一門課只有一個老師)。很好
  • 老師所在院系: 老師的院系是由 課程號 決定的嗎?不是! 它是由授課老師決定的。這樣就形成了一個依賴鏈條:
    課程號 -> 授課老師 -> 老師所在院系
    這就是傳遞依賴,它違反了3NF。

這又會引發老問題!如果“王老師”從“計算機系”調到了“人工智能系”,你就必須修改他教的每一門課的記錄,非常麻煩且容易出錯。

解決方法:再次拆分!

我們把這個傳遞依賴鏈條也拆開,把老師的信息獨立出去。

老師表 (Instructors)

授課老師 (主碼)老師所在院系
王老師計算機系
李老師數學系
趙老師物理系

新的課程表 (Courses)

課程號 (主碼)課程名稱授課老師 (外碼)
CS101計算機導論王老師
MTH202高等數學李老師
CS205數據結構王老師
PHY301量子力學趙老師

現在,如果王老師調動院系,我們只需在 老師表 中修改唯一的一條記錄。至此,我們所有的表都達到了3NF,房間整理完畢!

最終總結

  • 1NF:入場券。 確保數據是“原子的”(每個單元格一個值)。
  • 2NF:消除部分依賴。 確保所有非主屬性都依賴于整個組合主碼,而不是它的一部分。(解決方法:把依賴于部分的屬性拆出去)。
  • 3NF:消除傳遞依賴。 確保所有非主屬性都依賴于主碼,而不是依賴于其他非主屬性。(解決方法:把間接依賴的屬性拆出去)。

通過遵循這些法則,我們把一張龐大、混亂的表,拆分成了四個干凈、清晰、健壯的小表:學生表老師表課程表選課表。這就是關系數據庫設計的精髓所在。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/99124.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/99124.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/99124.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構---循環隊列

基于循環數組實現的循環隊列解決了順序隊列中的假溢出導致的空間浪費問題操作:(1)初始化//循環隊列 typedef struct {int *data;//指針模擬聲明數組int head,tail;//隊頭,隊尾 }Queue; //初始化 Queue *InitQueue() {Queue *q (Q…

深入理解線程模型

線程作為操作系統調度的基本執行單元,是實現高吞吐、低延遲系統的基礎。一、進程與線程的體系結構對比核心概念:進程(Process):操作系統資源分配的基本單位,擁有獨立的虛擬地址空間、文件描述符表、環境變量…

TTC定時器中斷——MPSOC實戰3

開啟TTC定時器&#xff0c;不同于7000系列的私有定時器此處設置LPD_LSBUS頻率TTC頻率取決于LPD_LSBUS可前往指定位置查看參數不使能填寫對應宏可前往指定位置查看參數main.c#include <stdio.h> #include "xparameters.h" #include "xgpiops.h" #incl…

人工智能訓練師三級備考筆記

一、實操1&#xff09;通用語法&#xff08;常見于實操題第一塊代碼塊&#xff09;1.讀取文件數據或加載數據集等描述時一般為以下結構&#xff1a;Datapd.read_文件格式(文件名) 注意&#xff1a;文件名需要用‘ ’框起來&#xff0c;必須要有引號文件格式有以下內容csv、txt…

Cherry Studio遞歸工具調用機制深度解析

在現代AI應用開發中,工具調用(Tool Calling)已成為大語言模型與外部系統交互的核心機制。Cherry Studio作為一款先進的AI對話客戶端,實現了一套完整的遞歸工具調用系統,能夠讓AI助手在執行復雜任務時自動調用多個工具,并根據執行結果智能決策下一步操作。本文將深入解析這…

[哈希表]966. 元音拼寫檢查器

966. 元音拼寫檢查器 class Solution:def spellchecker(self, wordlist: List[str], queries: List[str]) -> List[str]:origin set(wordlist) # 存儲原始單詞用于完全匹配lower_to_origin {} # 存儲小寫形式到原始單詞的映射vowel_to_origin {} # 存儲元音模糊形…

正則表達式與文本三劍客(grep、sed、awk)基礎與實踐

正則表達式基礎與實踐一、正則表達式概述1. 定義正則表達式&#xff08;Regular Expression&#xff0c;簡稱 RE&#xff09;是用于描述字符排列和匹配模式的語法規則&#xff0c;核心作用是對字符串進行分割、匹配、查找、替換操作。它本質是 “模式模板”&#xff0c;Linux 工…

eclipse中web項目編譯后的lib里面jar為空問題處理

1. 檢查項目構建配置驗證項目性質右鍵單擊項目 → Properties確認項目已正確配置&#xff1a;?Project Facets?&#xff1a;確保已勾選"Dynamic Web Module"?Targeted Runtimes?&#xff1a;確保已選擇服務器運行時&#xff08;如Tomcat&#xff09;檢查部署程序…

C語言中的遞歸問題——漢諾塔問題

漢諾塔&#xff08;Tower of Hanoi)&#xff0c;又稱河內塔&#xff0c;是一個源于印度古老傳說的益智玩具。傳說大梵天創造世界的時候做了三根金剛石柱子&#xff0c;在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在…

ArkAnalyzer源碼初步分析I——分析ts項目流程

1.前言&#xff1a; 鴻蒙程序分析框架ArkAnalyzer&#xff08;方舟分析器&#xff09; 源碼地址 入門文檔 2.閱讀入門文檔后&#xff1a; 本人具有一定的Java開發經驗。雖然我對 TypeScript&#xff08;TS&#xff09;和 ArkTS 還不熟&#xff0c;但很多概念對我這個 Java 開…

c#基礎二(類和對象,構造器調用順序、訪問級別、重寫和多態、抽象類和接口)

一、類1.0對象初始化器class Student {public String name;public int age { get; set; } } internal class Program {static void Main(string[] args){ //寫法一Student stunew Student();stu.name"Tom";stu.age20;//寫法二Student stu2 new Student { name &qu…

Qt之快捷鍵、事件處理、自定義按鍵——完成記事本項目

快捷鍵我們電腦中的記事本中還支持快捷鍵&#xff0c;如“CTRLO”打開文件、“CTRLS”保存文件在Qt中使用QShortcut這個類創建快捷鍵在.cpp文件的構造函數中創建QShortcut對象&#xff0c;綁定打開文件和保存文件的槽函數放大縮小字體還是在.cpp的構造函數中編寫代碼Widget::Wi…

Open cascade中如何使用BRepAlgoAPI_Splitter分割一個Face

理論介紹 在OpenCASCADE幾何建模內核中&#xff0c;BRepAlgoAPI_Splitter是一個強大的工具&#xff0c;用于將一個形狀&#xff08;Shape&#xff09;用另一個形狀&#xff08;Tool&#xff09;進行分割。這種操作在CAD建模中非常常見&#xff0c;比如用平面切割實體、用曲線分…

【醫療 AI】Baichuan-M2 醫療大模型:技術解讀與使用方法

【醫療 AI】Baichuan-M2 醫療大模型&#xff1a;技術解讀與使用方法1. Baichuan-M2 醫療大模型簡介1.1 基本信息1.2 下載地址1.3 技術特點2. Baichuan-M2 模型技術報告2.1 摘要2.2 醫學性能評估2.2.1 HealthBench基準2.2.2 中國醫療場景對比評估2.3 系統架構2.3.1 驗證器系統2.…

unity pcd 二進制版 簡單顯示文件對象(單色)

unity Point Cloud Viewer and Tool 那個插件不支持pcd二進制&#xff0c;而且網上到處都是AI 我恨這種AI濫用&#xff0c;提供不了一點價值 好了&#xff0c;言歸正傳 可以在Point Cloud Viewer and Tool這個插件報錯地方轉用這個代碼&#xff0c;具體咋結合請自行研究。 …

強大的開源文檔問答工具-Kotaemon

Kotaemon 是一個基于 RAG&#xff08;Retrieval-Augmented Generation&#xff09;架構的開源文檔問答工具&#xff0c;為用戶提供與文檔對話的智能交互體驗。該項目同時服務于終端用戶和開發者&#xff0c;具有高度的可擴展性和定制化能力。技術棧分析核心技術棧后端框架Pytho…

區塊鏈:搭建簡單Fabric網絡并調用智能合約

使用docker服務搭建Hyperledger/fabric網絡的詳細教程&#xff0c;實現構建多節點的簡單聯盟鏈&#xff0c;并編寫、調用智能合約實現投票業務。 目錄 背景知識 Hyperledger Fabric 基本組件 交易(Transaction) 智能合約 實驗目的 實驗環境 基礎依賴 安裝Golang 安裝do…

Web前端面試題(2)

Web前端面試題(附答案及解析)&#xff08;2025.9月最新版&#xff09;-CSDN博客 1.link 與 import 的區別和用法 主要區別 特性<link>import語法類型HTML標簽CSS規則加載方式并行加載&#xff08;與其他資源同時加載&#xff09;串行加載&#xff08;必須等待主CSS文件…

Paxos協議

目錄 Paxos 是什么&#xff08;What&#xff09; Paxos 的目的&#xff08;Why&#xff09; 角色與職責&#xff08;Who&#xff09; 基本流程&#xff08;How&#xff09; 常見問題與對策 什么是多數派&#xff08;Quorum&#xff09; Paxos vs Raft 異同點 Paxos 是什…

第十二篇:Qcom Camx打印實時幀率 FPS

一、第一種方式(有些低平臺可能沒有) adb shell setprop persist.vendor.camera.enableFPSLog TRUE adb shell setprop persist.vendor.camera.systemLogEnable TRUE adb shell setprop vendor.debug.camera.overrideLogLevels 0xff chi-cdk/core/chiframework/chxextensi…