“附加”表的正确名称是啥?
Posted
技术标签:
【中文标题】“附加”表的正确名称是啥?【英文标题】:What's the proper name for an "add-on" table?“附加”表的正确名称是什么? 【发布时间】:2010-12-31 11:56:48 【问题描述】:我有一个表 a
主键 id
和一个表 b
代表 a
的专用版本(它具有与 a
相同的跟踪特征,加上一些特定于它的b
-ness——后者是存储在b
中的所有内容。如果我决定通过让b
的主键也是a.id
的外键来表示这一点,那么b
与a
相关的正确术语是什么?
现实世界的示例可能是带有student
和teacher
附加表的person
表。 student
也可能是 teacher
(例如 TA),但它们都是相同的 person
。
我将其称为a
的“子表”,但我已经将其用作“详细表”的同义词,例如采购订单上的行。
【问题讨论】:
我们能否举一个真实的例子来说明重构前后 A 和 B 的样子? 没有重构,因此没有之前或之后。 :) 我只是询问设计的名称,特别是b
与 a
相关的名称。
【参考方案1】:
b 与 a 相关的正确术语是什么?
表B
是表A
(父表)的子表,因为要让记录存在于子表中,它必须首先存在于父表中。
表的建模应基于一对多或多对一的关系,具体取决于上下文,并且在这些选项中,它们可以是可选的,也可以是必需的。对于所涉及的每个表,将两组列表链接在一起的表将以多对一的方式与其他表相关。例如,users
、groups
和 user_groups_xref
- user_groups_xref
可以支持 user
记录的许多特定用户实例,以及与 groups
表的相同关系。
一对一关系没有意义 - 绝不应该允许这些关系存在,因为它应该只是一个表。
【讨论】:
有一点。person
可能不是 student
——那为什么还要在 person
中设置学生数据列呢?而且,如果您有多种类型的专业,您的表很快就会有很多列并且通常是稀疏的。这更有条理。否则,如果您按照 Bill 的链接走具体路线,您最终会出现数据重复并且不得不担心同步问题。
@Kev:这就是类型代码列(带有外键)的用途。或者可以将关系建模为类似于用户/组。这一切都取决于业务规则。
如果person
能够成为一种以上的特殊类型,则不会。【参考方案2】:
你的设计听起来像Concrete Table Inheritance。
我将表 B
称为 扩展表 A
的具体表。
这种关系是一对一的。
其他答案建议仅存储特定于扩展表的列。这种设计将被称为Class Table Inheritance。
【讨论】:
将其缩短为调用b
只是a
的扩展 是否不合适? (即,这在 SQL 表上下文中是否有其他含义?)
是的,类表继承就是其中之一。起初我让它听起来像混凝土,但在尼尔的回答让我意识到我没有清楚地描述它之后纠正了这一点。
当然,您的替代措辞很好。有关如何很好地使用这些模式的更多信息,请获取 Martin Fowler 的书 PofEAA。
PostgreSQL 支持执行此操作的表单表继承,但无论如何它都不是 SQL 标准。
@fennec:标准 SQL 中有表继承语法,但 PostgreSQL 不遵循标准。另外,PostgreSQL 的实现在很多情况下都会导致异常,所以我不建议使用它。【参考方案3】:
正如 Neil N 所说,如果您通过外键引用表 B 中的表 A,则不应在两个地方都有列。
您的描述听起来有点像面向对象编程中的继承。就个人而言,在这种情况下,我不使用任何特定的命名约定。我将 A 命名为它是什么,我将 B 命名为它是什么。例如,我可能有:
CREATE TABLE People
(
people_id INT NOT NULL,
first_name VARCHAR(40) NOT NULL,
last_name VARCHAR(40) NOT NULL,
...
CONSTRAINT PK_People PRIMARY KEY CLUSTERED (people_id)
)
GO
CREATE TABLE My_Application_Users
(
people_id INT NOT NULL,
user_name VARCHAR(20) NOT NULL,
security_level INT NOT NULL,
CONSTRAINT PK_My_Application_Users PRIMARY KEY CLUSTERED (people_id),
CONSTRAINT UI_My_Application_Users_user_name UNIQUE (user_name)
)
GO
这只是一个例子,所以请不要告诉我我的姓名列太长或太短,或者它们应该允许 NULL 等;)
【讨论】:
我两个都没有。b
仅包含特定于 b
的内容,以及返回到 a
的 FK/PK 以获取更多一般信息。
是的,很像OOP继承。【参考方案4】:
好吧,这有点离题了,但首先,为什么 B 拥有 A 的所有列?它应该只包含添加的列,特别是当您使用外键引用 A 时。
“添加”记录通常称为“详细信息”
例如,假设我的表 A 是“汽车”,我的表 B 将是“CarDetails”
【讨论】:
这不是详细信息表,因为 FK 是 PK。这是 1:1 的关系,而不是 M:1。 无论是 1:1 还是 1:M,它仍然是一个详细信息表。以上是关于“附加”表的正确名称是啥?的主要内容,如果未能解决你的问题,请参考以下文章