这篇日志记录一下我在公司所学习到的数据库安装包的设计。正好这些内容也是我最近工作遇到的一些问题,在此记录并分享一下。
在产品的开发和版本更新过程中,数据库的结构难免会一直发生变化。为了尽量减少升级时的工作量,设计一个好的数据库升级方式就显得很重要。在设计数据库安装包时,既要考虑到全新安装时如何生成默认数据,也要考虑从老版本升级时旧的数据如何迁移如有必要)。
基本上,安装包可以分成三个部分:Pre-script,数据库安装或升级和Post-script。
一、数据库安装或升级
首先,我们使用到的是Red Gate工具。这个工具会自动比较现有数据库和目标数据库在结构上的差异,并自动生成一个脚本进行升级(实际上是执行一连串的SQL语句)。这是个很好的工具,推荐使用(好像要收钱),可以减少很多的工作量。
如果Red Gate发现目标表在旧版本的数据库不存在,它会自动创建这个表并设置好主键、外键和其他约束。这个没什么要说的。
如果目标表已经存在,那么就会对原有的表进行更新,在此要特别注意要更改的表结构如何变化。举个例子:
我们原来有一张UserParameter表,结构如下:
现在,我们希望增加一个ParameterType字段,与UserId字段构成联合主键:
此时,如果旧版本的数据库有数据,在升级过程中添加新字段后由于ParameterType为空,会导致表的结构修改失败,这样安装包就会出错。
解决方法是为这个字段加一个默认值。一般做法是在数据库项目的Schema Objects – Tables – Contraints下加一个Default Constraint的约束:
ADD CONSTRAINT [DF_UserParameters_Type]
DEFAULT N’SU’
FOR [ParameterType]
二、Pre-script和Post-script
一般来说,大部分数据表的结构变化都可以又RedGate自动完成,我们要做的只是注意设置好默认值即可。但还有一些其他情况需要自行书写脚本来完成,这里举几个例子。
1.默认数据
默认数据是在数据库创建完后加上的。我们可以在Post-script中加一个名为DefaultData.sql的脚本,范例如下:
SET XACT_ABORT ON
BEGIN TRANSACTION
— New default for FloorAlertOrder
IF NOT EXISTS (SELECT 1 FROM TMS.[FloorAlertOrder] WHERE [ModeId] = 1 and [TypeId] = 7)
INSERT INTO [TMS].[FloorAlertOrder] ([TypeId], [Ordinal], [ModeId]) VALUES (7, 10, 1)
— TMS.User
IF NOT EXISTS (SELECT 1 from [TMS].[User] where XRef = ‘Host’)
INSERT INTO [TMS].[User]
([Active]
,[XRef]
,[LastName]
,[FirstName]
,[UserName]
,[CreationTime]
,[Dealer]
,[CasinoHost]
,[DomainName]
,[CMSUserName])
VALUES
(1
,’Host’
,’Host’
,’Host’
,’Host’
,GETUTCDATE()
,0
,0
,’Host’
,’Host’)
COMMIT TRANSACTION
GO
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/236691.html