我有一个包含一些用户和代理的数据库,并希望添加一个简单的消息系统。
所以我有以下一组简单的表格:
[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)
我不能做的一件事是将用户和代理合并到一个表中。 这是一成不变的。
听起来用户和代理都是我称之为"人"的超类的每个子类。 你可以再有一个人表,person_id作为PK。 然后,您可以将 user_id 替换为用户表中的person_id。 同样,将代理表中的agent_id替换为person_id。
请注意,在两个子类表(用户和代理(中,person_id执行双重任务。 它是自己表的PK,也是人员表的FK。 这强制实施用户与人员之间以及代理与人员之间 IS-A 关系的一对一性质。
现在,您所要做的就是在消息和人之间建立关系,嘿,presto! 消息与用户或代理之间存在关系(视情况而定(。
这是一个名为"类表继承"的设计模式的一个实例,另一个称为"共享主键"的实例。 您可以通过访问Stackoverflow中具有相同名称的标签来获取有关这些内容的更多信息,或者通过搜索Web来查找Martin Fowler对该主题的处理。