微軟給咱們提供了一種很是好用的數據庫遷移方案,可是我發現周圍的同窗用的並很少,因此我仍是想把這個方案整理一下。.NET選手看過來,特別是還在經過手工執行腳原本遷移數據庫的同窗們,固然你也能夠選擇EF的Migration方案和FluentMigrator,可是下面我介紹的這種方案符合我對團隊協做的全部要求,對開發者而言使用起來很是方便,不容易犯錯。html
1、方案目標git
一個好的數據庫遷移方案在我看來須要知足如下條件:github
一、適用於每一個開發者擁有本身獨立的數據庫開發環境,用於不一樣feature的並行開發sql
二、可以配合版本控制工具,不一樣的版本可以方便合併和易於解決衝突數據庫
三、數據庫開發環境要易於在不一樣的版本之間切換app
四、易於跟CI工具集成,不一樣的開發環境(Dev,QA,Staging,Product)可以部署不一樣的數據庫開發環境工具
五、DBA可以方便審覈開發人員提交的數據庫腳本ui
六、整個數據庫的遷移過程由腳本自動化完成,不該該有人工干涉.net
2、準備命令行
假設咱們有一個數據庫blog,該數據庫中包含一個表Users,數據庫初始腳本:
Create Database Blog GO USE [Blog] GO /****** Object: Table [dbo].[Users] Script Date: 2016/7/31 17:18:09 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Users]( [Id] [int] IDENTITY(1,1) NOT NULL, [UserName] [nvarchar](200) NULL, [Email] [nvarchar](100) NULL, [Age] [int] NULL, CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
如圖所示,咱們獲得了一個初始的數據庫版本:
3、新建數據庫遷移解決方案
一、打開vs, 我用的是vs2015
二、如圖所示,新建工程
3,在Blog.Database工程,右鍵,選擇Schema Compare…
四、點擊中間的「交換位置」圖標,左邊表明源(Source),右邊表明目標(Destination)。咱們如今要本地數據庫把schema更新在咱們新建的數據庫工程中。
五、在「源」中選擇Select source
六、按照下圖所示添加數據庫鏈接
七、Compare 而後Update,數據庫中的schema將會同步在咱們的vs解決方案中
4、添加存儲過程
至此爲止咱們已經添加了對Blog數據庫的遷移方案,全部開發人員對數據庫的更改都要經過該解決方案來完成。
好比開發者A這時候須要添加第一個存儲過程:
一、在dbo目錄下新建Stored Procedures文件夾
二、新建存儲過程腳本GetUser.sql
編寫如下存儲過程:
-- ============================================= -- Author: <Author,,Name> -- Create date: <Create Date,,> -- Description: <Description,,> -- ============================================= CREATE PROCEDURE GetUser AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for procedure here SELECT TOP 100* FROM Users END
腳本已經編寫完畢,這時候開發者A須要把這個更改更新到本地的數據庫中:
這時候「源」是咱們的數據庫遷移方案,目標是本機的數據庫,compare而後update
以git爲例,開發人員此時會把Blog.Database解決方案更改合併到develop分支,其餘開發人員經過compare-update操做將別人對數據庫的更改update到本地。
5、更改表結構
開發人員B在另外一個分支須要對錶User添加兩列:Gender和Description,直接在解決方案中打開User表作更改
固然最後要經過Compare-Update操做將更改應用到本地數據庫,其餘開發人員也會經過相同的方式將此更改應用在本地。
6、添加Reference Data
開發人員添加了一個表Gender,而且須要添加三條固定數據:
在Tables文件夾下右鍵-Tabel-Gender
這時候須要添加三條固定數據:Male,Female,Unknown,這時候要用到PostDeploymentSql:
一、新建PostDeploymentSql
二、新建Gender.sql
三、(重要)此時要在Gender.sql右鍵,Builder Action-None,不然沒法編譯
四、在Gender.sql添加下面的Sql,這個sql在每次部署的時候都要執行,因此必定是「冪等」的:
PRINT 'Beginning Deployment Gender table...' IF EXISTS (select top 1 1 from dbo.Gender where Value='01') update dbo.Gender set Name='Male' where Value='01' else insert dbo.Gender(value,Name) values('01','Male') IF EXISTS (select top 1 1 from dbo.Gender where Value='02') update dbo.Gender set Name='Female' where Value='02' else insert dbo.Gender(value,Name) values('02','Female') IF EXISTS (select top 1 1 from dbo.Gender where Value='03') update dbo.Gender set Name='Unknown' where Value='03' else insert dbo.Gender(value,Name) values('03','Unknown') PRINT 'Finishing Deployment Gender table...'
五、在Script.PostDeployment.sql中編寫下面的腳本:
PRINT 'Running Post-Deploy Scripts' :r .\Gender.sql --append other sql scripts PRINT 'End Post-Deploy Scripts'
六、Compare-Update,將此更改更新到本地數據庫
此時你會發現本地數據庫添加了Gender表,可是咱們添加的三條數據並無進來,這是由於Script.PostDeployment.sql並無執行,這個腳本只有在發佈的時候才能執行。
7、添加publish文件
經過上面的步驟咱們能夠看出來,咱們每次都是先更改數據庫遷移解決方案,而後經過Compare和Update操做將更新同步到本地,可是這樣操做存在兩個缺點:
一、Script.PostDeployment.sql並無執行,沒法將ReferenceData同步在數據庫
二、只適用於同步本地數據庫,其餘環境須要採用一些自動化的方式來完成,而不是手工compare,update,避免人工操做失誤
經過下面的步驟來添加publish文件
一、在Blog.Database工程上右鍵-publish
接下來要添加數據庫鏈接,而後添加Create Profile,最後點擊publish。
經過Create Profile添加了一個xml的publish文件,重命名爲:Local.publish.xml。
咱們能夠經過雙擊此xml文件完成對本地數據庫的publish操做
8、自動化publish數據庫遷移方案到其餘數據庫環境
咱們經過手工publish將更改應用到本地,可是其餘環境(Dev,QA,Staging,Prod)則要經過腳原本完成。
一、在本地新建一個空數據庫Blog_QA用來模擬QA的數據庫環境
二、採用以前的步驟新建一個publish文件,該publish文件的數據庫爲Blog_QA,將該xml文件重命名爲:Blog_QA.publish.xml
在Blog_QA.publish.xml右鍵,屬性,Copy To Output Directory:Copy Always
三、經過sqlpackage程序要遷移數據庫
運行命令行:cd 到C:\Program Files (x86)\Microsoft SQL Server\110\DAC\bin目錄
執行命令:SqlPackage.exe /Action:Publish /SourceFile:G:\SourceCode\Blog.Database\bin\Debug\Blog.Database.dacpac
/Profile:G:\SourceCode\Blog.Database\bin\Debug\Publish\Blog_QA.publish.xml
經過編寫腳原本完成不一樣環境的數據庫遷移。
該方案的核心在於:全部開發人員經過維護vs數據庫工程來完成對數據庫的更改,最後經過publish工具來完成數據庫遷移,同時咱們能夠經過sqlpackage工具來完成自動化遷移。
整個demo提供下載:https://git.oschina.net/richieyangs/Blog.Database.git
因爲數據庫鏈接字符串的不一樣,因此不能直接使用demo中的publish文件來完成數據庫遷移。你們根據本身的狀況作出修改。