用于将表与其他 2 个表中的 1 个相关联的数据库设计
Posted
技术标签:
【中文标题】用于将表与其他 2 个表中的 1 个相关联的数据库设计【英文标题】:Database design for relating a table to 1 of 2 other tables 【发布时间】:2014-12-19 02:37:06 【问题描述】:我有一个包含一些用户和代理的数据库,并想添加一个简单的消息系统。
所以我有以下一组简单的表格:
[users]
- user_id (PK)
[agents]
- agent_id (PK)
[message_threads]
- message_thread_id (PK)
[message]
- message_id (PK)
- message_thread_id (FK messages_threads.message_thread_id)
我没有来自消息和发布消息的个人的关系。
我有点卡住了,因为它可能是用户或代理。我认为这一定是一个常见问题,需要解决一个公认的模式,但我还没有找到这样的讨论。
我知道我有几个选择,但它们都有缺点。
选项 1: 我不喜欢一条消息可以将两个链接到不同的帐户。
[message]
- message_id (PK)
- message_thread_id (FK messages_threads.message_thread_id)
- user_id (FK users.user_id, ALLOW NULL)
- agent_id (FK agents.agent_id, ALLOW NULL)
选项 2: 这使得在 SELECT 的一列中获取所有消息变得很尴尬。
[message_by_user]
- message_id (PK)
- message_thread_id (FK messages_threads.message_thread_id)
- user_id (FK users.user_id)
[message_by_agent]
- message_id (PK)
- message_thread_id (FK messages_threads.message_thread_id)
- agent_id (FK agents.agent_id)
将用户和代理合并到一张表中是我不能做的一件事。这是一成不变的。
【问题讨论】:
【参考方案1】:听起来用户和代理都是我称之为“人员”的超类的子类。您可以再为人员提供一张桌子,以 person_id 作为 PK。然后,您可以在 users 表中将 user_id 替换为 person_id。同样,将agents 表中的agent_id 替换为person_id。
请注意,在用户和代理这两个子类表中,person_id 具有双重职责。它是它自己的表的PK,也是persons 表的FK。这加强了用户和个人之间以及代理和个人之间的 IS-A 关系的一对一性质。
现在,您所要做的就是在消息和人之间建立关系,嘿,快!消息与用户或代理之间存在关系,视情况而定。
这是一种称为“类表继承”和一种称为“共享主键”的设计模式的实例。您可以通过在 *** 中访问具有相同名称的标签或通过在网络上搜索 Martin Fowler 对该主题的处理来获取有关这些的更多信息。
【讨论】:
可以在How do I map an IS-A relationship into a database?找到关于这个设计的一个很好的讨论以上是关于用于将表与其他 2 个表中的 1 个相关联的数据库设计的主要内容,如果未能解决你的问题,请参考以下文章
FULL OUTER JOIN 将表与 PostgreSQL 合并
Oracle:将两个表与一个公共列加上第二个表中的一个附加列(最新生效日期)连接以选择其他列