代码之家  ›  专栏  ›  技术社区  ›  thaBadDawg

多应用实例的数据库设计理论

  •  2
  • thaBadDawg  · 技术社区  · 15 年前

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

    昨天晚上,我试图向我的两个测试帐户推出一个修改数据库的更新。虽然随后导致的错误是我的错(忘记了DDL中一个很小但显然非常重要的更改),但我开始担心我的整体操作理论,因为缺少一个alter column语句和一个完整的升级周期可能会被吹到地狱。所以在长时间积累之后,我的问题是:

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

    2)我是否应该考虑另一个数据库(和/或应用程序)设计模型?我知道如果我不再支持多个版本的应用程序,我实际上消除了很多长期的支持难题。

    5 回复  |  直到 15 年前
        1
  •  2
  •   gahooa    15 年前

    思想食粮:

    代码升级比数据库架构升级更频繁。确保你有一个 真的很好 供应链管理到位,以处理代码升级。我们使用 git 取得了巨大的成功。

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


    应为每个数据库架构版本指定唯一的顺序整数版本号。从每说100开始。

    每次需要升级时,都要编写一个sql脚本,比如

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

    每个脚本的任务是为该特定版本执行升级。它可以像添加表一样简单,也可以像重新排列外键一样复杂。但无论如何,他们会 可靠的 在他们被设计来做的事情上。

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


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

        2
  •  2
  •   DVK    15 年前
    1. 你不应该用手换数据库。通过执行所有DDL更改等的脚本来执行…

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

      (在版本控制系统中,ddl更改应该使用特定的标记进行标记)

    2. 你可以去微软路由RE:支持多个版本作为一个头痛-简单地指定所有版本之前的X(说2个版本回来)作为未支持。这样,您可以支持最后2-3个版本,但不要浪费更多的资源,同时允许客户机的灵活性在很大程度上。

    3. 你应该仔细权衡你所提议的app/db系统版本化的利弊。

      列出优点(比如安抚投资者,当你提到的版本发生意外变化时给客户带来积极的体验- 转化为保留/增加需要此类功能的新客户的边际概率 ,再加上一个简单的beta/uat测试方法, 再加上一个失败的方法来回滚模式更改 通过将客户机的数据从以前的版本加载到db schema)。

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

    比较两者,决定哪一个更适合你的生意。

        3
  •  2
  •   MusiGenesis    15 年前

    雷德盖特 SQL Compare 很好地比较和区分了两个sql server数据库(警告:商业第三方产品)。而且,我认为有一些免费的东西也能做同样的事情。

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

        4
  •  2
  •   Community CDub    7 年前

    手动运行脚本将不起作用。也不是什么工具。diff适用于2、4或10个数据库。但不能缩放,因为你需要的是 可靠性 出现故障时(脱机数据库,服务器重新启动所有这些)。

    通过调度升级脚本进行部署。例如,查看MySpace如何对1000多个数据库执行此操作: MySpace Uses SQL Server Service Broker to Protect Integrity of 1 Petabyte of Data . 关键是它们使用有保证、可靠的传递机制(ssb)来部署模式维护脚本。您需要一个异步的、可靠的机制来运行脚本,因为目的地数据库可能是离线的,运行预定的维护、UnReCabHe等,并且可靠的传递机制,例如Service Bug可以处理所有重试和相关问题(处理重复、确认等)。你也可以看看 Asynchronous procedure execution 例如如何通过ssb处理脚本执行。

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

    更新

    我想我有一些解释,为什么我认为扩散一个错误的方法。为了说明这一点,我要说的是数百台服务器和数千个数据库的部署。最初的帖子将自己比作facebook,我希望他们能够成功地达到这个规模,但同时也提出了一些问题 设计原则 ,所以我认为讨论云层尺度是适当的。

    我发现diff工具有两个问题:

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

    • Atomicity。diff工具需要“master”的稳定模式。这实际上会在升级过程中冻结“master”。虽然这可以在小规模上进行控制,但在大规模的情况下,当将主机本身升级到V.N+ 1时,成为一个问题,当一些可能仍在从V.N-1升级时,与所有的数千个数据库竞争。

    将升级脚本发送到“副本”的基于脚本的解决方案可以解决这两个问题。还有一些不同的工具,比如基于vsdb.dbschema的 vsdbcmd.exe 比“live”diff工具更好,因为“master”dbschema文件可以传递到“copy”计算机,并将整个升级过程转换为本地操作。

    总的来说,我也相信基于脚本的升级,使用元数据版本控制,是对基于diff的升级的支持,因为我在q1525591的链接中已经讨论过测试和源代码控制的原因。

        5
  •  0
  •   Andomar    15 年前

    如果我拿走支持多重 应用程序的版本 实际上去掉了很多长期的 支持性头痛

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

    因此,如果您有多个客户,为客户1推出修复程序将使客户2感到不安。它甚至不必是一个被窃听的版本;它可能只是改变了他们不同意的行为。对于大多数客户来说,不控制发布计划是不可接受的。

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

    有很多客户认为这种方法是失败的(比如雅虎邮件),但是阅读你的问题,我认为你已经安全地低于这个数字了。对于一个比较工具,我不得不同意那些建议RealGATE的SQL比较的帖子。