2016-10-05 7 views
0

私はエンティティの階層構造を持っています。それぞれが複数の名前を持つことがあるので、別々の名前テーブルがあります。PostgreSQL:複数のテーブルに影響を与える制約

CREATE TABLE users (
    id SERIAL NOT NULL PRIMARY KEY, 
    -- some fields 
); 

CREATE TABLE entities (
    id SERIAL NOT NULL PRIMARY KEY, 
    parent_id INTEGER NOT NULL, 
    owner_id INTEGER NOT NULL, 
    FOREIGN KEY (parent_id) REFERENCES entities(id), 
    FOREIGN KEY (owner_id) REFERENCES users(id) 
); 

CREATE TABLE entity_names (
    id SERIAL NOT NULL PRIMARY KEY, 
    entity_id INTEGER NOT NULL, 
    name VARCHAR(30) NOT NULL, 
    FOREIGN KEY (entity_id) REFERENCES entities(id) 
); 

をそして、私は(同じparent_idowner_idで、もちろん)重複した名前を持つエンティティがないことを確認する必要があり、次のように簡略化SQLスキーマが見えます。

SELECT COUNT(t.id) 
    FROM entity_names n 
    JOIN entities e ON n.entity_id = e.id 
    WHERE e.parent_id = 123 and e.owner_id = 456 and n.name = 'foo' 

をしかし、それはデータベースでこの制約を実現することが可能(およびSANE)だ場合、私は思ったんだけど:

私はこのようなクエリでentity_namesに名前を追加する前に、その権利を確保することができますか?

答えて

1

Postgresにはマルチテーブルの制約はありませんが、クエリをtag_namesに置くことによってcheckの制約をエミュレートできます。

0

entity_identity_namesのテーブルは、entitiesテーブル内の行を識別する。特定のエンティティのために重複した名前を追加しようとすると、次のようになります。

INSERT INTO entity_names (entity_id, name) VALUES (2, 'Name1'); 

各エンティティは、それ自身の親と所有者を持っていますが、まだ一意idで識別されます。したがって、私はあなたの問題をoverthinkingていると思うと、クロステーブル制約は必要ありませんが、シンプルUNIQUE 1:

CREATE UNIQUE INDEX ON entity_names (entity_id, name); 

これはあなたのエンティティと同じparent_idowner_idとは2つのレコードが存在しないと仮定しています - 私には意味があるとは思えないので、私にはの候補キーのように思えます。それはその後、トリガーを返す関数を作成し、そこにチェックを行う(私のためにほとんど信じ)の場合は、実際にはない場合


、その後、entity_namesテーブルの上にBEFORE INSERTトリガーを作成します。

関連する問題