写给.NET开发者的数据Migration方案

微软给我们提供了一种非常好用的数据库迁移方案,但是我发现周围的同学用的并不多,所以我还是想把这个方案整理一下。.NET选手看过来,特别是还在通过手工执行脚本来迁移数据库的同学们,当然你也可以选择EF的Migration方案和FluentMigrator,但是下面我介绍的这种方案符合我对团队协作的所有要求,对开发者而言使用起来非常方便,不容易犯错。

一、方案目标

一个好的数据库迁移方案在我看来需要满足以下条件:

1、适用于每个开发者拥有自己独立的数据库开发环境,用于不同feature的并行开发

2、能够配合版本控制工具,不同的版本能够方便合并和易于解决冲突

3、数据库开发环境要易于在不同的版本之间切换

4、易于跟CI工具集成,不同的开发环境(Dev,QA,Staging,Product)能够部署不同的数据库开发环境

5、DBA能够方便审核开发人员提交的数据库脚本

6、整个数据库的迁移过程由脚本自动化完成,不应该有人工干涉

二、准备

假设我们有一个数据库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

如图所示,我们得到了一个初始的数据库版本:

三、新建数据库迁移解决方案

1、打开vs, 我用的是vs2015

2、如图所示,新建工程

3,在Blog.Database工程,右键,选择Schema Compare…

4、点击中间的“交换位置”图标,左边代表源(Source),右边代表目标(Destination)。我们现在要本地数据库把schema更新在我们新建的数据库工程中。

5、在“源”中选择Select source

6、按照下图所示添加数据库连接

7、Compare 然后Update,数据库中的schema将会同步在我们的vs解决方案中

四、添加存储过程

至此为止我们已经添加了对Blog数据库的迁移方案,所有开发人员对数据库的更改都要通过该解决方案来完成。

比如开发者A这时候需要添加第一个存储过程:

1、在dbo目录下新建Stored Procedures文件夹

2、新建存储过程脚本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到本地。

五、更改表结构

开发人员B在另一个分支需要对表User添加两列:Gender和Description,直接在解决方案中打开User表做更改

当然最后要通过Compare-Update操作将更改应用到本地数据库,其他开发人员也会通过相同的方式将此更改应用在本地。

六、添加Reference Data

开发人员添加了一个表Gender,并且需要添加三条固定数据:

在Tables文件夹下右键-Tabel-Gender

这时候需要添加三条固定数据:Male,Female,Unknown,这时候要用到PostDeploymentSql:

1、新建PostDeploymentSql

2、新建Gender.sql

3、(重要)此时要在Gender.sql右键,Builder Action-None,否则无法编译

4、在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...‘

5、在Script.PostDeployment.sql中编写下面的脚本:

PRINT ‘Running Post-Deploy Scripts‘
:r .\Gender.sql
--append other sql scripts 

PRINT ‘End Post-Deploy Scripts‘

6、Compare-Update,将此更改更新到本地数据库

此时你会发现本地数据库添加了Gender表,但是我们添加的三条数据并没有进来,这是因为Script.PostDeployment.sql并没有执行,这个脚本只有在发布的时候才能执行。

七、添加publish文件

通过上面的步骤我们可以看出来,我们每次都是先更改数据库迁移解决方案,然后通过Compare和Update操作将更新同步到本地,但是这样操作存在两个缺点:

1、Script.PostDeployment.sql并没有执行,无法将ReferenceData同步在数据库

2、只适用于同步本地数据库,其他环境需要采用一些自动化的方式来完成,而不是手工compare,update,避免人工操作失误

通过下面的步骤来添加publish文件

1、在Blog.Database工程上右键-publish

接下来要添加数据库连接,然后添加Create Profile,最后点击publish。

通过Create Profile添加了一个xml的publish文件,重命名为:Local.publish.xml。

我们可以通过双击此xml文件完成对本地数据库的publish操作

八、自动化publish数据库迁移方案到其他数据库环境

我们通过手工publish将更改应用到本地,但是其他环境(Dev,QA,Staging,Prod)则要通过脚本来完成。

1、在本地新建一个空数据库Blog_QA用来模拟QA的数据库环境

2、采用之前的步骤新建一个publish文件,该publish文件的数据库为Blog_QA,将该xml文件重命名为:Blog_QA.publish.xml

在Blog_QA.publish.xml右键,属性,Copy To Output Directory:Copy Always

3、通过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文件来完成数据库迁移。大家根据自己的情况做出修改。

时间: 2024-10-14 19:44:09

写给.NET开发者的数据Migration方案的相关文章

数据存储方案评估标准RDBMS or KV

作者:zhanhailiang 日期:2014-12-11 本文主要介绍常见的数据存储方案及相应选型的评估标准的介绍. Guideline:针对不同应用场景,针对性选择存储方式. 1. 数据存储方案 SQL: MySQL 5.5/5.6/MariaDB(对于Dev绝大多数场景下透明): Oracle|MS SQL暂不考虑: NoSQL: Memcached 1.4.21: Redis 2.8: MongoDB 2.6.6: Hbase 0.96/0.98: 2. 评估标准 RDBMS:(MySQ

Android Learning:数据存储方案归纳与总结

前言 最近在学习<第一行android代码>和<疯狂android讲义>,我的感触是Android应用的本质其实就是数据的处理,包括数据的接收,存储,处理以及显示,我想针对这几环分别写一篇博客,记得我的学习心得,也希望跟各位新手同学相互努力促进.今天这篇博客,我想介绍一下数据的存储,因为数据的接收,存储,处理以及显示这几环环环相扣,而数据的存储直接关系到数据的处理和显示,所以显得尤为重要. 所以本文针对数据存储的常见方案和其使用进行了归纳.分为程序内存储和程序间数据访问,程序内存储

数据缓存方案

数据缓存方案 by 伍雪颖 今天考虑一个适合自己项目的缓存方案,基本都实验了下(以前一直用CoreData) 1.coredata,用MagicalRecord+Mogenerator 要建表,还要写好多解析代码,果断不用,好麻烦 2.序列化 [NSKeyedArchiver archiveRootObject:model toFile:path]; [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 好方便,不过总感觉体验不好,测了下方法时间,当

基于文件的离线数据同步方案

产品此前的数据备份方案,存在不少问题,所以需要设计一个新的方案.本文总结一下新旧方案的优劣 首先APP是一个支持离线的应用.本地数据保存在sqlite,在离线环境下,在本地数据库里读写记录,在有网络的时候,再将数据备份到服务器:同时,也可以随时将数据从服务器恢复到本地 旧方案 此前的备份方案是基于内容的,每一条记录都有create_date和modify_date字段,同时APP保存有latest_backup_date(上次备份时间).然后开始备份的时候,就对所有表进行扫描,根据这3个时间的对

报表填报--数据提交方案

在开发基于web的数据填报模块时,总是会遇到数据的提交方案.提交方案的复杂程度,取决于输入页面的复杂程度.最简单的一个页面一条记录,对应数据库的一张物理表:复杂点的多条记录,但是依旧对应数据库的一张物理表:再复杂些的,对应数据库多张物理表:最复杂的,估计要数多库提交了. 我们在数据提交方案不管多复杂,最基本的要求是保持数据库的事务一致性.事务一致性对单库说起来挺容易的,但是对多个数据库的情况就很难实现了. 其次,是对数据类型的处理,网页上提交上来的数据是无法识别录入的数据类型的,因此需要在后台对

大规模IM在线用户的计算和数据存储方案

简单的计算模型 1.如果一秒钟处理1000笔请求(每条都进行存储),那么一天的数据量是:24*60*60*1000=8640万:如果每秒1万笔的话,数据大概是8.64亿 2.行业里一般的统计方法是峰值是日活量的五分之一,日活是总用户的8%.按照,按照峰值1万来进行计算的话,总的用户数是: 1万*5/0.08=62.5万,另外付费用户占总用户一般在5%左右,具体看运营情况. 3.日活跃用户产生峰值的计算:一般的消息类的,大概能到0.5%到1%就不错(一秒钟同时发出,网络游戏可能有点不一样,会高一点

sql server数据同步方案-日志传送

1 功能描述 本方案采用日志传送模式,把核心数据库(主数据库)定期同步到灾备数据库(辅助服务器)及备份库(辅助服务器,便于其他系统使用,减轻主数据压力),期间,如果发生异常导致无法同步,将以电子邮件.短信方式通知管理人员. 2 系统环境 2.1硬件 主数据库: SQLHA 灾备库服务器:DisaterDBSVRA 备份库服务器:BackupDataSVR 2.2软件 主数据库: Win2008 x64 SQL2005 SP4 x64 灾备库: Win2008 x64 SQL2005 SP4 x6

混合云存储组合拳:基于云存储网关与混合云备份的OSS数据备份方案

前言阿里云对象存储(OSS)用户众多.很多用户因为业务或者合规性需求,需要对OSS内的数据做备份,无论是线上备份,还是线下备份.用户可以选择使用OSS的开放API,按照业务需求,做数据的备份,也可以选择OSS已有的服务进行数据备份,比如OSS的跨域复制.但是,前一种方式,存在易用性和备份效率问题:后一种方式,只是将数据存双份或者多份,无法有效规避原始数据出问题后,被复制的那份数据也出问题的风险.本文介绍的基于云存储网关和混合云备份的OSS数据备份方案,不仅能保证OSS数据按策略的多版本备份,而且

saas系统多租户数据隔离的实现(一)数据隔离方案

0. 前言 前几天跟朋友聚会的时候,朋友说他们公司准备自己搞一套saas系统,以实现多个第三方平台的业务接入需求.聊完以后,实在手痒难耐,于是花了两天时间自己实现了两个saas系统多租户数据隔离实现方案.俗话说“独乐乐不如众乐乐”,所以我把我的“研究成果”写出来,让大家乐呵乐呵. 在分享我的研究成果之前,我们先了解一下相关的定义吧.如果对这部分内容熟悉的同学,可以直接略过. 1. 什么是saas系统 引用百度百科上面的描述, “SaaS平台是运营saas软件的平台.SaaS提供商为企业搭建信息化