專案開發中,常面臨舊版資料庫結構需升級至新版,且必須保留客戶現有數據的情境。本文分享三種演進方案,從手動操作到自動化工具,逐步優化升級流程。
客戶使用舊版資料庫已有一段時間,累積一定業務數據。新版本需求導致資料庫結構大幅變動:包含預存程序調整、新增資料表、欄位型別變更、欄位新增等。挑戰在於:如何在不遺失舊數據的前提下,將客戶端資料庫結構平滑升級?
INSERT INTO ... SELECT 將舊數據遷移至新表。缺點: 數據量大時耗時極長,客戶端操作複雜,易出錯,需停機維護窗口過長。
核心邏輯:針對現有表,先改名備份,再依新腳本建表,最後將舊表數據寫入新表(僅對應同名欄位)。
-- 重命名表
EXEC sp_rename 'OldTableName', 'OldTableName_Bak';
-- 建立新表(依新版腳本)
CREATE TABLE NewTableName (...);
-- 搬移數據(指定欄位對應)
INSERT INTO NewTableName (Col1, Col2, ...)
SELECT Col1, Col2, ... FROM OldTableName_Bak;
EXEC sp_renamedb 'OldDB', 'NewDB';EXEC sp_rename 'TableName.[OldCol]', 'NewCol', 'COLUMN';SELECT name FROM sys.procedures;SELECT constraint_name, table_name FROM information_schema.table_constraints;ALTER TABLE TableName DROP CONSTRAINT [PK_|FK_|UK_|DF_|CK_]ConstraintName;| 約束類型 | 前綴範例 | 語法 |
|---|---|---|
| 主鍵 | PK_Column | CONSTRAINT PK_Column PRIMARY KEY (Column) |
| 唯一約束 | UK_Column | CONSTRAINT UK_Column UNIQUE (Column) |
| 預設約束 | DF_Column | CONSTRAINT DF_Column DEFAULT ('Value') FOR Column |
| 檢查約束 | CK_Column | CONSTRAINT CK_Column CHECK (LEN(Column) > 1) |
| 外鍵 | FK_Main_Ref | CONSTRAINT FK_Main_Ref FOREIGN KEY (Col) REFERENCES MainTable(PKCol) |
核心思路:讀取舊表結構與新版腳本結構,僅對差異執行 ALTER TABLE,完全避免數據搬移。
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'TableName';ALTER TABLE [TableName] ALTER COLUMN [ColName] [NewType] NOT NULL;ALTER TABLE [TableName] ADD [ColName] [Type] NOT NULL;此演進過程展示了從人工腳本到自動化工具的思維轉變。實務上,成熟的資料庫遷移工具(如 Flyway, Liquibase, DbUp)已提供版本化、冪等、可回滾的遷移框架,建議新專案優先採用成熟方案,避免重複造輪子。