是否有開發人員遵循數據庫更改的“最佳實踐”類型流程?
將數據庫更改從開發環境遷移到 QA 到生產環境的好方法是什麼?目前我們:
- 在 SQL 文件中編寫更改腳本並將其附加到 TFS 工作項。
- 這項工作經過同行評審
- 當工作準備好進行測試時,SQL 將在 QA 上執行。
- 作品經過 QA 測試
- 當工作準備好進行生產時,SQL 將在生產數據庫上執行。
問題在於它非常手動。它依賴於開發人員記得附加 sql 或如果開發人員忘記了同行評審員來獲取它。有時,最終是發現問題的測試人員或 QA 部署人員。
第二個問題是,如果兩個單獨的任務更改同一個數據庫對象,您有時最終需要手動協調更改。這可能就是這樣,但似乎仍然應該有一些自動化的方式來“標記”這些問題或其他東西。
我們的設置:我們的開發商店裡到處都是具有豐富數據庫經驗的開發人員。我們的項目非常面向數據庫。我們主要是一個 .NET 和 MS SQL 商店。目前我們正在使用 MS TFS 工作項來跟踪我們的工作。這對於程式碼更改很方便,因為它將更改集連結到工作項,因此我可以準確找出在遷移到 QA 和生產環境時需要包括哪些更改。我們目前沒有使用數據庫項目,但將來可能會切換到該項目(也許這是答案的一部分)。
我非常習慣我的原始碼控制系統為我處理這樣的事情,並希望我的 SQL 也有同樣的事情。
在 VS 環境中,我一直使用數據庫項目來實現更新腳本。我傾向於為我的腳本使用諸如“DatabaseUpdate17.sql”或“PriceUpdateFebruary2010.sql”之類的缺乏想像力的名稱。將它們作為數據庫項目讓我可以將它們與 Team Server 任務、錯誤聯繫起來(如果我們進行程式碼審查,也可以與它們聯繫起來)。我還在每個數據庫(我有權限)中包含一個專門用於收集模式更改的表。
CREATE TABLE [dbo].[AuditDDL]( [EventID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL, [EventData] [xml] NULL, -- what did they do [EventUser] varchar(100) NOT NULL, -- who did it [EventTime] [datetime] DEFAULT (getdate()) -- when did they do it ) GO
好吧,這可以解決6 個 Ws中的 3 個。
CREATE TRIGGER [trgAuditDDL] ON DATABASE FOR DDL_DATABASE_LEVEL_EVENTS AS INSERT INTO AuditDDL(EventData, EventUser) SELECT EVENTDATA(), original_login() GO
我包含一個插入語句來記錄更新檔的開頭和更新檔的結尾。更新檔之外發生的事件是需要調查的事情。
例如,“patch 17”的“begin patch”插入看起來像:
INSERT INTO [dbo].[AuditDDL] ([EventData] ,[EventUser]) VALUES ('<EVENT_INSTANCE><EventType>BEGIN PATCH 17</EventType></EVENT_INSTANCE>' ,ORIGINAL_LOGIN()) GO
由於它還會在重建索引時擷取,因此您需要每個月左右執行以下命令來清除這些事件:
DELETE FROM AuditDDL WHERE [EventData].exist('/EVENT_INSTANCE/EventType/text()[fn:contains(.,"ALTER_INDEX")]') =1 GO DELETE FROM AuditDDL WHERE [EventData].exist('/EVENT_INSTANCE/EventType/text()[fn:contains(.,"UPDATE_STATISTICS")]') =1 GO
在符合 SOX 和 PCI-DSS 的環境中,您將永遠無法訪問生產伺服器。因此,腳本需要事先明確和練習。更新腳本頂部的註釋包括新表、儲存過程、函式等的列表以及修改表、儲存過程、函式等的列表。如果數據被修改,請解釋修改的內容和原因。
第二個問題是,如果兩個單獨的任務更改同一個數據庫對象,您有時最終需要手動協調更改。這可能就是這樣,但似乎仍然應該有一些自動化的方式來“標記”這些問題或其他東西。
我從來沒有遇到過可以讓我們自動跟踪它的工具。以前的雇主使用“數據庫所有者”的原則——只有一個人親自負責數據庫。此人不會是唯一針對該數據庫工作的開發人員,而是所有更改都必須經過他們。這可以很好地防止更改相互碰撞和損壞。