首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 數據庫設計規範化核心原則:拒絕空值欄位與重複列的實戰策略

     編輯:Oracle 資料庫基礎

判斷規範化水平的兩個宏觀指標

  1. 窄表多:實體拆分細緻,單表欄位少,關聯關係清晰。
  2. 寬表少:避免「大而全」的寬表,減少冗餘與鎖競爭。

符合此二者,通常達到 3NF 以上。具體執行層面需遵循五大要求,本文詳細闡述前兩條。

要求一:表中應盡量避免可為空的列

空值的隱性成本

  • 優化器處理空值需特殊邏輯(IS NULL 不走普通 B*Tree 索引),增加解析與執行開銷。
  • 大量空值列導致行長度變化大,影響區塊存儲密度與一致性讀構建。
  • 應用層須處理 NULL 邏輯(NVL、COALESCE),代碼複雜度上升。

解決策略

策略 1:設置默認值替代空值

-- 身份證號可能暫無,默認 'UNKNOWN' 而非 NULL
ALTER TABLE employee MODIFY (id_card DEFAULT 'UNKNOWN' NOT NULL);
  • 業務語義明確:'UNKNOWN' 區別於「未填寫」與「無證件」。
  • 索引可正常建立(NOT NULL 列全表掃描可用索引快速全掃描)。

策略 2:垂直拆分稀疏屬性至副表

場景:表 30 列,其中 10 列稀疏填充(< 10% 非空)。

-- 主表:核心高頻屬性
CREATE TABLE emp_core (
  emp_id    NUMBER PRIMARY KEY,
  name      VARCHAR2(30) NOT NULL,
  dept_id   NUMBER NOT NULL,
  hire_date DATE NOT NULL
);

-- 副表:稀疏擴展屬性
CREATE TABLE emp_ext (
  emp_id       NUMBER PRIMARY KEY REFERENCES emp_core(emp_id),
  id_card      VARCHAR2(18),
  emergency_contact VARCHAR2(50),
  -- ... 其他稀疏列
);
  • 主表窄、密、快,核心查詢無干擾。
  • 副表按需 LEFT JOIN,空值天然不佔用空間(無行即無存儲)。
  • 通過視圖 CREATE VIEW v_emp AS SELECT ... FROM emp_core LEFT JOIN emp_ext USING (emp_id) 對應用透明。

要求二:表不應有重複的值或列(消除重複組)

反模式:水平展開重複列

-- 錯誤設計:客戶聯系人展開為多列
CREATE TABLE customer_bad (
  cust_id       NUMBER PRIMARY KEY,
  contact1_name VARCHAR2(30), contact1_phone VARCHAR2(20), contact1_role VARCHAR2(20),
  contact2_name VARCHAR2(30), contact2_phone VARCHAR2(20), contact2_role VARCHAR2(20),
  contact3_name VARCHAR2(30), contact3_phone VARCHAR2(20), contact3_role VARCHAR2(20),
  -- 聯系人增加需 ALTER TABLE,歷史聯系人覆蓋導致訂單追溯失真
);

弊端:結構僵化、空值多、歷史追溯失真、頻繁 DDL 變更。

正規設計:獨立聯系人表 + 關聯

CREATE TABLE customer (
  cust_id NUMBER PRIMARY KEY,
  name    VARCHAR2(100) NOT NULL
);

CREATE TABLE customer_contact (
  contact_id   NUMBER PRIMARY KEY,
  cust_id      NUMBER NOT NULL REFERENCES customer(cust_id),
  contact_name VARCHAR2(30) NOT NULL,
  phone        VARCHAR2(20),
  role         VARCHAR2(20),        -- '採購'、'倉庫'、'財務'
  start_date   DATE DEFAULT SYSDATE,
  end_date     DATE,                -- 歷史保留,不覆蓋
  is_primary   NUMBER(1) DEFAULT 0
);
  • 聯系人無限擴展,無需 DDL。
  • 歷史完整保留(end_date 標記離職),訂單關聯 contact_id 永不失真。
  • 主聯系人由 is_primary 標記,查詢高效。

同理:產品多開發人員

CREATE TABLE product_dev (
  product_id NUMBER REFERENCES product(id),
  emp_id     NUMBER REFERENCES employee(id),
  role       VARCHAR2(20),          -- '主開'、'協作'、'審核'
  PRIMARY KEY (product_id, emp_id)
);

總結

規範化本質是將多值屬性、稀疏屬性拆分為獨立實體,通過外鍵關聯與視圖封裝,換取結構彈性、查詢性能與數據真實性的長期收益。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved