用于将表与其他2个表中的1个相关联的数据库设计

时间:2014-12-19 02:37:07

标签: database-design class-table-inheritance shared-primary-key

我有一些包含一些用户和代理的数据库,并希望添加一个简单的消息系统。

所以我有以下简单的表格集:

[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 个答案:

答案 0 :(得分:3)

听起来用户和代理商都是超级类的子类,我称之为“#34; person"”。您可以为人员增加一个表,其中person_id为PK。然后,您可以将user_id替换为users表中的person_id。同样,将agent_id替换为代理程序表中的person_id。

请注意,在两个子类表,用户和代理中,person_id确实是双重职责。它是自己的表的PK,也是人员表的FK。这强制了用户和个人之间以及代理人和个人之间IS-A关系的一对一性质。

现在,你要做的就是在消息和人之间建立一种关系,嘿嘿!根据具体情况,消息与用户或代理之间存在关系。

这是一个名为" Class Table Inheritance"的设计模式的一个实例。和一个名为"共享主键"。您可以通过在Stackoverflow中访问具有相同名称的标签,或通过在网络上搜索Martin Fowler对该主题的处理来获得有关这些的更多信息。