2011-01-14 10 views
4

さまざまなオブジェクトをどのように関連付けることができますか? Usecase私は達成しようとしていますコメントは、通常、ユーザーが所有しています。だから私はそれのためのuser_idを持っています。しかし、会社のページでは、会社のページでコンテンツを所有しているので、所有者はcompany_idです。 (複数のユーザーによって管理されます)異なるユーザータイプ/オブジェクトが同じテーブル内のコンテンツを所有しています - どのようにですか?

1つの方法は、2つのテーブルuser_commentsとcompany_commentsを持つことですが、問題は次にオブジェクトあたり2つのテーブルが必要です。ユーザータイプを追加すると複数のテーブルが必要になります。列はこれらのすべてで取得することや他のいくつかの方法があるだろうかだから、

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

のは、私は一緒にすべてのユーザータイプをリンクするために、所有者のテーブルを作成するとしましょう、:どのような私が達成したいことがある1台です?

答えて

2

alt text

6

人と組織は、スーパータイプとサブタイプの関係の良い例です。彼らは同一ではありませんが、全く異なるわけではありません。それらは多くの属性を共有します。人と組織の両方に住所と電話番号があり、人と組織の両方が訴訟の原告と被告になることができ、人と組織の両方があなたのシステムにコメントを持つことができます。

これをSQL dbmsに実装するには、人と組織の両方に共通の列を、たとえば「締約国」と呼ばれる1つのテーブルに配置します。人々に特有の列は人のテーブルに入ります。組織固有の列は組織表に入ります。実装の詳細を隠すには、サブタイプごとに1つのビューを使用します。クライアントはビューを使用し、表は使用しません。

あなたのコメントの所有者として、スーパータイプテーブルの「締約国」のキーを使用します。 (私は思う)

ここでは簡単な例を示します。

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が提供する機能を使用して、ビューを更新可能にします。 (おそらくトリガします。)そして、アプリケーションコードを適切なビューに挿入するだけです。私は `pers`と` orgs`で冗長「固定値」 `party_type`列を持っていることによって、あなただけの` parties`.`party_idを保ち対(FKの整合性を適用できることを好き

+0

+1 'を' pers'と 'orgs'に複製した' party_id'を可能にするプライマリとして - 'party_type'がなくてもデータ定義で許可されます)。問題は、 'parties'テーブルが(4、 'I'、 'x')と(4、 'O'、 'y')を存在させることができるので、 'party_type'の冗長性が必要なことです。したがって、クエリには 'party_type'を含める必要があります。しかし、PKが 'id'であり、制約が' uniq(id、type) 'だった場合、OK – aneroid

+1

*"当事者テーブルは(4、 'I'、 'x')と(4、 'O '、' y ') "*:そうではありません。それを試してみてください。 (party.party_idには独自の制約があります。) "party_type"列は、SQLの欠点を克服するために必要です。リレーショナル・モデルはそれを必要とせず、CREATE ASSERTIONをサポートするSQL dbmsはそれを必要としません。しかし、アサーションをサポートするSQL dbmsはありません。 –

+0

"_(parties.party_idには一意の制約があります)_" - うん、申し訳ありませんが、それを逃しました。したがって、クエリは 'party_type'を必要とせず、構造体は期待どおりに機能します+1 – aneroid

関連する問題