在这些实体之间建立关系的最有效方法是什么?

时间:2019-12-04 19:14:31

标签: sql database database-design relational-database entity

我有一个包含如下实体的数据库:

1. User entity
2. Event entity (musical concert etc.)
3. Ticket entity
3. Notification entity
  • 通知实体与两个票证都有直接关系 和事件(1:N [票务/事件:通知])。
  • 通知将会 存储在数据库中,用户可以通过以下方式访问它们 通知标签。
  • 可以向用户通知相关的通知 到他的机票(例如“我们刚将您的机票发送给您!”)或关于 一些事件(例如“事件xy即将到来!请预留您的位置!”)。

我一直在考虑三种可能的解决方案:

a)通知实体具有以下结构:

id serial PRIMARY KEY, 
.
.
ticketId integer REFERENCES tickets(id),
eventId integer REFERENCES events(id))
userId integer REFERENCES users(id) // this is present in all three solutions;

通过这种方式,Notification实体同时拥有两个外键,但是一次只能填充其中一个(eventId或ticketId),另一个永远永远为空。

b)通知实体只有与通知本身相关的列,它不保存任何外键(userId除外)。
关系被提取到具有此结构的另外两个关系映射表中(对于“通知-票证”关系,同样适用于“通知-事件”,但外键引用事件除外)

id serial PRIMARY KEY,
notificationId integer REFERENCES notifications(id),
ticketId integer REFERENCES tickets(id));

这样,我们创建了类似于接口的内容,并且不让Notification实体知道有关该关系的任何信息(它仅具有与通知本身和userId相关的属性),并且还有两个映射该关系的表。

c)将Notification实体分为两个不同的实体
(TicketNotification,EventNotification),它们每个都具有相同的属性,但是在外键列中有所不同。

- TicketNotification - foreign key references ticketId
- EventNotification - foreign key references eventId

这样,我们有两个具有相同属性的表,只是在同一列中有所不同,对我而言,这似乎并不十分干燥。

我将非常感谢您提供的任何帮助和可能的解决方案,我可能会完全不赞成并从不良的角度来看待它。谢谢。

1 个答案:

答案 0 :(得分:2)

您不知道的是这个。您要声明的谓词是:

  • 每个通知与{事件|票证}

这需要互斥子类型群集。绝对,我们不想要可空的外键,其后果是可怕的。这是正确的解决方案。

参考

请检查以下答案以从概念上了解问题和解决方案:

关系数据模型

krstf

注意•表示法

  • 我所有的数据模型都以 IDEF1X 呈现,这是自1993年以来建立关系数据库建模的标准。

  • 我的 IDEF1X Introduction 对初学者来说是必不可少的阅读内容。

  • 有关理解和实现子类型

  • 的完整详细信息,请参见 Subtype