【问题标题】:Storing "redundant" foreign keys to avoid joins存储“冗余”外键以避免连接
【发布时间】:2017-03-25 23:51:26
【问题描述】:

我正在为一个 Web 应用程序项目设计一个数据库,我得出的结论是,我可能只有很少的查询需要大量连接的表才能进行一次检查。

我想知道在某处存储外键以减少这些查询所需的连接数量有多糟糕?

举个例子说明我现在的情况: 服务 => 预订 => 交易 => 钱包 => BonusOffer

我需要检查是否使用与奖金相关的钱包购买了该服务。将 BonusOffer id 存储为 Transaction 的外键是否明智?

您可能会问为什么是 Transaction - 这是因为这些查询中的大多数将“通过”Transaction,而 Transaction 将位于中间的某个位置。

【问题讨论】:

  • 我的心说你不应该,但我的想法是,如果你愿意,你可以试试。一如既往地检查EXPLAIN PLAN 以检查您是否有任何改进。因为有时您会花费大量时间尝试优化数据库已经设计优化的东西,所以无需担心too many 加入
  • @JuanCarlosOropeza 我的心也是!我想过使用辅助表来链接BonusOfferTransaction。这样我就可以避免冗余并且可以满足查询。你认为这是一个更好的做法吗?事实上,我很确定这些查询无论如何都会很快,但我想在真正需要优化数据库以提高性能之前获得更多信息,而不是在遇到性能问题时快速执行。
  • 我认为这不是更好的做法,因为这会使某些事情变得过于复杂并且超出正常范围。这意味着更难维持,你需要向后面的每个人解释你的聪明捷径。
  • 我想我和@Uueerdo 有类似的想法。答案似乎取决于此处未详细说明的数据方面。如果一个钱包可以有多个与其相关联的赠金,或者赠金会影响交易,那么如果此处的列 not 以及组合的两列外键 ( wallet_id, bonus_offer_id) 可能是合适的。如果赠金实际上不是交易的属性,而只是钱包的属性,那么将其包含在此处是不好的设计。避免连接不足以产生冗余数据。
  • 请使用您设计的最少列给出 DDL,以说明您的问题。请阅读How to Ask。请注意,设计问题可以从minimal reproducible example 的尽可能多的元素中受益。 PS什么@Michael-sqlbot最后评论说,除了你应该有冗余列和FK(s)或没有列但适当的约束

标签: mysql database-design foreign-keys foreign-key-relationship database-normalization


【解决方案1】:

联接是关系 DBMS 的工作方式。了解和使用规范化。

我需要检查是否使用与奖金相关的钱包购买了该服务。

如果每个服务都是如此,那么您的数据库就会受到约束。就是(select service from Service_has_transaction join Transaction_has_wallet)(select service from Service_has_transaction join Transaction_has_wallet join Wallet_has_bonus) 的子集。

大多数 SQL DBMS 不允许您以声明方式表达该约束,并且不知道如何优化执行它。然而,我们可以使用一个 SQL 习惯用法来以声明的方式表达和执行它。 (猜测你的表定义:)首先添加一个bonus 列到Transaction_has_wallet 和一个从Transaction_has_wallet (wallet, bonus)Wallet_has_bonus 的外键。然后将钱包和奖金列添加到Service_has_transaction 和从Service_has_transaction (transaction, wallet, bonus)Transaction 的外键。这增加了冗余列,但仍然将数据库限制为有效状态,因为外键约束防止冗余值出错。 (希望这是一个学习通过触发器表达任意约束的动机示例。)

【讨论】:

    猜你喜欢
    • 2017-08-10
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    相关资源
    最近更新 更多