【问题标题】:Structuring Relational databases - combining similar and related tables结构化关系数据库 - 组合相似和相关的表
【发布时间】:2020-01-31 01:23:26
【问题描述】:

我习惯于看到不同实体存储在不同表中的关系数据库。 (简单示例:国家、州、城市)。最近,我看到更多不同但相似的实体被捆绑到同一个表中并结合不同视图的案例。我认为这可以节省表格和数据访问程序(可能以牺牲清晰度和灵活性为代价)。重新阅读规范化数据库的定义,我不认为这违反了任何规则,但它似乎不那么直观,并且通过回到旧的大型机“杂项”表,您可以在其中放置在设计阶段忘记的任何内容。请参阅下面的 2 个示例:多表解决方案与单表解决方案。这种现象是数据或编程设计模式的一部分并且有名称吗?

【问题讨论】:

  • 能否请您更新您的帖子并澄清您的问题是什么?此外,它可能更适合Database Admins StackExchange 站点。
  • 您能否阐明您的意图并可能提供一个具体的例子?我不知道您是在问是否应该对表格进行规范化或非规范化,或者问题是否与完全不同的东西有关。此外,正如@devlincarnate 所说,这可能是关于数据库管理员堆栈交换的更好问题。

标签: sql normalization


【解决方案1】:

如果您有小型专用表,那么数据库可以轻松地将所需的表缓存在内存中。

如果您将原本很小的表塞进一张表中,数据库将不知道哪些条目对缓存很重要,哪些不重要。

更重要的是,出现错误的机会更多,因为您可能会无意中输入错误的类型代码并最终加入不相关的内容,而没有 RI 或类型检查来警告您。如果您使用小型专用表,则可以指定 RI 约束。

回想一下我看到单个怪物查找表模式完成的地方,我认为吸引人的是开发人员可以添加更多种类的条目而无需 DBA 干预来创建更多表。有很多开发人员,只有少数 DBA,这就是 DBA 避免每次引入新类型的查找条目时都必须创建专用查找表的方法。 (显然,在 dev 中授予创建表权限对于那里的 DBA 来说是不可接受的。)

对于难以更改数据库架构的环境,这似乎是一种解决方法。但另一个考虑因素是,如果所有条目都在一个表中,国际化可能会更容易。

并且该模式有一个既定名称,称为One True Lookup Table。链接的文章将其称为反模式,并列出了该技术的更多缺陷。以下是文章中的项目符号列表:

  • 这让 SQL 看起来很丑。

  • 许多语句需要多次连接到查找表。额外的连接列使语句看起来更大更可怕。使用单独的查找表时会有相同数量的连接,但这些连接会更简单。

  • 对同一个表的多次引用可能会使您难以确定执行计划中发生了什么,因为您将在那里看到那些重复的引用,并且必须引用谓词才能理解表引用的上下文。如果您使用单独的查找表,则在执行计划的任何时候都可以清楚地看到您引用的是哪个表。

  • 您不能对这种类型的表使用外键。从技术上讲,如果您愿意将两列(lookup_type_code 和lookup_key)都放在表中,则可以,但您不会,因为它很难看。这意味着您的数据完整性很有可能会随着时间的推移而受到损害。为单个查找表设置外键非常容易,因此可以保护您的数据。

  • 很难控制表格的内容。它是共享资源,因此检查约束和触发器是有问题的。如果您需要用户拥有不同的权限,这取决于他们正在处理的查找,事情会变得一团糟。使用单独的查找表将非常容易。

  • 如果您需要对一种引用类型进行更改,例如扩展键或值的大小,则会影响所有引用数据。使用单独的查找表可以隔离更改。

  • 随着时间的推移,许多参考表会包含额外的数据。要对此建模,您需要从该共享查找表中分离出参考数据,或者开始添加可选列以应对“一次性”问题。对于单独的查找表,这样的更改非常简单。

  • 数据类型很重要。您应该始终使用正确的数据类型,因为它会减少所需的数据类型转换次数。隐式数据类型转换是等待发生的错误!

  • 性能可能是 OTLT 方法的一个问题,因为优化器很难对数据做出正确的判断。优化器关心基数,但如果您要处理大量行,其中大部分在任何特定上下文中都无关紧要,则可能很难做出决定。优化器还关心高/低值,但这些值与任何一次查找都不相关,而是共享的。我们还提到您可能不会对该数据使用外键,这将减少优化器在做出决策时所拥有的信息量。您可能人为地使列成为可选的,实际上是强制性的,键必须有值,但是哪一列?我想你明白了。

【讨论】:

  • 更多错误机会 = 好点......而且所有旧的都是新的......“通过回到旧的大型机“杂项”表,您可以在其中放置任何在设计阶段被遗忘的东西”。我喜欢你的名字“怪物查找表模式”。
  • @Mustapha:记得有一个名字,celko写了一篇关于它的文章。
【解决方案2】:

我认为,如果您只需要名称字典(用于拼写检查或类似的东西),第二种方法就足够了。否则,如果对象有一些额外的特定字段,则第二种方法很糟糕。

【讨论】:

    猜你喜欢
    • 2023-03-15
    • 2013-09-13
    • 2021-08-24
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    相关资源
    最近更新 更多