编辑:更多有关使用双向触发器同步的解释;更新了语法、语言和清晰度。
前言
我在一家大型网络应用程序上工作了7年,面临着类似的数据模型升级问题,所以我理解你的困境。基于这种经验,我提出了一些有点不同但希望更容易实施的建议。首先,有一个观察:
对于组织而言,价值在于数据——数据将长时间存在,超越所有当前应用程序的生命周期。企业将不断发明新方法来从捕获的数据中获取价值,这将产生新的报告、应用程序和业务方式。
因此,正确地获取新的数据结构应该是最重要的目标。不要为了其他短期开发目标(特别是以下内容)而牺牲获取正确的结构:
- 操作性目标,如推出新服务
- 报告性能(使用材料化视图、触发器或批处理作业替代)
这个结构会随着时间的推移而改变,因此您的架构必须允许频繁添加和不经常正常化它。这意味着您的数据结构和任何共享的API(包括RESTful服务)必须得到适当的版本控制。
为什么使用RESTful Web服务?
你提到你将“将所有功能移动到RESTful服务中,以便没有应用程序可以直接访问数据库”。我需要就传统应用程序提出一个非常重要的问题:这很重要吗?它带来了什么价值?
我之所以这样问,是因为:
- 您失去了ACID事务(除非您实现一些可怕复杂的WS-*标准,否则每个调用都是单个事务)
- 性能下降:直接连接数据库将更快(没有Web服务器工作和翻译需要),并且延迟较小(通常为1ms而不是50-100ms),这将显著地降低应用程序对直接DB连接编写的响应性
- 数据库结构并没有从RESTful服务中抽象出来,因为您承认随着数据库规范化,您必须重新编写Web服务并重写调用它们的应用程序。
而其他交叉关注点则没有改变:
- 可管理性: 直接数据库连接可通过许多通用工具进行监控和管理
- 安全性: 直接连接比您的开发人员编写的 Web 服务更安全
- 授权: 数据库权限模型非常先进,可以细致到你想要的程度
- 可扩展性: Web 服务是一个(仅有的?)直接连接的数据库应用程序,因此只能像数据库一样进行扩展
您可以通过维护遗留 RESTful API 来迁移数据库并保持遗留应用程序运行。但是,如果我们不引入“遗留”RESTful服务,而是保持遗留应用程序呢。
数据库版本控制
假设大部分“遗留”应用程序使用 SQL 直接访问数据表; 您可能还有许多数据库视图。
一种数据迁移方法是:新数据库(以新架构中的新范式结构为基础)将旧结构作为< strong>视图 向遗留应用程序呈现,通常来自不同的模式。
实际上这很容易实现,但仅解决报告和只读功能。那么遗留应用程序 DML 呢?DML 可以使用以下方式解决:
- 可更新视图用于简单转换
- 引入存储过程(如果不支持可更新视图)(例如 "CALL insert_emp(?, ?, ?)" 而不是 "INSERT INTO EMP (col1, col2, col3) VALUES (?, ? ?)")
- 使用触发器和 DB 链接具有与新数据库同步的“遗留”表
具有双向同步功能的遗留格式表,使用触发器与新格式表进行同步是一种粗暴的解决方案,相对丑陋。您最终会在两个不同的模式(或数据库)中拥有相同的数据,并且如果同步代码存在错误,则可能导致数据不同步 - 然后您就会面临“两个主人”的经典问题。因此,请将其视为最后的手段,例如当:
- 基本结构已更改(例如更改关系的基数),或
- 将数据转换为旧版格式是一个复杂的函数(例如,如果旧版列是新格式列值的平方并设置为“4”,可更新的视图无法确定正确值是+2还是-2)。
当需要对数据进行这种更改时,代码和逻辑会有一些重大变化。您可以实现兼容性层(优点:不更改旧代码)或更改旧应用程序(优点:数据层干净)。这是工程团队的技术决策。
使用上述方法创建遗留结构的兼容性数据库可最大限度地减少对旧应用程序的更改(在某些情况下,旧应用程序甚至不需要进行任何代码更改)。这极大地降低了开发和测试成本(对于业务来说没有净功能收益),并极大地降低了推出风险。
它还使您能够集中精力关注组织的真正价值:
- 新的数据库结构
- 新的RESTful web服务
- 新应用程序(可能使用RESTful web服务构建)
Web服务的积极方面
请不要将上述内容解读为反对web服务,特别是RESTful web服务。当用于正确的原因时,例如用于启用web应用程序或在不同系统之间进行集成时,这是一种良好的架构解决方案。然而,在数据迁移期间管理您的旧应用程序可能并非最佳解决方案。