不要做。现在做。
TLDR:现在(而不是稍后)编写(和测试)您的数据库脚本;只需对它们进行编码,以便其执行取决于数据库版本。
例
例如,假设您希望将列名从更改SSN
为TaxID
,这是国际化时的常见要求。
为了实现这一点,也许您会暂时拥有a TaxID
和一SSN
列。同时支持两个版本时,您将具有一个触发器来相互更新。但是您不希望无限期地保持该触发器,因此,稍后,当不再需要向后兼容时,您希望该触发器被删除(SSN
列被删除)。我们将在不需要ToDo项的情况下预先编写所有代码。
在我们的示例中,我们将部署版本102(具有新列),同时保持与版本101(不具有)的兼容性。
步骤如下。
1.设置版本表
添加称为一个表Configuration
有两列,Name
和Value
。
添加带有Name
“ TargetVersion” 的行,并将设置Value
为要部署的新版本的版本。
添加带有Name
“ CompatibleWith” 的行,并将设置为Value
与部署必须兼容的最低版本号。
每次部署之前,请检查并更新这些行。
2.修改部署脚本
添加一个脚本,该脚本创建一个新的列TaxID
,与并排放置SSN
,并从SSN
列中填充它。将此代码放在If
检查TargetVersion 的语句中;如果目标版本太低(即TaxID
不需要),请跳过。
SELECT @TargetVersion = TargetVersion FROM Configuration
IF @TargetVersion < '102' THEN RETURN
ALTER TABLE Customer ADD COLUMN taxID VarChar(12) NOT NULL
UPDATE Customer SET TaxID = SSN
添加一个脚本,该脚本创建一个TaxID
在插入或更新时填充的触发器,SSN
反之亦然。将此代码括在If
检查目标版本和兼容版本的语句中。如果TargetVersion太低(TaxID
不需要)或CompatibleWith版本太高(SSN
不需要字段),则跳过。
SELECT @TargetVersion = TargetVersion,
@CompatibleWith = CompatibleWith
FROM Configuration
IF @TargetVersion < '102' THEN RETURN
IF @CompatibleWith > '101' THEN RETURN
CREATE TRIGGER SSNAndTaxIDTrigger ON Customer etc.
添加脚本以删除该SSN
列。If
仅在CompatibleWith版本足够高(SSN
不再需要)时,才使用封闭该语句的语句。
SELECT @CompatibleWith = CompatibleWith FROM Configuration
IF @CompatibleWith <= '101' THEN RETURN
IF OBJECT_ID('SSNAndTaxIDTrigger') IS NOT NULL DROP TRIGGER SSNAndTaxIDTrigger
IF EXISTS (SELECT * FROM syscolumns c JOIN sysobject o ON o.id = c.is WHERE o.Name = 'Custeomr' AND c.Name = 'SSN') BEGIN
ALTER TABLE Customer DROP COLUMN SSN
END
3.测试
确保使用希望在生产中支持的蓝色/绿色版本号的任意组合来测试您的部署。通过Configuration
在QA环境中操作表格,您可以在代码准备就绪后立即进行测试。
4.在您的部署手册中
为工程师添加一个步骤以更新CompatibleWith版本和TargetVersion行。如果要部署到Blue,请将TargetVersion设置为Blue的版本号,并将CompatibleWith版本设置为Green的版本号;如果您要部署Green,则将其反转。
陷阱
您的部署脚本可以引用并依赖该数据库表中保存的那些版本号是可以的。不是运行时代码。
如果您开始编写运行时代码以检查版本号,那么您将在应用程序中引入新的复杂性水平,这可能会成为一个巨大的可维护性问题。每个运行时执行路径都必须经过测试;如果您继续解决这些问题,则质量检查人员必须将痛苦矩阵汇总在一起,以便每次发布时都可以对其进行验证。我的建议是仅将此类条件保留在部署脚本中。
所有这一切的结果
最后,您应该能够预先编写所有代码(并对其进行测试),而不必担心它执行得太早。同样,该代码将在时间到来时清除向后兼容触发器,而无需您进一步担心。
这样,您就可以在考虑时预先编写和测试所有代码,而无需处理那些凌乱的ToDo注释。