如何在多架构 MS SQL Server 环境中使用 Flyway?
Posted
技术标签:
【中文标题】如何在多架构 MS SQL Server 环境中使用 Flyway?【英文标题】:How to use Flyway in a multi-schema MS SQL Server environment? 【发布时间】:2014-09-05 23:31:04 【问题描述】:我们有一个使用“多模式”策略的多租户 SaaS 应用程序,即每个客户在同一个数据库实例中都有专用的模式。我们使用 MS SQL Server 作为数据库,它通过 SQL Server“用户”的“默认模式”设置在模式之间切换。例如客户 A、B 和 C 在 SQL Server 中的配置如下:
客户 A:user_A
,默认架构 schema_A
客户 B:user_B
,默认架构 schema_B
客户 C:user_C
,默认架构 schema_C
... 等等。
在我们的应用程序中,我们通过在每次查询之前执行以下 SQL 来设置连接上的 SQL Server“用户”来切换 DataSource 连接以指向每个客户的正确架构:
EXECUTE AS USER = 'user_A';
当我们尝试使用 Flyway 以全局方式管理模式版本的状态时,这给我们带来了一些问题。由于 flyway 的架构支持仅接受架构名称列表,因此这不适用于 MS SQL Server。 Flyway 在 DataSource 配置提供的用户的默认模式上执行迁移;在 SQL Server 的情况下,“用户”需要因客户/模式而异。
理想情况下,我们应该有一个像FlywayCallback.beforeEachSchemaMigrate(Connection)
这样的回调,它可以让我们通过在每个架构的每次迁移之前执行“以用户身份执行”语句来设置每个架构所需的用户上下文。不知道为什么没有那个钩子?
flyway 的另一个缺点是在模式列表中使用第一个模式的约定,作为持有schema_version
表的模式。这在基于 SQL Server 的多租户环境中是不需要的。因为我们不能假设包含schema_version
表的模式也是真正的客户模式。请记住,在像我们这样的 SaaS 应用程序中,每个租户/客户的模式是动态创建/销毁的。当用户注册时,配置过程的一部分会根据一些约定创建新模式。所以模式列表对我们来说是动态的。
理想情况下,我们可以告诉 Flyway 使用给定架构来创建 schema_version
表,而无需尝试在该架构上运行迁移。通常这将是 dbo
架构(这是 SQL Server 中的默认架构)。我们使用 dbo 模式来保存跨所有租户的全局表,schema_version 将被视为全局表。
所以最终迁移成功后,我们的数据库应该如下所示:
- dbo.schema_version
- schema_A.my_tables
- schema_B.my_tables
- schema_C.my_tables
以上所有架构都处于相同的“状态”,由dbo.schema_version
表指示和控制。
目前可以吗?
【问题讨论】:
【参考方案1】:您必须以不同的方式解决问题。与其为每个人执行一次 Flyway,不如为每个模式执行一次。您可以将 Flyway 包装在一个循环中,并在每次迭代时为一个租户提供正确的配置。您最终会为每个租户创建一个 schema_version 表,但它们都可以单独命名并且仍然存在于 dbo 架构中。
【讨论】:
这是真的,我已经有一个概念证明,我正在循环遍历每个模式并为每个模式创建新的 Flyway 实例,效果很好(这是我们的 B 计划)。事实上,在这种情况下,我们不想将 schema_version 表放在 dbo 中,因为它不是“全局的”,它们将驻留在各自的模式中。然而,这样做的缺点是我们不能保证同一数据库中的所有模式都处于相同的确切“状态”。一种模式可能是 2.0.1 版本,另一种可能是 2.0.2,这是我们试图避免的。没有架构回调的任何原因? 现在我们将为每个模式使用单独的 Flyway 实例。事实证明,出于各种其他原因,这可能是一种更好的方法。 不,你不能。这适用于除 sql server 之外的每个数据库,这是关于此的。当然,除非我遗漏了什么。 我错过了:占位符。我认为如果提及它们,答案会更好(如果不改变答案,我实际上无法改变我的投票),但我不太清楚如何将提及纳入这个答案。以上是关于如何在多架构 MS SQL Server 环境中使用 Flyway?的主要内容,如果未能解决你的问题,请参考以下文章
如何在工作组环境中为 MS SQL Server 创建 Windows 服务帐户?