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

Oracle 資料庫設計規範化核心原則:避免空值與重複欄位的實戰策略

     編輯:Oracle 資料庫基礎

資料庫設計規範化的兩大核心指標

判斷 Oracle 資料庫設計是否規範,主要看兩點:窄表數量與寬表數量。窄表多、寬表少,通常意味著設計符合正規化原則,資料冗餘低、維護性好。為達此目標,需滿足五大設計要求,本文深入解析前兩項最關鍵的要求。

要求一:表中應避免可為空的欄位

為什麼空值會傷害效能

  • Oracle 處理 NULL 需特殊邏輯(如索引預設不存 NULL、比較運算需三值邏輯)
  • 大量空值欄位會增加查詢計劃複雜度,降低執行效率
  • 空值在聯結、排序、聚合時需額外判斷,消耗 CPU 與 I/O

策略 1:設定預設值替代 NULL

案例:人事系統的身分證字號欄位,員工入職時可能暫無證件。

-- 不佳設計
ID_NO VARCHAR2(18) NULL;

-- 建議設計
ID_NO VARCHAR2(18) DEFAULT 'N/A' NOT NULL;
  • 數值型欄位可用 0 或 -1 作為預設標記值
  • 日期型可用 DATE '1900-01-01' 或 SYSDATE 視業務而定
  • 字串型用明確標記如 'N/A'、'UNKNOWN',避免空字串 ''(Oracle 視同 NULL)

策略 2:垂直拆分——將稀疏欄位移至副表

適用場景:某表可空欄位佔比超過 1/3,且多為選填資訊。

-- 主表:核心高頻欄位
CREATE TABLE EMP_MAIN (
    EMP_ID NUMBER PRIMARY KEY,
    EMP_NAME VARCHAR2(50) NOT NULL,
    DEPT_ID NUMBER NOT NULL,
    HIRE_DATE DATE NOT NULL
);

-- 副表:低頻、可選欄位
CREATE TABLE EMP_EXT (
    EMP_ID NUMBER PRIMARY KEY REFERENCES EMP_MAIN(EMP_ID),
    ID_NO VARCHAR2(18),
    EMERGENCY_CONTACT VARCHAR2(100),
    BANK_ACCOUNT VARCHAR2(30),
    HOBBY VARCHAR2(200)
);
  • 主表保持窄而快,核心查詢不受稀疏欄位拖累
  • 副表透過 PK 關聯,查詢時才 LEFT JOIN
  • 節省主表儲存空間,減少全表掃描 I/O

要求二:表不應有重複的值或欄位

典型違規場景:多值欄位與重複群組

案例 A:產品開發者可能多人

-- 不佳設計:單欄位存多值,或重複欄位
CREATE TABLE PRODUCT_BAD (
    PROD_ID NUMBER PRIMARY KEY,
    PROD_NAME VARCHAR2(100),
    DEVELOPER_1 VARCHAR2(50),
    DEVELOPER_2 VARCHAR2(50),
    DEVELOPER_3 VARCHAR2(50)  -- 還要不要加第 4、5 位?
);

案例 B:客戶多聯絡人管理

-- 不佳設計:重複欄位群組
CREATE TABLE CUSTOMER_BAD (
    CUST_ID NUMBER PRIMARY KEY,
    CUST_NAME VARCHAR2(100),
    CONTACT_1_NAME VARCHAR2(50), CONTACT_1_PHONE VARCHAR2(20), CONTACT_1_ROLE VARCHAR2(20),
    CONTACT_2_NAME VARCHAR2(50), CONTACT_2_PHONE VARCHAR2(20), CONTACT_2_ROLE VARCHAR2(20),
    CONTACT_3_NAME VARCHAR2(50), CONTACT_3_PHONE VARCHAR2(20), CONTACT_3_ROLE VARCHAR2(20)
    -- 採購員換 6 次怎麼辦?加到 CONTACT_6?歷史訂單聯絡人怎麼查?
);

正確設計:正規化拆分為獨立實體表

-- 產品開發者關聯表(多對多)
CREATE TABLE PRODUCT_DEVELOPER (
    PROD_ID NUMBER REFERENCES PRODUCT(PROD_ID),
    EMP_ID NUMBER REFERENCES EMPLOYEE(EMP_ID),
    ROLE VARCHAR2(30),  -- 主開發、協助開發、審核等
    PRIMARY KEY (PROD_ID, EMP_ID)
);

-- 客戶聯絡人表(一對多,含歷史追蹤)
CREATE TABLE CUSTOMER_CONTACT (
    CONTACT_ID NUMBER PRIMARY KEY,
    CUST_ID NUMBER REFERENCES CUSTOMER(CUST_ID),
    CONTACT_NAME VARCHAR2(50) NOT NULL,
    PHONE VARCHAR2(20),
    ROLE VARCHAR2(30),  -- 採購、倉管、財務等
    START_DATE DATE DEFAULT SYSDATE,
    END_DATE DATE,      -- 為 NULL 表示現任
    IS_PRIMARY CHAR(1) DEFAULT 'N' CHECK (IS_PRIMARY IN ('Y','N'))
);

正規化拆分的三大收益

  1. 結構彈性:聯絡人數量無上限,角色可擴充,無需 DDL 異動
  2. 歷史追蹤:透過生效/失效日期,完整保留歷史聯絡人,訂單查詢不會錯誤顯示現任人員
  3. 查詢效能:主表保持窄表,索引更小,核心業務查詢更快;聯絡人查詢走獨立索引

進階補充:如何識別隱性重複欄位

  • 欄位命名規律:出現 _1、_2、_A、_B 等後綴,極大機率是重複群組
  • 語義相同:多個欄位代表同一業務概念(如多個電話、多個地址)
  • 同步異動:這些欄位總是同時新增、修改、刪除

總結

資料庫規範化的前兩項要求直指核心痛點:

  1. 拒絕 NULL:用預設值或垂直拆分,讓主表乾淨高效
  2. 拒絕重複:識別多值欄位與重複群組,拆分為獨立關聯表,賦予業務彈性與歷史追蹤能力

這兩項做到位,資料庫結構已勝過 80% 的專案。後續三項要求(主鍵設計、外鍵約束、索引策略)將在後續文章詳細說明。

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