判斷 Oracle 資料庫設計是否規範,主要看兩點:窄表數量與寬表數量。窄表多、寬表少,通常意味著設計符合正規化原則,資料冗餘低、維護性好。為達此目標,需滿足五大設計要求,本文深入解析前兩項最關鍵的要求。
案例:人事系統的身分證字號欄位,員工入職時可能暫無證件。
-- 不佳設計
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)適用場景:某表可空欄位佔比超過 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)
);
-- 不佳設計:單欄位存多值,或重複欄位
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 位?
);
-- 不佳設計:重複欄位群組
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、_2、_A、_B 等後綴,極大機率是重複群組資料庫規範化的前兩項要求直指核心痛點:
這兩項做到位,資料庫結構已勝過 80% 的專案。後續三項要求(主鍵設計、外鍵約束、索引策略)將在後續文章詳細說明。