【发布时间】:2019-09-20 08:59:50
【问题描述】:
我有 2 个表,它们可以提供代表某些项目的相关记录,这些项目大致由以下类图建模。这是高度简化的,每个来源都是不同的复合模型。
从数据库而不是 OOP 的角度考虑这一点,项目表包含任何可能项目的记录。如果你想知道一个widget的定义是什么,或者gewgaw的定义是什么,这就是item表的用途。 Source* 表代表物理项目的位置类型,每条记录代表一个特定位置。 Source* 表还包含大量不相交的信息。
源中包含特定小部件或 gewgaws 实例的集合,即 Source1 有 10 个不同的小部件和 3 个不同的 gewgaws,而 Source2 目前可能只包含 1 个不同的小部件。
为了表示这种关系,如果只存在 1 个源表,我通常会使用以源 id 和项目 id 作为外键的数据透视表。
我对如何表示第二种类型的商店的第一个想法是创建另一个数据透视表,即 item_source2,然后当我需要汇总库存数量时,在 item_source1 和 item_source2 之间执行联合。
这似乎不是特别优雅,违反了 DRY,并在可能不需要的地方引入了一个联合。
下一个想法是将 item_source1 表概括为也具有 Source2.id 键的字段。实际上,对于任何给定记录,Source1.id 或 Source2.id 中只有一个是有效引用,而另一个必须为 null - 特定小部件不能同时存在于 2 个位置。
从编程的角度来看,我可以创建逻辑来测试和实施这种设计,但我很清楚这不是最佳实践,但我看不出如何通过数据库设计来解决这个问题。
我将在 Laravel 模式中实现这一点,但在这里理解设计方面可能更为关键。
【问题讨论】:
-
我将对问题进行一些编辑以提高质量,无论它是否会关闭,我会报告在我的最终实现中是否出现继承和组合之间的任何显着差异.
-
在我的上一条消息中,我的意思是“两种定位的东西”。所以表相关(x,事物),事物(事物,p1,...),pocket_thing(事物,pt1,..)和货架_事物(事物,st1,...)。链接的答案是关于 subtyping,而不是 OO。也许我误解了。 PS 不要制作 OO 模型,然后将其简单地映射到关系数据库。 (尽管这是 ORM 所做的。)这不是您的业务的关系设计,而是您的业务的 OO 设计的关系设计。 (关系设计是确定必要且足够的谓词/表来记录描述您的情况/状态的语句。)
-
我想对此表示赞同,但除了您的“说明 [...]”之外,我无法详细了解文本描述的大部分内容。尽管我主要可以根据您在 DDL 中给出的设计对其进行逆向工程。尽管您的 DDL 实际上并不正确,但您确实非常有帮助地明确地说“类似”和“某种 [...]?”。尽管给出更少的单词加上 DDL 会好得多,但它应该是是 DDL,并添加了清晰的完整句子重新约束,而不会通过将它们称为 FK 或 PK 来歪曲它们。使用足够的单词、句子和对部分示例的引用。
-
避免对“子类型化”可能意味着什么的先入之见,因此当子类型化习语可以应用时。如果我们有子集,那么我们就有子类型。您的 business 子集/类型项目按它们所在的来源、按他们持有的项目的来源和按它们所在的# 的来源等。任何 FK 都涉及一个子类型。 nvogel's & my subtypes, disjoint & not. Ours & your "other must be null" radio-button-FKs design. 根据我的第一个 cmets,这是“对许多表的 FK”作为“子类型”的反模式的情况。 (Google。)祝你好运。
标签: database-design database-schema