Personの関係があり、それとEmployee which IS-A Person、Manager、which = ISA 人も。
ManagerがEmployeeではないこと、およびその逆を確実にする正しい方法は何ですか?
質問をするときに何を探すべきかわかりませんでした。おそらく、その質問に対する答えはすでに存在しているでしょう。
Person (PK:personId, name, ...);
Manager(PK:#personId); -- A manager ISA person
Employee(PK:#personId); -- An employee ISA person
INSERT INTO Person (1,'Peter',...);
INSERT INTO Manager (1); -- OK
INSERT INTO Employee(1); -- Nope, error.
人は同時に従業員とマネージャーになることはできません。
多分別の例で。
Shape (shapeId);
Rectangle(shapeId, width, length);
Circle(shapeId, radius);
円は形状であり、長方形は形状です。長方形が円ではないことを確認するにはどうすればよいですか(またはその逆)。
したがって、私の質問、独自の「IS-A」関係を実施する正しい方法は何ですか?
Application
およびPerson
リレーションを参照するリレーションPosition
は、一意のpersonID
属性を持ち、単一の属性positionID
を持つ必要があります。一度に1つだけの値。
ここに2つの別々の質問があり、これに答えることができません。
それらの1つはモデリングに関するもので、もう1つは整合性に関するものです。それは答えるのを難しくします
RDBMSのスコープに(1:1)のIS-Aが表示される場合は常に、単純な外部キーを考える必要があります。
CREATE TABLE person (
person_id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
-- stuff
);
CREATE TABLE manager (
manager_id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
person_id int REFERENCES person,
-- stuff
);
CREATE TABLE employee (
manager_id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
person_id int REFERENCES person
-- stuff
);
多重継承(M2M)がある場合は、リンクテーブルを使用します。
"マネージャーは従業員ではなく、その逆も同様です"
これは、次のいずれかの場合にのみ実行できます
CHECK
制約を実装しますTRIGGER
を使用しますそれがあなたの唯一の選択肢です。関係が1つのテーブルに格納されている場合。
CREATE TABLE relationships (
id_person REFERENCES person,
id_manager REFERENCES manager,
UNIQUE ( greatest(id_person,id_manager), least(id_person,id_manager) )
);
そして、それはうまくいくはずです。
これらの非常に単純なケースは、現実の世界では、たとえばn階層の関係など、より大きな問題に直面することがよくあります。マネージャーにマネージャーがいる場合はどうなりますか。それぞれに個別のテーブルを作成するプロセスは、非常に速くなります。
あなたはこれをすることができます、
CREATE TABLE persons (
id_person int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
id_superior REFERENCES persons
; stuff
);
ただし、この場合、id_person
とid_superior
がグラフに循環関係を作成しないようにする簡単な方法はないため、さらに賢くする必要があります...
そしてそれが、この種の質問がより多くの情報を必要とする理由です。