SQL - 具有多个" One"的一对多的最佳实践。表

时间:2018-03-07 20:08:13

标签: sql postgresql database-design django-models

我的场景很难在一个简短的标题中解释,所以这是一个例子:

我有多张桌子" birthday_event"," meeting_event"," dinner_event"他们在一张名为"与会者"的桌子上有多个孩子。从本质上讲,我有3个不同的一对多关系:" birthday_event"有很多"与会者"," meeting_event"有很多"与会者"等等。

每个"事件"表有自己的特定属性。通常,我会有一个外键" event_id" in"与会者"所以关系很稳健,但是有很多不同的事件表可以实现" event_id"属性,所以它不是一个严格的外键,如果这是有道理的。

我的理解是,当建立外键时,它强烈地链接到单个表中的属性,而不是像示例中的3个事件表那样的多个表。我也理解外键不应该为空,以确保数据的健壮性。那么,在我的许多活动和许多与会者之间建立稳固关系的最佳做法是什么?

我可能的解决方案:

  • 使用" event_id"作为"与会者的正常属性"表,以便所有三个事件都可以使用"与会者"。缺点是这只是一个伪外键。

  • 创建3个不同的"与会者"每个活动的表格,所以会有" birthday_attendee"," meeting_attendee"和" dinner_attendee"表。缺点是更多的表格。

  • 使用" event_attendee"等联合表不起作用,因为这个表也会有链接单个外键的问题" event_id"多个事件表。

这些或其他解决方案中的哪一个是理想的数据库设计可理解,可扩展和高性能?

顺便说一句,我打算使用Django后端对这些数据库表进行模型操作,如果这对答案有任何影响的话。

2 个答案:

答案 0 :(得分:1)

Postgres为您提供了一个解决方案,具有表继承功能。它在documentation中有详细描述。

基本上,您可以拥有events表,然后有三种不同类型的事件。您可以对特定事件或父events表具有外键引用。

例如,您可以拥有通用的eventAttendees表。这将有events的外键。但引用可以是任何特定的事件类型。然后,特定事件类型将包含event(可能只有eventId)的公共列,并且只包含该特定类型的列。

答案 1 :(得分:0)

听起来你可能会遇到一些轻微的设计问题,所以在我回答当前背景下的问题之前,我先解决这个问题。

event可以超过以下其中一种:生日,会议,晚餐吗?如果没有,那么event表应该具有en event_type列,该列确定它是哪种事件类型。然后,event表应包含所有事件中通用的所有列。对于额外的列,您可以使用带事件表的0 / 1-1的birthday_event,meeting_event和dinner_event表。

那么0 / 1-1是什么?一对一关系,其中一方可以为空。所以是的,外键可以为空可以。可以为空的外键只是意味着可能存在关系,也可能没有关系,但必须的关系必须与外键约束的表相对应。

由于您已将其标记为PostgreSQL,因此我将提供另一种选择 - 一个event表和event_type列,event_detailsjsonb。这是一个相对较新的PostgreSQL类型,允许您将JSON数据存储在一个字段中,然后查询该列,就像它是一个深层嵌套的列数组。 (见PostgreSQL documentation on the json/jsonb types

我会说,无论你是否有一个包含所有常用信息的中央事件表,或者你将信息存储到三个卫星表中,你仍然希望使用event_attendees表来存储与会者。与会者与事件有关,他们不关心事件类型。