2012-04-17 60 views
15

我有一個應用程序,將部署在具有SQL Server的生產型PC上。 我希望能夠在我的數據庫中存儲和檢索架構的一個版本。 我感興趣的最佳實踐,能夠做到這一點,有以下主要目標:在SQL Server中存儲數據庫模式版本的最佳實踐?

  1. 能夠存儲和方便地檢索數據庫的版本號。
  2. 被客戶隱藏或更難找到和操縱。
  3. 能夠在我們創建新版本時進行編輯/更改。
  4. 備份數據庫或刪除數據庫將保留用於取證的版本#。

我希望有一種方法可以在元數據中存儲「版本」,或者不是可以通過系統存儲過程訪問/設置的普通表。

任何想法或最佳實踐?

編輯:我發現可能有前途的一個選項是使用SQL Server擴展屬性,將鍵值分配給數據庫的「Schema_Version」和版本號。它沒有加密(但值可能),並沒有隱藏,但至少從我們的一些用戶和現場工作人員瀏覽的實際DB結構中刪除(對我的沮喪!:))

+1

爲什麼你會在意,如果客戶端可以訪問的領域?如果他們直接編輯它,是不是隻會弄亂應用程序,然後這將是他們自己的錯誤? – mellamokb 2012-04-17 18:32:02

+0

@mellamokb - 偉大的標註,但我們需要這特別是因爲在現場人們正在做的是:與數據庫搞混。我們希望這是用於法醫調查,因此隱藏它(例如在SQL元數據中)只會降低更改的可能性。 – pearcewg 2013-01-31 21:46:07

+2

@pearcewg如果你想取證,那麼你步入安全領域,然後你就錯過與你的需求點。你不應該試圖保護那些擁有它的人的數據庫 - 這就是所謂的「過度保護設計」。如果你覺得真的很深,你會發現絕對沒有辦法讓你知道一個有SA密碼的人是否搞亂了數據庫。這就是整個問題。讓解決方案「更難以找到和操縱」只會讓你在沒有時感到受到保護。 – 2013-05-14 12:30:57

回答

17

我是Red Gate的SQL Source Control和SQL Compare的產品經理。我們必須解決這個問題,因爲我們的工具需要知道數據庫處於哪個版本才能選擇適當的遷移腳本來構建完整的部署腳本。

我們考慮了一個版本表,這是最常見的自制解決方案。但是,從我們的研究中,我們瞭解到用戶希望保持數據庫對象的「未受污染」,因此我們選擇了數據庫級擴展屬性。我們把這段腳本如下:

IF EXISTS (SELECT 1 FROM fn_listextendedproperty(N'SQLSourceControl Database Revision', NULL, NULL, NULL, NULL, NULL, NULL)) 
    EXEC sp_dropextendedproperty N'SQLSourceControl Database Revision', NULL, NULL, NULL, NULL, NULL, NULL 
EXEC sp_addextendedproperty N'SQLSourceControl Database Revision', @RG_SC_VERSION, NULL, NULL, NULL, NULL, NULL, NULL 

當數據庫被加載到SQL比較,它執行檢查,以確保它聲稱的版本是對應於版本存儲在源代碼控制。

希望這會有所幫助!

+0

大衛:這是一個很好的答案,基本上是我想爲更多的研究後的解決方案。謝謝! – pearcewg 2012-04-18 12:59:58

+0

沒問題。很高興幫助!當然,這並不妨礙客戶端對數據庫進行更改,這會使其與您標記的版本號不一致。這被稱爲數據庫漂移,是一個相當普遍的問題。 – 2012-04-18 19:37:09

5

實際上,我們只存儲每個數據庫的架構編號。我們在數據庫中有一張表格,僅供軟件配置管理團隊使用,該表格告訴我們當前的版本,以便我們可以快速地查看各種環境的版本。我不會擔心把它放在db之外的地方,因爲這隻會讓事情變得複雜。

我想如果你真的想要安全,你總是可以創建一個存儲過程,其硬編碼值。然後,您可以加密存儲過程,以便在您不知情的情況下無法查看/篡改存儲過程。您可以在更改sp時更新sp。編譯後,您也可以進入系統並從系統表中刪除存儲過程代碼,但我真的不會這樣做。它只會導致問題。

1

我在以前的公司做過的是將表格存儲在一個包含幾個字段(主要版本,次要版本,構建和日期應用)的表中,以便我可以獲得更新的歷史記錄。在表上設置適當的權限足以防止篡改。

如果你真的想讓DBA難以閱讀,可以將這些值作爲加密字符串存儲在表中。這種方式只有你現在如何解碼它們。

5

,我實現了基於跟蹤四段架構版本(主要,次要,建立,修訂版)與時間戳時,每一個版本的開頭和結尾的有效性一個表中的解決方案。只有一行具有用於結束時間戳的NULL,並且這是當前版本。

此外,還有一堆支持此版本控制系統的存儲過程,並且所有數據庫更改必須在它們對數據庫模式進行任何更改時立即測試和更新模式版本(例如,添加一個表,刪除一列等)。

注意變化的完整歷史記錄存儲在跟蹤數據庫版本表。出現問題時,解決方案非常靈活。例如,如果在執行過程中發生更改中斷,則成功完成的所有更改都會記錄在版本表中,因爲在每一步之後都會增加修訂版本號。您可以改進alter並再次運行,它會自動跳過成功完成的步驟,並繼續執行上一次沒有做的第一步。

還有一個(選配)招 - 我用奇怪的版本號爲中間版本,甚至搭建完成的版本號。這樣,一旦開始更改,它會首先將內部版本號更改爲下一個奇數值,然後執行所需內容。如果在任何時候你看到一個奇怪的版本號(版本號中的第三段),那麼你肯定有一些修改沒有完成!一旦修改完成了最後一步,它只需再次更改模式版本,這次是下一個偶數內部版本號,只是爲了通知大家它已完成。

您可以查看整個源代碼,用戶手冊和例子在這篇文章中:How to Maintain SQL Server Database Schema Version

+0

我喜歡使用奇數來表示正在進行數據庫升級的想法。 – 2015-04-01 23:33:34