【问题标题】:Is a 'blackhole' table evil?“黑洞”表是邪恶的吗?
【发布时间】:2011-12-07 01:59:15
【问题描述】:

阅读this question 我刚刚了解到blackhole 表技巧的存在:基本上是使用单个表插入数据,然后使用触发器将数据拆分到许多其他表中。

我想知道这是否会导致问题,一旦从事该项目的开发人员意识到这一点。

这种技术的优缺点是什么?

编辑: 当我看到这个例子时,我想到的眨眼是关于事务的:如果由于某种原因事务失败,你会发现 blackhole 行包含原始数据,用于历史目的,也许有助于调试 - 但这似乎是我能看到的唯一 +1 黑洞。想法?

【问题讨论】:

  • re: 作为一种事务日志。是的,大多数数据库都不容易阅读事务日志。良好的事务日志管理并非易事。理想情况下,事务日志应该更新每一行的前后。这会导致事务日志增长得非常快。黑洞模式只捕获插入。
  • 我只是赞成,因为你让我意识到了另一种可怕的做法。

标签: mysql database postgresql database-design


【解决方案1】:

我不认为黑洞有任何真正的优点。

编写触发器代码来移动数据可能并不比编写代码将数据插入到正确的位置要少得多。

正如 Christian Oudard 所写,它并没有降低复杂性 - 只是将其移至真正难以调试的地方。

不利的一面:

“副作用”在软件开发中通常是个坏主意。触发器是副作用——我打算做一件事(在表中插入数据),它实际上做了很多其他的事情。现在,当我调试我的代码时,我也必须把所有的副作用都记在脑子里——而且副作用本身也可能有副作用。

大多数软件在维护上花费的时间远比在开发上花费的时间多。将新开发人员带入团队并解释黑洞技巧可能会增加学习曲线 - 收益微不足道(在我看来)。

因为触发器是副作用,如果你不小心就很容易触发大量的触发器,所以我一直尝试在不依赖触发器的情况下设计我的数据库;触发器显然是正确的方法,我只让我最有经验的开发人员创建它们。黑洞把戏使触发器成为一种正常、有规律的工作方式。当然,这是个人观点。

【讨论】:

  • +1。事实上,它可能没有优点,只有业余爱好者:-)。 (这个笑话是“业余”这个词的法语意思,意思是“支持者”。)
  • @Erwin - 笑话在英语中也可以,基本上是no good points, only enthusiastic beginners,暗示谁不知道他们在做什么
  • 如果您正在测量数据库驱动程序的性能,并且您希望性能数据与服务器的时间分离,这非常有用。不幸的是,其他 SQL Server 没有这个强大的功能。
【解决方案2】:

提示您的 original question 并不是 MySQL“黑洞”的核心。

什么是黑洞?

在 MySQL-speak 中,BLACKHOLE 是一个 storage engine,它简单地丢弃所有插入其中的数据,类似于空设备。使用这个后端有很多原因,但它们往往有点深奥:

  • “仅中继”二进制日志过滤从站
    请参阅 docsherehere
  • 基准测试
    例如,测量二进制日志记录的开销,而不用担心存储引擎开销
  • 各种计算技巧
    here

如果您不知道为什么需要伪装成表的数据接收器,请不要使用它。

你问的是什么技术?

use under consideration 似乎是:

  1. 将插入的数据重定向到其他表
  2. 审核记录原始 INSERTion 操作
  3. 丢弃原来的 INSERT 数据

因此,“邪恶”或优缺点问题的答案与可插入/可更新 VIEW(实现 #1 的常用方法)、基于触发器的审计日志(大多数人如何做#2)和行为覆盖/反作用一般(有很多方法可以完成#3)。

那么,答案是什么?

答案当然是,“有时这些技术是合适的,有时是不合适的。” :) 你知道你为什么这样做吗?应用程序是否适合此功能?抽象是不是太脆、太漏、太死板等等?

【讨论】:

    【解决方案3】:

    这看起来不是个好主意。如果您想保持前端代码简单,为什么不直接使用存储过程呢?如果不是为了保持前端代码简单,那我完全没看懂。

    【讨论】:

      【解决方案4】:

      有趣的是,我今天也知道了黑洞的存在。

      可以说这里的问题实际上是一个更广泛的问题,即业务逻辑是否应该嵌入到数据库触发器中。在这种情况下,黑洞表本质上被用作临时数据存储,黑洞表上的触发器可以利用它。应该首先使用触发器吗?对我来说,这才是问题的实质。

      我个人认为触发器的使用应该仅限于日志记录和特定于 DBA 的任务,并且不应该包含应该牢牢属于应用层的业务逻辑(或任何与此相关的逻辑)。似乎已经有不少关于database triggers are evil or not的意见。我认为您的问题也属于这一类。

      在数据库触发器中嵌入应用层逻辑可能会有风险。

      很可能最终会在应用程序之间拆分业务逻辑 代码和数据库。这确实非常令人困惑 有人试图支持并深入了解代码库。

      如果您最终在触发器和存储过程中使用了过多的逻辑,那么您很容易在数据库服务器上遇到性能问题,这些问题本可以通过分配繁重的处理任务(即复杂的业务)来解决应用服务器之间的逻辑,并让数据库服务器空闲用于其主要目的,即提供数据。

      当然只是我的两块钱!

      【讨论】:

        【解决方案5】:

        每次您在表中插入一行时,很有可能您正在写入硬盘驱动器的同一区域或同一页面(在 MS-SQL 世界中,我不了解 postgresql),所以这技术可能会导致争用和锁定,因为所有事务现在都在竞争写入同一个表。

        这也将使插入性能减半,因为插入需要两个插入而不是一个。

        这是非规范化,因为现在有两个数据副本而不是一个。

        【讨论】:

        • 性能很好,但在这种情况下,非规范化可用于“历史”目的..这次我不认为它很糟糕
        • 我从 1970 年代就开始使用数据库,这可能是我在数据库设计方面听过的最糟糕的想法。您为数据完整性、性能和安全性设计数据库。您设计它们并不是为了让应用程序开发人员更简单。用户通常每分钟插入多次记录,开发人员每隔几年就会接触一次该部分的代码。这是一场性能噩梦。除非您有两个用户并且几乎没有插入,否则这不可能在负载下工作。
        • @daniel,如果您想要历史记录,请使用审计表,但同样不要对所有表使用一个审计表,因为这会损害性能。
        • @HLGEM atm im 使用日志(其中大多数基于文件)作为历史记录,应该是这样,但是.. 这个技术只是在我心中点亮了一个灯泡;)
        【解决方案6】:

        请不要这样做。这不会降低复杂性,它只是移动它。这种逻辑属于应用层,可以使用 PHP、Python 或 Ruby 等更好的语言来实现。

        【讨论】:

          【解决方案7】:

          不要这样做。它被称为技巧而不是标准的做事方式这一事实对我来说已经足够了。

          这完全扼杀了关系模型的正常使用模式。不确定它是否真的会杀死正常形式,因为您仍然可以将它们全部到位。它只是弄乱了数据进入目标表的方式。看起来像是维护噩梦之上的性能噩梦。例如,想象一个表有一个触发器,该触发器必须触发 1,800 多个表插入。那只是让我感到恶心。

          这只是一个有趣的客厅把戏而已。

          【讨论】:

            【解决方案8】:

            我想这会很慢,因为不能使用“批量插入”的优势。

            【讨论】:

              猜你喜欢
              • 2011-01-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-11-18
              • 2010-11-26
              • 2020-08-10
              相关资源
              最近更新 更多