【问题标题】:Maintaining complex logic integrity across tables跨表维护复杂的逻辑完整性
【发布时间】:2019-04-20 12:54:06
【问题描述】:

我正在设计一个关系数据库,表之间有许多复杂的完整性规则。我的想法是定义最基本的表,并编写视图来表示从基本表中产生的更高级别的概念。

例如,假设有一个银行账户数据库,我定义了一个具体的transaction 表,保存账户的存款和取款,以及一个名为balance 的视图,汇总每个账户的所有存款和取款。还有一个名为liability 的具体表,记录每个账户中的冻结金额,因此avaliable_balance 视图是balance 给出的余额减去表liability 中账户所有冻结资金的总和。随着时间的推移,它变得越来越复杂。

随着数据库的增长,我担心像查找客户可以花多少钱这样简单的事情会产生过于复杂和昂贵的查询。替代方案是:

  • 物化视图,但据我了解,它们不会自动更新,而且更新它们是一项代价高昂的操作,不能在每次表更改时都完成。
  • 视图的具体表,仅通过基本表上的UPDATEINSERTDELETE 触发器自动更新。但这很容易出错,在开发时间上代价高昂,而且感觉不对,因为关系和更新规则可以从视图的定义中“轻松”推断出来,并且似乎应该自动完成。

当这样的数据库增长时,我会遇到性能问题吗?如果是,我该如何解决?哪个是最好的方法,性能方面?有没有我没有看到的替代方案?

【问题讨论】:

  • 我的 preference 是视图或物化视图。其他人可能会争论触发器。您可以将功能添加到可能性的万神殿中。但是您的问题既广泛(“通常接近”)又是意见问题(“哪个是最好的”)。
  • 这个问题似乎太常见了,我想也许有一个我不知道的简单、优雅的解决方案。
  • 究竟是什么问题?架构是否太复杂?查询太慢了吗?这个问题太宽泛了,请把它限制在一个具体的问题上,否则你很可能会在短时间内获得 5 票“太宽泛”。
  • 我对此的感觉是,在 RDBMS 中强制执行业务头脑可以想到的每条完整性规则实际上是不可能的,因此最好坚持基本原则。您还有一个问题,即交易无法看到彼此,无论如何您都需要实现每个帐户的锁定机制,以保证可以执行交易。正如你所说,PostgreSQL 中的 MV 在提交时无法快速刷新,所以我会忽略它们。
  • 您是否估计每天会发生多少事务,有多少用户将运行这些视图(以及运行频率)?它是某种报告数据库还是产品的实际后端?

标签: postgresql view data-modeling materialized-views


【解决方案1】:

这个问题太笼统了,我只能给出一个非常笼统的答案;改天我可能会投票给“太宽泛”。

视图可能是好事也可能是坏事。它们有利于

  • 从实际物理数据模型中抽象出一个接口

  • 只允许用户查看表格中的部分数据

您的用例是第一个。

在定义观点时使用品味和辨别力。以下是两条准则:

  • 不要将视图层次结构嵌套得太深。超过两个级别通常太多了。视图的深层层次结构使模型难以理解,并且使调试变得非常困难。

  • 永远不要忘记视图不是表。它可能只在某些查询中表现良好,例如在某些额外的WHERE 条件下。

您可以做的最好的事情是在设计时弄清楚您将对数据库运行哪些类型的查询,尤其是频繁查询。然后您可以规划您的视图,以便它们在这些查询中表现良好。

仅当您的性能要求让您没有其他出路时,才使用物化视图和其他保留冗余数据的技术。通常一个好的设计就足够了。

【讨论】:

    猜你喜欢
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    • 2011-11-26
    • 2011-06-15
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多