重度多态表

时间:2016-07-13 14:31:14

标签: sql postgresql

我有一张桌子events。每个活动都可以启动'和/或'收到'通过UserVisitorTeam,我想对这些关联进行建模。

我在想像

Event
type
user_actor_id
user_subject_id
visitor_actor_id
visitor_subject_id
team_actor_id
team_subject_id

演员/主体是指发起/接收事件的人

这是正确的做法吗?好像我存储了大量冗余数据,我不得不做很多条件连接,因为它想查询表并得到像

这样的结果
actor_id:
actor_type (either user, visitor or team)

更新:

然后我会像这样做一个选择查询

    select
  coalesce(ua.id, va.id, ta.id) as actor_id,
  (CASE WHEN ua.id IS NOT NULL THEN 'user' WHEN va.id IS NOT NULL THEN 'visitor' ELSE 'team' END) as author_type,
  (CASE WHEN ua.id IS NOT NULL THEN ua.display_name WHEN va.id IS NOT NULL THEN va.name ELSE ta.name END) as author_name,
  (CASE WHEN ua.id IS NOT NULL THEN ua.avatar WHEN va.id IS NOT NULL THEN va.avatar ELSE ta.icon END) as author_name
from events e
  left join users ua on ua.id = e.user_actor_id
  left join users us on us.id = e.user_sibject_id
  left join visitors va on va.id = e.visitor_actor_id
  left join visitors vs on vs.id = e.visitor_sibject_id
  left join teams ta on ta.id = e.team_actor_id
left join teams ts on ts.id = e.team_sibject_id

1 个答案:

答案 0 :(得分:2)

我会做以下事情:

create table tPeople ( -- contains as many rows as there are people
   int ID,
   nvarchar(max) Name
)

create table tRole ( -- contains three rows: Visitor, Team, User
   int ID,
   nvarchar(max) Name
)

create table tPeopleRole ( -- associates people with roles
   int People_ID, -- FK to tPeople.ID
   int Role_ID -- FK to tRole.ID
)

create table tEvent (
   int ID,
   int Type_ID,
   int InitiatedPeople_ID, -- FK to tPeople.ID
   int ReceivedPeople_ID -- FK to tPeople.ID
)

然后,您可以查询tEvent并加入tPeople / tPeopleRole以获取发起人和收件人的姓名和/或角色。