【问题标题】:Database Design Theory For Multiple Application Instances多应用实例的数据库设计理论
【发布时间】:2009-10-27 00:45:59
【问题描述】:

我正在开发一个 SaaS 项目,该项目将让每个客户都有一个应用程序实例(customer1.application.com、customer2.application.com 等),理想情况下,每个客户都将拥有自己的“自己”空间数据库。当前的计划是为每个客户创建一个数据库,并将应用程序的一个实例部署到网络场中。这个想法是每个客户都可以选择退出升级以维持现状(我们的一位投资者真正想要的,很大程度上是因为他讨厌 Facebook 如何不断改变它的工作方式。)

昨晚我尝试向我的两个测试帐户推出更改数据库的更新。虽然随后引起的错误是我的错(忘记了 DDL 中一个很小但显然非常重要的更改),但我开始担心我的整体操作理论,因为缺少一个 ALTER COLUMN 语句和整个升级周期可能会被吹到地狱。因此,经过这么长时间的积累,这是我的问题:

1) 有没有办法在两个数据库(“测试”生产数据库和实际生产数据库)之间进行差异,以准确记录所做的每个更改?

2) 我应该考虑其他数据库(和/或应用程序)设计模型吗?我知道,如果我取消对应用程序的多个版本的支持,我实际上会消除很多长期支持方面的麻烦。

【问题讨论】:

  • 您只需要一个更好的测试策略。您不应将未经测试的更改应用于生产数据库。
  • 我没有真正的生产数据库,我目前正在研究我的部署方法,并且我已经建立了两个测试客户帐户来测试升级过程。
  • 我想指出,SQL Diff 解决方案不能可靠地涵盖架构升级期间经常发生的数据更改。如果您添加一列,那么通常您可以同时使用一些计算数据填充它。 SQL diff(虽然有用)在实时数据库中进行大的更改是不安全的。
  • @Glen:根据 Code Complete,cc2e.com,最好的测试人员在任何部署中最多发现 20% 的错误。因此,虽然添加测试可以提高质量,但这并不是保证。您必须将收益与成本进行比较。

标签: sql-server


【解决方案1】:

深思:

代码升级比数据库架构升级更频繁。确保您有一个非常好的 SCM 来处理代码升级。我们使用git 取得了巨大成功。

代码易于管理,而数据库则不然(相比之下)。原因是它们是可变的,并且每时每刻都在变化。另外,它们真的很难回滚(可能,但很耗时,需要停机)。因此,我们必须找到一种简单的方法来跟踪架构更新(以及相关的数据更改),并能够在未来将它们应用到其他类似的数据库中。


每个数据库架构版本都应该被赋予一个唯一的、连续的整数版本号。从每人 100 个开始。

每次要升级的时候,写一个类似的sql脚本

  • 100-101.sql
  • 101-102.sql
  • 102-103.sql

为特定版本执行升级是每个脚本的工作。它可以像添加表格一样简单,也可以像重新排列外键一样复杂。但无论如何,他们将可靠按照他们的设计目标。

您可以在测试期间(在新数据上)多次应用任何给定脚本,以确保它按预期工作。


因此,当您发现自己需要将客户端从版本 130 升级到 180 时,您可以安全地应用 sql 脚本(按顺序),您将到达正确的目的地。

【讨论】:

    【解决方案2】:
    1. 您永远不应该手动更改数据库。通过执行所有 DDL 更改等的脚本来执行此操作...

      理想情况下,应该有一个使用 DDL 版本作为配置/输入的通用数据库发布脚本。

      (并且 DDL 更改应在版本控制系统中使用特定标记进行标记)

    2. 您可以采用 Microsoft 路线重新:支持多个版本令人头疼 - 只需将 X 之前的所有版本(比如 2 个版本)指定为不受支持。这样一来,您可以支持最后 2-3 个版本,但不会在任何其他方面浪费资源,同时在很大程度上允许每个客户端的灵活性。

    3. 您应该仔细权衡使用您建议的版本化应用程序/数据库系统的利弊。

      列出优点(例如安抚投资者,在您提到的版本意外更改时为客户提供积极的体验 - 转化为保留/添加需要此类功能的新客户的边际概率,以及一种进行 BETA/UAT 测试的简单方法,加上一个失败的方法来回滚错误的架构更改,方法是将客户端的数据从先前版本加载到数据库架构中)。

      列出缺点(数据库空间成本、实施时间成本、支持成本)

    比较两者并决定哪个更适合您的业务。

    【讨论】:

    • DDL 是通过脚本应用的...我只是没有将列添加到新表引用的表中。因此询问 DDL 差异工具。
    【解决方案3】:

    Redgate 的SQL Compare 在比较和区分两个 SQL Server 数据库方面做得很好(警告:商业第三方产品)。另外,我认为那里有很多免费的东西可以做同样的事情。

    如果您希望在旧版本的产品上留下一些客户,维护一个每个客户一个数据库的模型可能更有意义,其中用于构建每个版本的数据库的脚本在源代码下控制。这使您的客户彼此隔离,甚至允许您在某些客户上切换数据库供应商(例如从 SQL Server 到 Oracle)或版本(即从 SQL Server 2000 到 Sql Server 2005),同时让其他客户使用旧版本。

    【讨论】:

      【解决方案4】:

      手动运行脚本将不起作用。就此而言,也没有差异工具。 Diff 适用于 2,4 可能 10 个数据库。但无法扩展,因为您需要的是在出现故障(离线数据库、服务器重新启动所有这些)时的可靠性

      您通过安排升级脚本进行部署。例如,查看 MySpace 如何为 1000 多个数据库执行此操作:MySpace Uses SQL Server Service Broker to Protect Integrity of 1 Petabyte of Data。关键是他们使用有保证的、可靠的交付机制 (SSB) 来部署模式维护脚本。您需要一种异步、可靠的机制来运行脚本,因为目标数据库可能处于脱机状态、运行计划维护、unreacahbe 等,并且像 Service Broker 这样的可靠交付机制可以处理所有重试和相关问题(处理重复、确认等)。您还可以查看Asynchronous procedure execution,了解如何通过 SSB 处理脚本执行的示例。

      至于脚本本身,我建议您开始将数据库架构和配置数据视为版本化资源。我已经多次解决了这个问题,例如。见Do you put your database static data into source-control ? How?

      更新

      我想我有一些解释为什么我认为差异化是一种错误的方法。为了清楚起见,我说的是数百台服务器和数千个数据库的部署。原始帖子将自己与 facebook 进行比较,我希望他们能够成功达到这个规模,但也提出了有关 设计原则的问题,所以我说讨论云级别规模是合适的。

      我发现差异工具存在两个问题:

      • 可用性。所有差异工具都通过连接到“主”和“副本”来工作,因此它们只有在两者都在线时才能完成工作。这会创建一个热点、单点故障、“主”副本,其可用性对于部署升级至关重要。高可用性总是有代价的。它还将“复制”可用性问题作为次要实现细节留下,升级方案必须自行处理重试和超时以及与客户端断开连接(无论如何都不是小问题)。

      • 原子性。 diff 工具需要一个稳定的“master”模式。这实际上会在升级过程中冻结“master”。虽然这可以在小范围内控制,但在大范围内它会成为一个问题,因为将 master 本身升级到 v. N+1 会成为与所有数千个数据库的竞赛,而其中一些可能仍在从 v. N-1 升级.

      将升级脚本发送到“副本”的基于脚本的解决方案解决了这两个问题。此外,基于vsdbcmd.exe 的 VSDB .dbschema 之类的差异工具比“实时”差异工具更好,因为“主”dbschema 文件可以传送到“复制”机器,并将整个升级过程转变为本地操作。

      总的来说,我也相信基于脚本的升级,使用元数据版本控制,优于基于差异的升级,因为我已经在 Q1525591 的链接中谈到了测试和源代码控制的原因。

      【讨论】:

      • Remus - 你的第一句话显然是假的。我们每天在 100 多个数据库上执行此操作(除了 100 多个客户端文件系统)。最简单的技巧是与“黄金副本”进行比较。
      • 数百个数据库和数百个文件系统是 100% 在线可用的吗?这是行业首创......
      • 没有人声称 100% 正常运行时间,SSB 甚至没有意义。只有一台数据库服务器!
      【解决方案5】:

      如果我取消支持多个 我的应用程序版本 实际上消除了很多长期 支持头痛

      任何变化,无论多么微小,都有可能破坏对某人很重要的东西。

      因此,如果您有多个客户,则为客户 1 推出修复程序会使客户 2 感到不安。它甚至不必是一个有问题的版本;这可能只是他们不同意的行为改变。对于大多数客户来说,不控制发布时间表是完全不能接受的。

      因此,我建议您为每个客户保留不同的代码库。只有在与客户达成协议后才能推出修复程序。

      这种方法有很多客户失败(想想雅虎邮件),但阅读你的问题,我认为你安全地低于这个数字。对于比较工具,我不禁同意建议 Redgate 的 SQL 比较的帖子。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-02
        • 2012-03-09
        • 1970-01-01
        • 2011-05-09
        • 1970-01-01
        • 2011-07-03
        • 1970-01-01
        • 2012-08-22
        相关资源
        最近更新 更多