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

一、方案目标

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

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

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

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

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

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

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

二、准备

假设我们有一个数据库blog,该数据库中包含一个表Users,数据库初始脚本:

Create Database Blog
GOUSE [Blog]
GO/****** Object:  Table [dbo].[Users]    Script Date: 2016/7/31 17:18:09 ******/
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GOCREATE 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 hereSELECT 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'
elseinsert 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'
elseinsert 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'
elseinsert 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文件来完成数据库迁移。大家根据自己的情况做出修改。

转载于:https://www.cnblogs.com/richieyang/p/5723644.html

写给.NET开发者的数据库Migration方案相关推荐

  1. 数据库设计 读多写少、写多读少、写多读多各场景数据库建设方案

    数据库建设方案 读多写少 写多读少 写多读多 数据库集群方案优缺点 读多写少 解决方案:采用传统关系型数据库足以应对,若并发量很大,采用mysql集群即可应对! 写多读少 1.业务场景:滴滴.饭堂刷卡 ...

  2. 如何彻底解决烦人的 MySQL 分库分表问题?写一个更好的数据库!

    作者 | 黄东旭 责编 | 郭   芮 我还清楚记得,五年前的这个时候,当时还在豌豆荚,午后与刘奇和崔秋的闲聊关于未来数据库的想象,就像一粒种子一样,到了今天看起来也竟枝繁叶茂郁郁葱葱,有点感慨.按照 ...

  3. php语+言教程,写给thinkphp开发者的laravel系列教程(九)打印数据-Fun言

    php这种脚本语言调试起来是很方便的: 大多时候看报错打印一下数据就知道问题所在了: php 内置了常用打印函数 print 和 var_dump : 但是打印出来的样式实在让人目瞪狗呆: think ...

  4. 数据库性能测试方案示例

    前言 :   究竟怎样进行数据库性能测试,数据库性能测试需要做些什么?大多数产品线的RD和QA也比较迷茫,经常过来咨询.   一般说来,做数据库性能测试需要如下几个步骤: 1:明确测试目的 2:设计测 ...

  5. 常用数据库优化方案(三)

    特别鸣谢:http://blog.csdn.net/zhushuai1221/article/details/51740846 一.百万级数据库优化方案 1.对查询进行优化,要尽量避免全表扫描,首先应 ...

  6. SQL Server数据库优化方案

    SQL Server数据库优化方案 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计 ...

  7. 架构组件:基于Shard-Jdbc分库分表,数据库扩容方案

    架构组件:基于Shard-Jdbc分库分表,数据库扩容方案 一.数据库扩容 1.业务场景 互联网项目中有很多"数据量大,业务复杂度高,需要分库分表"的业务场景. 这样分层的架构 ( ...

  8. python语言的开发者_写给.NET开发者的Python教程(一):引言

    距离上一篇博文已过去8个月了,这段时间发生了很多事情导致没能持续更新博客.这段时间除了工作繁忙,业余时间都投入到AI技术的学习中,后面一段时间将会给大家分享我作为一个.NET开发人员在深度学习领域学习 ...

  9. 企业级MySQL数据库备份方案:增量备份、全量备份、逻辑备份

    一份好的备份方案无非包括以下几点: 为什么需要备份? 备份的方式有哪些? 某几种备份方式的区别在哪? 备份实战操作概述 恢复实战操作概述 其它备注信息 那么,此文将从以上几个角度,结合一些实际的实战经 ...

  10. mysql数据库性能测试实例_数据库性能测试方案示例

    究竟怎样进行数据库性能测试,数据库性能测试需要做些什么?大多数产品线的RD和QA也比较迷茫,经常过来咨询. 一般说来,做数据库性能测试需要如下几个步骤: 1:明确测试目的 2:设计测试模型 (即压力模 ...

最新文章

  1. XSL 扩展样式表语言(EXtensible Stylesheet Language)
  2. Android中文API(115)——AudioFormat
  3. 到2026年,非洲数据中心市场规模将达到50亿美元
  4. matlab拟合函数,Matlab拟合自定义函数 - 计算模拟 - 小木虫 - 学术 科研 互动社区...
  5. 如何提高后台服务应用问题的排查效率?日志 VS 远程调试
  6. python制作考试系统_Python系统学习 - Pytest单元测试框架
  7. mysql jion 三张_mysql三张表 left join
  8. 30分钟轻松入门Spring MVC
  9. WCF添加服务失败一则
  10. 展示360度全景影像的利器--PanoramaGL
  11. android 汉字 转 拼音首字母,Android开发之拼音转换工具类PinyinUtils示例
  12. 无线网络安全与解决方案(Wireless Security)
  13. 2022软工K班结对编程任务
  14. 计算机初级程序员哪里颁发的,初级程序员证书怎么考_初级程序员证书考什么_上学吧...
  15. APP微信登录后端PHP,PHP开发微信授权登录教程
  16. 【企业开源】小米开源:站在巨人肩膀上的创新
  17. ICP许可证的作用是什么?ICP许可证可以转让吗?
  18. 设计模式实例学习-策略模式
  19. 开发微信小程序,就是这么简单!可自动生成微信小程序源代码,配套JS SDK、接口和后台
  20. 插槽+生命周期+过滤器

热门文章

  1. 【项目分析】利用J#类库解决项目中数据压缩以及解压的问题
  2. 操作WORD配置说明
  3. 【提前批】22届的同学看过来,百度提前批开始啦~
  4. 这些神经网络调参细节,你都了解了吗
  5. 梯度消失与梯度爆炸----解决方案(一)
  6. 筹备两年,60万字诚意续作《腾讯游戏开发精粹Ⅱ》正式发布
  7. 如何成为一名合格的CRUD工程师?
  8. 我用过了TensorFlow、PyTorch等好几种框架,为什么还是吃不透深度学习算法?
  9. python函数 - 函数创建、属性、参数及偏函数
  10. ARM 指令集 比较指令