【问题标题】:What are the problems with a join between two tables in two different databases?连接两个不同数据库中的两个表有什么问题?
【发布时间】:2011-07-05 21:25:39
【问题描述】:

我对您对连接来自不同数据库的两个或多个表的缺陷的想法很感兴趣。我试着举个例子。

假设表 Table1 位于 DatabaseA 数据库中,Table2 位于 DatabaseB 中。 假设我在DatabaseA 中有一个视图,它从Table1DatabaseA' 中的一些其他表中提取了一些数据。

这个视图是用来把数据推送到另一个数据库的,我们就叫这个吧,别想了,DatabaseC

如果我需要来自Table2 的一些数据,我的直觉是在这个视图中直接加入Table2,有点像table1 inner join DatabaseB..table2 on [some columns]

这样做非常简单快捷,但我脑子里有个唠叨的声音一直告诉我不要这样做。我担心的是无法根据Table2 追踪所有对象,因此如果我在那里更改某些内容,我必须非常小心并记住我使用此表的任何地方。所以,有点像打破这个视图(和两个数据库)的 SRP,因为这个视图可以从两个不同的操作中改变(在两个不同的数据库上执行:更改 Table1 或更改 Table2

我对你的意见很感兴趣。这是个好主意还是坏主意?这种方法会有什么问题(性能方面、维护方面等等),如果你有一个真实的世界经验,这种方法要么是一个大错误,要么是你的救命稻草。

P.S:我在 google 和 SO 上搜索过这个主题,但找不到与此相关的任何内容。我很乐意接受 SO 用户的减分票、重复问题和其他“谴责”,只是为了对这个问题有不同的看法。

P.P.S:我使用的是 SQL Server 2005。

谢谢你,希望我说清楚:)

【问题讨论】:

    标签: sql-server database sql-server-2005 database-design


    【解决方案1】:

    就像 SQL 中的其他所有内容一样,这取决于。

    在我的工作中,我们经常这样做。我们有非常大的数据集,以及用于标题和详细级别记录的单独数据库,然后是用于我们根据其他数据构建的报告或表格的额外数据库等。

    跨数据库加入并没有真正的性能问题,在某些情况下,根据您的硬件设置,它可能会更快。如果 DatabaseA 和 DatabaseB 位于具有不同控制器的不同物理驱动器上,则运行查询连接它们可能会比它们位于同一卷上的同一数据库中更快。

    维护可能是一个问题,但不会超过任何其他数据库/表。这不像您拥有相同表的不同版本,您只是将这些表放在不同的数据库中。

    唯一的主要缺点是 SQL Server 在显示数据库内依赖关系方面做得很差,因此您需要自己跟踪这些依赖关系。有一些脚本和第三方实用程序,我听说 SQL Server Denali 会为此添加额外的支持,但我不确定这是否准确。

    【讨论】:

      【解决方案2】:

      如果它们在同一台服务器上,则从单独的数据库中提取没有真正的问题。事实上,您可能出于充分的理由想要将它们分开。例如,如果您有从文件导入的事务表和查找表的组合。事务数据需要完全恢复和频繁的事务日志备份才能正确恢复,而查找数据不需要并且可以从处于简单恢复模式的数据库中受益。

      我们的应用程序使用许多不同的数据库,并且我们一直在查询中跨数据库。只要正确完成索引,就不会出现明显的性能差异。最大的潜在问题是数据完整性,因为您无法跨数据库设置外键。如果需要,这可以在触发器中处理。

      现在,当数据库位于不同的服务器上时,可能会出现性能问题并且获取数据更加复杂。

      【讨论】:

      • 感谢您提出服务器问题。我相信这将是我们未来的设置(不同服务器上的数据库),提前计划是件好事。
      【解决方案3】:

      你唠叨的声音可能是对的。

      其中最重要的问题是如何强制声明性引用完整性,因为您无法在数据库之间创建外键,因此迟早您将不得不处理不一致、不匹配或不完整的数据。

      但如果你不关心这个,我看不出有什么问题:-)

      【讨论】:

      • 您可以通过触发器强制执行数据完整性约束。
      【解决方案4】:

      您的问题的答案是……视情况而定。

      我注意到,当您保持查询良好和简单(更少的连接等)时,性能并没有严重下降。

      查询越复杂,优化器产生次优执行计划的机会就越大。

      优化器最终决定如何执行查询。查询越复杂,优化器获得“错误”操作顺序的机会就越大。

      我最近尝试过这个问题...

      我在单个数据库上运行了大约 8 个连接的查询。然后,我在同一台服务器上以不同的名称创建了该数据库的副本,然后我修改了查询,以便它可以连接到数据库的第二个副本中的几个表。

      作为单个数据库查询,它在 3 秒内运行;考虑到数据量的预期。

      跨数据库联接查询运行时间不到 3 分钟。

      enter code here
      

      【讨论】:

        【解决方案5】:

        一些关于跨数据库连接的一般主题:

        外键

        正如其他人指出的那样,在没有外键的情况下,您需要滚动自己的参照完整性。本身不是问题,但当您无法控制一个或多个数据库中的数据时,问题就会浮出水面。

        一个相关的问题是 CASE 工具的使用。在对架构进行逆向工程时,他们将忽略不存在 FK->PK 关系的表之间的链接。

        性能

        如果数据库位于不同的服务器上,那么您将面临这些服务器上运行的任何其他内容的变幻莫测以及运行连接操作本身的成本。同样,如果服务器都在您的控制范围内,那么您可以监控这些内容,但可能并非如此。

        耦合

        如果您的解决方案依赖于其他数据库,则会出现多个故障点。如果数据库出现故障,这可能会级联到一个或多个系统。

        数据修改

        您的解决方案可能与您认为是另一个数据库的表中的静态数据相结合。但是,如果这被意外(或故意)修改、复制或删除怎么办。同样,如果有问题的数据库不在您的职权范围内,其他团队/部门可能不知道您的系统是如何运行的。


        所有这些,的确,在很多情况下跨数据库连接是常态。我见过的几个例子:

        集市库

        在集市上进行高性能操作,而主数据存储在存储库中。 CRUD 操作在两者之间频繁或不频繁地进行(夜间更新、实时等)。

        旧版数据库

        您可能会为了数据迁移和/或报告/审计目的而公开旧数据库。

        查找

        您的一个或多个数据库可能包含可重复使用的静态查找信息。


        所以要回答您的问题 - 这取决于您到底在做什么以及风险是否可以接受。存在其他解决方案,例如复制,但同样,这将取决于您的部门/公司的结构。

        【讨论】:

          猜你喜欢
          • 2014-05-14
          • 1970-01-01
          • 2019-08-11
          • 1970-01-01
          • 2018-04-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-05
          相关资源
          最近更新 更多