不同的用户类型/对象在同一个表中拥有内容 - 如何?

时间:2011-01-14 07:50:43

标签: database database-design schema

知道如何将不同的物体联系在一起吗?我试图实现的用例是评论通常由用户拥有。所以我有一个user_id。但我也有公司页面,公司在其页面上拥有内容,因此所有者是company_id。 (哪个是几个用户的管理员)

一种方法是拥有2个表user_comments和company_comments,但问题是我需要每个对象2个表,如果我添加更多用户类型,那么我需要多个表。我想要实现的是1个表:

comment_id PK  
owner_id (user id or company id or etc...)  - fk?

所以让我说我创建一个所有者表只是为了将所有用户类型链接在一起,列将是什么以获取这些或者还有其他方式?

2 个答案:

答案 0 :(得分:8)

人和组织是超类型/子类型关系中的一个很好的例子。它们并不完全相同,但它们并不完全不同。它们共享许多属性。人员和组织都有地址和电话号码,人员和组织都可以成为诉讼中的原告和被告,人员和组织显然都可以在您的系统中拥有评论。

要在SQL dbms中实现此功能,请将人员和组织共有的列放在一个名为“Parties”的表中。人们独有的列在人们的桌子上;组织特有的列在组织表中。使用视图(每个子类型一个)来隐藏实现细节;您的客户使用视图,而不是表格。

您可以使用超类型表“派对”中的密钥作为评论的所有者。 (我想。)

这是一个简化的例子。

create table parties (
    party_id integer not null unique,
    party_type char(1) not null check (party_type in ('I', 'O')),
    party_name varchar(10) not null unique,
    primary key (party_id, party_type)
);

insert into parties values (1,'I', 'Mike');
insert into parties values (2,'I', 'Sherry');
insert into parties values (3,'O', 'Vandelay');

-- For "persons", a Subtype of "parties"
create table pers (
    party_id integer not null unique,
    party_type char(1) not null default 'I' check (party_type = 'I'),
    height_inches integer not null check (height_inches between 24 and 108),
    primary key (party_id),
    foreign key (party_id, party_type) references parties (party_id, party_type)
);

insert into pers values (1, 'I', 72);
insert into pers values (2, 'I', 60);

-- For "organizations", a subtype of "parties"
create table org (
    party_id integer not null unique,
    party_type CHAR(1) not null default 'O' check (party_type = 'O'),
    ein CHAR(10), -- In US, federal Employer Identification Number
    primary key (party_id),
    foreign key (party_id, party_type) references parties (party_id, party_type)
);

insert into org values (3, 'O', '00-0000000');

create view people as
select t1.party_id, t1.party_name, t2.height_inches
from parties t1
inner join pers t2 on (t1.party_id = t2.party_id);

create view organizations as 
select t1.party_id, t1.party_name, t2.ein
from parties t1
inner join org t2 on (t1.party_id = t2.party_id);

使用dbms提供的任何功能使视图可更新。 (可能触发。)然后应用程序代码可以插入到适当的视图中。

答案 1 :(得分:3)

alt text