2010-05-05 61 views
12

關於SQL的版本控制和網絡上的大量資源,有幾個問題,但我找不到能夠完全涵蓋我想要做的事情。SQL版本控制方法

首先,我在這裏討論一種方法。我熟悉各種源代碼控制應用程序,並且我熟悉像Red Gate的SQL Compare等工具,並且我知道如何編寫應用程序來自動檢查源代碼控制系統中的內容。如果有一種工具對於提供全新的方法或者具有有用和不常見的功能非常有幫助,但對於上面提到的任務,我已經設置好了。

,我試圖滿足的要求是:

  • 數據庫架構和查表數據版本
  • 數據修復DML腳本,以更大的表版本
  • 服務器可以從版本N升級到版本N + X,其中X可能並不總是爲1
  • 代碼在版本控制系統中不重複 - 例如,如果我向表中添加一列不想擁有以確保更改同時存在於創建腳本和更改scr中IPT
  • 系統需要支持多個客戶端誰在各種版本的應用程序(試圖它們加起來得到在1個或2個版本,但是現在還沒有)

一些組織保持增量變化腳本在他們的版本控制中,並且從版本N到N + 3,您必須運行N> N + 1然後N + 1→N + 2然後N + 2→N + 3的腳本。其中一些腳本可能是重複的(例如,添加了一個列,但之後它被更改爲更改數據類型)。我們試圖避免這種重複性,因爲一些客戶端數據庫可能非常大,所以這些更改可能需要的時間超過必要的時間。

一些組織只會在每個版本級別上保留一個完整的數據庫構建腳本,然後使用像SQL Compare這樣的工具將數據庫引入其中一個版本。這裏的問題是混合DML腳本可能是一個問題。設想一種場景,我添加一列,使用DML腳本填充所述列,然後在更高版本中更改列名稱。

也許有一些混合解決方案?也許我只是要求太多?任何想法或建議將不勝感激。

如果主持人認爲這將作爲社區wiki更合適,請告訴我。

謝謝!

+2

不知道你是否看到這一個,但我得到了一些合理的答案:http://stackoverflow.com/questions/2401229/database-structure-and-source-control-best-practice – Paddy 2010-05-05 15:31:30

+1

這是否有幫助? http://msmvps.com/blogs/deborahk/archive/2010/05/02/vs-2010-database-project-an-introduction.aspx請注意,文章底部有更多鏈接。 – 2010-05-05 15:33:27

+0

@Paddy - 感謝您的鏈接。 pdc有一個很好的解決方案,與我們正在考慮的解決方案相匹配,但腳本創建任務被外包給印度(不是我的選擇),而且其專業知識有限,因此一些更復雜的代碼可能會成爲問題。儘管如此,它仍然在桌面上。 – 2010-05-05 16:27:21

回答

4

最近我採取了一項似乎工作得很好的策略之前,我爲此奮鬥了好幾年。我生活的關鍵點:

  • 數據庫並不需要從應用程序
  • 所有數據庫更新腳本應該是冪等

。其結果是獨立版本,我不再產生任何版本表的種類。我只需將更改添加到可在任何給定時間應用而不會損壞數據庫的.sql文件的編號序列中。如果它使事情變得簡單,我將爲應用程序編寫一個簡單的安裝程序屏幕,以便管理員隨時運行這些腳本。

當然,這種方法確實強加在數據庫設計的幾個要求:

  • 所有架構更改通過腳本完成的 - 沒有圖形用戶界面的工作。
  • 必須格外小心,以確保所有鍵,約束等都被命名,以便在必要時可以通過稍後的更新腳本來引用它們。
  • 所有更新腳本都應檢查現有條件。從最近的一個項目

例子:

001.sql:

if object_id(N'dbo.Registrations') is null 
begin 
    create table dbo.Registrations 
    (
     [Id]     uniqueidentifier not null, 
     [SourceA]    nvarchar(50)  null, 
     [SourceB]    nvarchar(50)  null, 
     [Title]     nvarchar(50)  not null, 
     [Occupation]   nvarchar(50)  not null, 
     [EmailAddress]   nvarchar(100) not null, 
     [FirstName]    nvarchar(50)  not null, 
     [LastName]    nvarchar(50)  not null, 
     [ClinicName]   nvarchar(200) not null, 
     [ClinicAddress]   nvarchar(50)  not null, 
     [ClinicCity]   nvarchar(50)  not null, 
     [ClinicState]   nchar(2)   not null, 
     [ClinicPostal]   nvarchar(10)  not null, 
     [ClinicPhoneNumber]  nvarchar(10)  not null, 
     [ClinicPhoneExtension] nvarchar(10)  not null, 
     [ClinicFaxNumber]  nvarchar(10)  not null, 
     [NumberOfVets]   int    not null, 
     [IpAddress]    nvarchar(20)  not null, 
     [MailOptIn]    bit    not null, 
     [EmailOptIn]   bit    not null, 
     [Created]    datetime   not null, 
     [Modified]    datetime   not null, 
     [Deleted]    datetime   null 
    ); 
end 

if not exists(select 1 from information_schema.table_constraints where constraint_name = 'pk_registrations') 
    alter table dbo.Registrations add 
     constraint pk_registrations primary key nonclustered (Id); 

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_created') 
    create clustered index ix_registrations_created 
     on dbo.Registrations(Created); 

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_email') 
    create index ix_registrations_email 
     on dbo.Registrations(EmailAddress); 

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_email') 
    create index ix_registrations_name_and_clinic 
     on dbo.Registrations (FirstName, 
           LastName, 
           ClinicName); 

002.sql

/********************************************************************** 
    The original schema allowed null for these columns, but we don't want 
    that, so update existing nulls and change the columns to disallow 
    null values 
*********************************************************************/ 

update dbo.Registrations set SourceA = '' where SourceA is null; 
update dbo.Registrations set SourceB = '' where SourceB is null; 
alter table dbo.Registrations alter column SourceA nvarchar(50) not null; 
alter table dbo.Registrations alter column SourceB nvarchar(50) not null; 

/********************************************************************** 
    The client wanted to modify the signup form to include a fax opt-in 
*********************************************************************/ 

if not exists 
(
    select 1 
     from information_schema.columns 
    where table_schema = 'dbo' 
     and table_name = 'Registrations' 
     and column_name = 'FaxOptIn' 
) 
alter table dbo.Registrations 
    add FaxOptIn bit null 
     constraint df_registrations_faxoptin default 0; 

003.sql,004.sql等..

在任何給定的時間,我都可以針對數據庫運行整個系列腳本在任何狀態下都可以使用,並且知道使用當前版本的應用程序立即可以加快速度。因爲一切都是腳本化的,所以構建一個簡單的安裝程序來執行此操作會更容易,並且它將架構更改添加到源代碼管理中根本沒有問題。

+0

謝謝。這與Paddy鏈接中發佈的「pdc」類似。這是我過去一天試圖出售的東西。這裏的一些人仍然與帶有額外元數據的模型數據庫的想法聯繫在一起,然後使用比較工具以及其他元數據,但也許我可以控制它們。實際上,我的方法仍然儘可能地將單個對象的腳本保存在一個文件中,並且在文件中發生新變化而不是不斷添加新腳本。在版本之間訂購是唯一的挑戰,我想我也有一個解決方案。 – 2010-05-06 19:44:39

3

你已經有了一個相當嚴格一套要求,我不知道你是否會找到一些東西,把所有的盒子裏的支票,特別是特別是多個併發模式和智能版本控制。

我讀過的最有前途的工具是Liquibase
這裏有一些額外的鏈接:

+0

感謝您的建議。是的,絕對是一個苛刻的要求清單,但我很有希望:)我會看看LiquiBase可以做什麼。 – 2010-05-05 17:02:25

2

是的,你問了很多,但他們都真的很中肯點!在Red Gate,我們正在朝着一個完整的數據庫開發解決方案和我們的SQL Source Control SSMS擴展方向發展,同時我們面臨着類似的挑戰。

http://www.red-gate.com/products/SQL_Source_Control/index.htm

對於即將到來的版本中,我們會全力支持架構更改,並通過我們的SQL數據間接支持靜態數據比較工具。所有更改都保存爲創建腳本,但當您更新或部署到數據庫時,該工具將確保將更改適當地應用爲ALTER或CREATE。

尚未擁有簡單解決方案的最具挑戰性的要求是版本管理和部署,這些描述非常清晰。如果您對模式和數據進行了複雜的更改,則可能不可避免地會構建手動遷移腳本以在兩個相鄰版本之間進行訪問,因爲並非所有的「意圖」都始終與新版本一起保存。列重命名是一個很好的例子。解決方案可能是設計一個可以保存意圖的系統,或者如果這太複雜,則允許用戶提供自定義腳本來執行復雜的更改。某種版本管理框架可以管理這些並且從兩個任意版本「神奇地」構建部署腳本。

1

我們正在使用SQL Examiner在版本控制下保持數據庫模式。我也嘗試過VS2010,但在我看來,VS方法對於中小型項目來說過於複雜。有了SQL Examiner,我主要使用SSMS並使用SQL Examiner來檢查SVN的更新(TFS和SourceSafe也支持,但我從未嘗試過)。

這裏是SQL考官的做法的描述:How to get your database under version control

+0

感謝您的建議。不幸的是,這隻適用於將腳本引入源代碼管理系統。我的問題是在部署時 - 使處於不同版本軟件上的許多客戶端實現自動化。 – 2010-05-12 17:03:51

+0

SQL Examiner將存儲在SVN中的數據庫腳本與目標數據庫進行比較,並生成模式遷移腳本。另外,您可以將SVN中的版本10與SVN中的版本12進行比較,並生成腳本以將架構從版本10遷移到版本12。 – SQLDev 2010-05-12 17:23:18

0

嘗試DBSourceTools。 (http://dbsourcetools.codeplex.com
它的開放源代碼,特別設計用於腳本化整個數據庫 - 表,視圖,過程到磁盤,然後通過部署目標重新創建該數據庫。
您可以編寫所有數據的腳本,或者只指定要爲其編寫數據的表。
此外,您可以壓縮分發結果。
我們使用它來控制數據庫的源代碼,並測試新版本的更新補丁。
在後端它是圍繞SMO構建的,因此支持SQL 2000,2005和2008.
DBDiff已集成,以允許進行模式比較。
玩得開心, - Nathan。