資料庫設計文件範本(Database Design Document Template)

適用標準:ISO/IEC 11179(Metadata Registries)、DAMA DMBOK 2.0、ISO/IEC/IEEE 42010:2022
適用階段:系統設計階段(Design Phase)
負責角色:系統架構師(SA)、資料庫管理師(DBA)


📑 章節目錄

  1. 文件資訊
  2. 資料庫架構概觀
  3. 實體關聯模型(ER Diagram)
  4. 資料表設計
  5. 索引設計策略
  6. 資料關聯與完整性約束
  7. 命名規範
  8. 資料治理與安全
  9. 效能設計考量
  10. 資料遷移與版本控制
  11. 附錄

📝 範本


1. 文件資訊

項目內容
文件名稱[系統名稱] 資料庫設計文件
文件編號[專案代碼]-DBD-[版本號]
版本v[X.Y]
建立日期[YYYY-MM-DD]
最後更新[YYYY-MM-DD]
撰寫者[SA/DBA 姓名]
審核者[技術主管/架構師]
核准者[專案經理]

版本歷程

版本日期修改人修改內容
v1.0[YYYY-MM-DD][姓名]初版發布

關聯文件

文件名稱文件編號關係
系統架構文件(SAD)[編號]上游輸入
功能需求文件(FRD)[編號]需求來源
API 規格文件[編號]介面對應

2. 資料庫架構概觀

2.1 資料庫技術選型

項目選擇說明
RDBMS[PostgreSQL / SQL Server / MySQL][選型原因]
版本[版本號]
部署模式[Single / Primary-Replica / Cluster][HA 需求]
字元集[UTF-8 / UTF-16]
排序規則[Collation]

2.2 資料庫實例配置

實例名稱用途主機連接埠備註
[DB_MAIN]主要業務資料[hostname][port]Primary
[DB_READ]讀取副本[hostname][port]Read Replica
[DB_ARCHIVE]歷史資料歸檔[hostname][port]Archive

2.3 Schema 架構

[Database]
├── schema: core        -- 核心業務資料表
├── schema: auth        -- 認證授權相關
├── schema: audit       -- 稽核軌跡
├── schema: staging     -- ETL 暫存區
└── schema: archive     -- 歷史歸檔

3. 實體關聯模型(ER Diagram)

3.1 概念層 ERD(Conceptual ER Diagram)

呈現主要實體(Entity)之間的高階關係,不含欄位細節。

erDiagram
    [ENTITY_A] ||--o{ [ENTITY_B] : "[關係描述]"
    [ENTITY_A] ||--|{ [ENTITY_C] : "[關係描述]"
    [ENTITY_B] }o--|| [ENTITY_D] : "[關係描述]"

3.2 邏輯層 ERD(Logical ER Diagram)

呈現所有實體、屬性與關係,對應正規化後的結構。

erDiagram
    [TABLE_A] {
        bigint id PK
        varchar(100) name
        timestamp created_at
    }
    [TABLE_B] {
        bigint id PK
        bigint table_a_id FK
        varchar(200) description
        boolean is_active
    }
    [TABLE_A] ||--o{ [TABLE_B] : "has many"

3.3 物理層 ERD(Physical ER Diagram)

完整呈現資料型別、索引、約束等實作細節。(可使用 ERD 工具匯出,如 DBeaver、dbdiagram.io)

[附上物理 ERD 圖檔或連結]


4. 資料表設計

4.1 資料表清單

#Schema資料表名稱中文說明預估資料量成長率/月
1core[table_name][說明][N rows][% / month]
2core[table_name][說明][N rows][% / month]

4.2 資料表規格(逐表詳述)

Table: [schema].[table_name]
說明[中文功能描述]
預估資料量[初始筆數] → [1年後預估]
分區策略[None / Range / Hash / List]
保留策略[永久 / N年後歸檔 / N年後刪除]
#欄位名稱資料型別NULL預設值PK/FK/UK說明
1idBIGINTNOT NULLGENERATEDPK主鍵(自動遞增)
2[column][type(length)][NULL/NOT NULL][default][FK → table.col][說明]
3created_atTIMESTAMP WITH TZNOT NULLCURRENT_TIMESTAMP建立時間
4created_byVARCHAR(100)NOT NULL建立者
5updated_atTIMESTAMP WITH TZNULL更新時間
6updated_byVARCHAR(100)NULL更新者
7is_deletedBOOLEANNOT NULLFALSE軟刪除標記
8versionINTEGERNOT NULL1樂觀鎖版本號

Check Constraints:

約束名稱條件說明
[ck_table_column][column] IN (‘A’, ‘B’, ‘C’)[業務規則]

5. 索引設計策略

5.1 索引清單

#資料表索引名稱索引類型欄位說明
1[table][ix_table_col]B-Tree[col1, col2][查詢場景]
2[table][ux_table_col]Unique[col1][唯一約束]
3[table][ix_table_col_gin]GIN[jsonb_col][JSONB 搜尋]

5.2 索引設計原則

原則說明
選擇性索引欄位基數(Cardinality)應 > [閾值]
覆蓋索引高頻查詢使用 covering index 避免回表
複合索引順序遵循最左前綴原則,等值條件在前、範圍在後
索引數量限制單表索引不超過 [N] 個
定期維護排程 REINDEX / REBUILD 頻率:[週期]

6. 資料關聯與完整性約束

6.1 外鍵關係

子表子表欄位父表父表欄位ON DELETEON UPDATE
[child_table][fk_col][parent_table][pk_col][CASCADE/RESTRICT/SET NULL][CASCADE/NO ACTION]

6.2 完整性設計決策

決策項目選擇理由
外鍵強制約束[是 / 應用層檢查][效能/彈性考量]
軟刪除 vs 硬刪除[軟刪除][稽核/復原需求]
Cascade 策略[限定使用/禁止][資料安全]

7. 命名規範

7.1 物件命名規則

物件類型命名格式範例
Schemasnake_casecore, auth
資料表snake_case(單數名詞)employee, leave_request
欄位snake_casefirst_name, department_id
主鍵idid
外鍵{referenced_table}_iddepartment_id
索引ix_{table}_{column}ix_employee_department_id
唯一索引ux_{table}_{column}ux_employee_employee_no
Check 約束ck_{table}_{column}ck_employee_status
Sequenceseq_{table}seq_employee
Viewvw_{name}vw_active_employee
Stored Proceduresp_{action}_{object}sp_calculate_salary
Functionfn_{name}fn_get_work_days
Triggertrg_{table}_{event}trg_employee_audit

7.2 稽核欄位標準

欄位名稱型別用途
created_atTIMESTAMP WITH TIME ZONE記錄建立時間
created_byVARCHAR(100)建立者帳號
updated_atTIMESTAMP WITH TIME ZONE最後修改時間
updated_byVARCHAR(100)修改者帳號
is_deletedBOOLEAN DEFAULT FALSE軟刪除標記
deleted_atTIMESTAMP WITH TIME ZONE刪除時間
deleted_byVARCHAR(100)刪除者帳號
versionINTEGER DEFAULT 1樂觀鎖版本

8. 資料治理與安全

8.1 資料分類分級

分類等級定義處理原則範例
一般資料Level 1公開或低敏感標準存取控制部門名稱
內部資料Level 2限組織內部角色授權員工清單
機密資料Level 3高度敏感加密 + 稽核薪資、績效
個資(PII)Level 4受法規保護加密 + 遮罩 + 同意管理身分證字號、地址

8.2 加密策略

類型適用場景方法備註
靜態加密(At Rest)整個 DB / TablespaceTDE(Transparent Data Encryption)
欄位加密PII / 機密欄位AES-256 + 應用層加解密影響查詢
傳輸加密(In Transit)Client ↔ DBTLS 1.3強制啟用
備份加密Backup filesAES-256

8.3 存取控制

角色Schema 權限表權限說明
app_readonlycore (USAGE)SELECT唯讀服務帳號
app_readwritecore (USAGE)SELECT, INSERT, UPDATE讀寫服務帳號
dba_adminALLALLDBA 管理帳號
audit_readeraudit (USAGE)SELECT稽核讀取

8.4 資料保留策略

資料類型保留期限歸檔策略法規依據
[交易資料][N 年][移至 archive schema][法規名稱]
[日誌資料][N 個月][壓縮歸檔至 Object Storage][內部政策]
[個資][依同意書期限][匿名化/刪除][GDPR / 個資法]

9. 效能設計考量

9.1 分區策略(Partitioning)

資料表分區方式分區鍵分區週期說明
[table]RANGE[date_column][資料量大,依日期查詢]

9.2 讀寫分離

操作類型目標實例說明
寫入(INSERT/UPDATE/DELETE)Primary
即時查詢(OLTP)Primary / Read ReplicaReplica lag < [N]ms
報表查詢(OLAP)Read Replica / Analytics DB

9.3 連接池配置

參數說明
最小連接數[N]
最大連接數[N]
連接逾時[N]s
閒置逾時[N]s
連接池工具[PgBouncer / HikariCP]

10. 資料遷移與版本控制

10.1 Schema 版本管理工具

項目選擇
Migration 工具[Flyway / Liquibase / EF Migrations]
版本命名規則V{版本號}__{描述}.sql
執行環境[CI/CD Pipeline 自動執行]

10.2 Migration 腳本規範

規則說明
每個 migration 應可 rollback提供對應 undo script
禁止修改已部署的 migration建立新 migration 修正
大資料表 DDL 變更使用 online DDL / pt-osc
資料填充(seed)與 DDL 分開管理

10.3 環境同步策略

來源環境目標環境同步方式頻率
ProductionStagingMigration scripts forward每次部署前
ProductionDev結構同步 + 遮罩資料[週期]

11. 附錄

11.1 常用 SQL 範例

-- 建立資料表範例
CREATE TABLE [schema].[table_name] (
    id          BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    [columns]   ...,
    created_at  TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    created_by  VARCHAR(100) NOT NULL,
    updated_at  TIMESTAMP WITH TIME ZONE,
    updated_by  VARCHAR(100),
    is_deleted  BOOLEAN NOT NULL DEFAULT FALSE,
    version     INTEGER NOT NULL DEFAULT 1
);

-- 建立索引範例
CREATE INDEX ix_[table]_[column] ON [schema].[table_name] ([column]);

-- 建立外鍵範例
ALTER TABLE [child_table]
ADD CONSTRAINT fk_[child]_[parent]
FOREIGN KEY ([column]) REFERENCES [parent_table](id)
ON DELETE RESTRICT ON UPDATE CASCADE;

11.2 資料字典匯出格式

建議使用工具自動產出,並納入版本控制。


📖 使用說明

各章節填寫指引

章節填寫時機負責人重點說明
§1 文件資訊文件建立時SA確保版本追蹤
§2 架構概觀技術選型完成後SA/DBA說明 DB 選型決策理由
§3 ER Diagram需求分析轉設計時SA先做概念層→邏輯層→物理層
§4 資料表設計詳細設計階段SA/DBA每張表獨立描述,含預估資料量
§5 索引策略配合查詢場景設計DBA需配合效能測試調整
§6 關聯約束詳細設計階段SA明確標示外鍵與完整性策略
§7 命名規範專案啟動時制定架構團隊全專案統一遵守
§8 資料治理設計階段SA/資安配合資安需求與法規要求
§9 效能設計設計階段DBA依 NFR 的效能指標規劃
§10 遷移管理導入 CI/CD 時DBA/DevOps確保環境一致性

ER 建模方法論

  1. 概念層建模(Conceptual):識別核心業務實體與關係,不含欄位
  2. 邏輯層建模(Logical):正規化至 3NF,定義所有屬性與資料型別
  3. 物理層建模(Physical):加入索引、分區、反正規化等效能最佳化

正規化檢核

正規化規則何時可反正規化
1NF消除重複群組,確保原子值
2NF消除部分相依
3NF消除遞移相依高頻讀取 + 低頻更新場景
BCNF消除所有非平凡相依通常 3NF 即足夠

💡 範例(以 HRMS 人力資源管理系統為例)


範例:文件資訊

項目內容
文件名稱HRMS 人力資源管理系統 資料庫設計文件
文件編號HRMS-DBD-v1.0
版本v1.0
建立日期2026-03-15
最後更新2026-05-10
撰寫者陳柏翰(SA)、林志偉(DBA)
審核者王大明(技術主管)

範例:概念層 ERD

erDiagram
    EMPLOYEE ||--o{ LEAVE_REQUEST : "submits"
    EMPLOYEE ||--o{ ATTENDANCE : "records"
    EMPLOYEE }o--|| DEPARTMENT : "belongs to"
    DEPARTMENT ||--o{ POSITION : "has"
    EMPLOYEE }o--|| POSITION : "holds"
    EMPLOYEE ||--o{ SALARY_RECORD : "receives"
    EMPLOYEE ||--o{ PERFORMANCE_REVIEW : "evaluated in"
    MANAGER ||--o{ LEAVE_REQUEST : "approves"

範例:邏輯層 ERD(部分)

erDiagram
    employee {
        bigint id PK
        varchar employee_no UK
        varchar first_name
        varchar last_name
        varchar email UK
        bigint department_id FK
        bigint position_id FK
        date hire_date
        varchar status
        timestamp created_at
        varchar created_by
        boolean is_deleted
    }
    department {
        bigint id PK
        varchar dept_code UK
        varchar dept_name
        bigint parent_dept_id FK
        bigint manager_id FK
        boolean is_active
        timestamp created_at
    }
    leave_request {
        bigint id PK
        bigint employee_id FK
        varchar leave_type
        date start_date
        date end_date
        decimal total_days
        varchar status
        bigint approver_id FK
        text reason
        timestamp created_at
    }
    employee }o--|| department : "belongs to"
    employee ||--o{ leave_request : "submits"

範例:資料表規格

Table: core.employee
說明HRMS 員工主檔
預估資料量5,000 筆 → 8,000 筆(1年後)
分區策略None(資料量未達分區閾值)
保留策略永久保留(離職員工軟刪除)
#欄位名稱資料型別NULL預設值PK/FK/UK說明
1idBIGINTNOT NULLGENERATED ALWAYS AS IDENTITYPK主鍵
2employee_noVARCHAR(20)NOT NULLUK員工編號
3first_nameVARCHAR(50)NOT NULL
4last_nameVARCHAR(50)NOT NULL
5emailVARCHAR(150)NOT NULLUK公司信箱
6phoneVARCHAR(20)NULL聯絡電話(加密)
7id_numberVARCHAR(100)NOT NULL身分證字號(AES-256 加密)
8department_idBIGINTNOT NULLFK → department.id所屬部門
9position_idBIGINTNOT NULLFK → position.id職位
10hire_dateDATENOT NULL到職日
11resignation_dateDATENULL離職日
12statusVARCHAR(20)NOT NULL‘ACTIVE’ACTIVE/ON_LEAVE/RESIGNED
13created_atTIMESTAMPTZNOT NULLCURRENT_TIMESTAMP建立時間
14created_byVARCHAR(100)NOT NULL建立者
15updated_atTIMESTAMPTZNULL更新時間
16updated_byVARCHAR(100)NULL更新者
17is_deletedBOOLEANNOT NULLFALSE軟刪除
18versionINTEGERNOT NULL1樂觀鎖

Check Constraints:

約束名稱條件說明
ck_employee_statusstatus IN (‘ACTIVE’, ‘ON_LEAVE’, ‘RESIGNED’)員工狀態列舉

範例:索引設計

#資料表索引名稱索引類型欄位說明
1employeeux_employee_employee_noUnique B-Treeemployee_no員工編號唯一
2employeeux_employee_emailUnique B-Treeemail信箱唯一
3employeeix_employee_department_idB-Treedepartment_id依部門查詢
4employeeix_employee_statusB-Treestatus, is_deleted在職員工清單
5leave_requestix_leave_request_employee_dateB-Treeemployee_id, start_date員工請假查詢
6leave_requestix_leave_request_approverB-Treeapprover_id, status主管待審核清單
7attendanceix_attendance_employee_dateB-Treeemployee_id, check_date出勤記錄查詢

範例:資料治理(PII 欄位)

資料表.欄位分類等級加密方式遮罩規則備註
employee.id_numberLevel 4 (PII)AES-256(應用層)A1234*****個資法
employee.phoneLevel 3AES-256(應用層)0912-***-789
salary_record.amountLevel 3TDE + 欄位加密***,***僅薪資人員可見
employee.emailLevel 2內部公開

範例:DDL 腳本

-- ====================================
-- HRMS Database Schema: core
-- Version: V1.0__initial_schema.sql
-- ====================================

CREATE SCHEMA IF NOT EXISTS core;

CREATE TABLE core.department (
    id              BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    dept_code       VARCHAR(20)  NOT NULL UNIQUE,
    dept_name       VARCHAR(100) NOT NULL,
    parent_dept_id  BIGINT       REFERENCES core.department(id),
    manager_id      BIGINT,      -- FK added after employee table created
    is_active       BOOLEAN      NOT NULL DEFAULT TRUE,
    created_at      TIMESTAMPTZ  NOT NULL DEFAULT CURRENT_TIMESTAMP,
    created_by      VARCHAR(100) NOT NULL,
    updated_at      TIMESTAMPTZ,
    updated_by      VARCHAR(100),
    is_deleted      BOOLEAN      NOT NULL DEFAULT FALSE,
    version         INTEGER      NOT NULL DEFAULT 1
);

CREATE TABLE core.employee (
    id              BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    employee_no     VARCHAR(20)  NOT NULL UNIQUE,
    first_name      VARCHAR(50)  NOT NULL,
    last_name       VARCHAR(50)  NOT NULL,
    email           VARCHAR(150) NOT NULL UNIQUE,
    phone           VARCHAR(100),             -- encrypted
    id_number       VARCHAR(100) NOT NULL,    -- encrypted
    department_id   BIGINT       NOT NULL REFERENCES core.department(id),
    position_id     BIGINT       NOT NULL,
    hire_date       DATE         NOT NULL,
    resignation_date DATE,
    status          VARCHAR(20)  NOT NULL DEFAULT 'ACTIVE'
                    CHECK (status IN ('ACTIVE', 'ON_LEAVE', 'RESIGNED')),
    created_at      TIMESTAMPTZ  NOT NULL DEFAULT CURRENT_TIMESTAMP,
    created_by      VARCHAR(100) NOT NULL,
    updated_at      TIMESTAMPTZ,
    updated_by      VARCHAR(100),
    is_deleted      BOOLEAN      NOT NULL DEFAULT FALSE,
    version         INTEGER      NOT NULL DEFAULT 1
);

-- 索引
CREATE INDEX ix_employee_department_id ON core.employee(department_id);
CREATE INDEX ix_employee_status ON core.employee(status, is_deleted);

-- 補建 department.manager_id FK
ALTER TABLE core.department
ADD CONSTRAINT fk_department_manager
FOREIGN KEY (manager_id) REFERENCES core.employee(id);

CREATE TABLE core.leave_request (
    id              BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    employee_id     BIGINT       NOT NULL REFERENCES core.employee(id),
    leave_type      VARCHAR(30)  NOT NULL,
    start_date      DATE         NOT NULL,
    end_date        DATE         NOT NULL,
    total_days      DECIMAL(4,1) NOT NULL,
    status          VARCHAR(20)  NOT NULL DEFAULT 'PENDING'
                    CHECK (status IN ('PENDING', 'APPROVED', 'REJECTED', 'CANCELLED')),
    approver_id     BIGINT       REFERENCES core.employee(id),
    reason          TEXT,
    reject_reason   TEXT,
    created_at      TIMESTAMPTZ  NOT NULL DEFAULT CURRENT_TIMESTAMP,
    created_by      VARCHAR(100) NOT NULL,
    updated_at      TIMESTAMPTZ,
    updated_by      VARCHAR(100),
    is_deleted      BOOLEAN      NOT NULL DEFAULT FALSE,
    version         INTEGER      NOT NULL DEFAULT 1,
    CHECK (end_date >= start_date)
);

CREATE INDEX ix_leave_request_employee_date ON core.leave_request(employee_id, start_date);
CREATE INDEX ix_leave_request_approver ON core.leave_request(approver_id, status);

📌 審閱重點

  • ER Diagram 是否完整反映 FRD 中的所有業務實體?
  • 命名規範是否全專案一致?
  • PII 欄位是否都有標示加密與遮罩策略?
  • 索引是否覆蓋主要查詢場景(配合 EXPLAIN ANALYZE 驗證)?
  • 分區與歸檔策略是否符合資料保留法規要求?