2

ユーザーが指示書(.pdf、.doc、.txt)をアップロードするか、指示のテキストを提供できるようにする必要があることを示すWebアプリが必要です。ユーザーはドキュメントをアップロードしてテキストを提供することも、どちらか一方を実行することもできますが、何かを実行する必要があります(null許容ではありません)。これはデータベースでどのように設計されますか?これは完全なサブタイプと見なされますか(以下を参照)?

ここに画像の説明を入力してください これは大きなスキーマのごく一部なので、この特定の質問に必要だと感じたものを投稿しました。

4

4 に答える 4

4

Ypercubeの答えは問題ありませんが、実際には、個別のテーブルを保持しながら、宣言型の整合性によって純粋に実行できます。秘訣は、延期された循環外部キーを少しの創造的な非正規化と組み合わせることです。

ここに画像の説明を入力してください

CREATE TABLE Instruction (
    InstructionId INT PRIMARY KEY,
    TextId INT UNIQUE,
    DocumentId INT UNIQUE,
    CHECK (
        (TextId IS NOT NULL AND InstructionId = TextId)
        OR (DocumentId IS NOT NULL AND InstructionId = DocumentId)
    )
);

CREATE TABLE Text (
    InstructionId INT PRIMARY KEY,
    FOREIGN KEY (InstructionId) REFERENCES Instruction (TextId) ON DELETE CASCADE
);

CREATE TABLE Document (
    InstructionId INT PRIMARY KEY,
    FOREIGN KEY (InstructionId) REFERENCES Instruction (DocumentId) ON DELETE CASCADE
);

ALTER TABLE Instruction ADD FOREIGN KEY (TextId) REFERENCES Text DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE Instruction ADD FOREIGN KEY (DocumentId) REFERENCES Document DEFERRABLE INITIALLY DEFERRED;

テキストの挿入は次のように行われます。

INSERT INTO Instruction (InstructionId, TextId) VALUES (1, 1);
INSERT INTO Text (InstructionId) VALUES (1);
COMMIT;

次のようなドキュメントの挿入:

INSERT INTO Instruction (InstructionId, DocumentId) VALUES (2, 2);
INSERT INTO Document (InstructionId) VALUES (2);
COMMIT;

そして、次のようにテキストとドキュメントの両方を挿入します。

INSERT INTO Instruction (InstructionId, TextId, DocumentId) VALUES (3, 3, 3);
INSERT INTO Text (InstructionId) VALUES (3);
INSERT INTO Document (InstructionId) VALUES (3);
COMMIT;

ただし、命令のみを挿入しようとすると、コミットに失敗します。

INSERT INTO Instruction (InstructionId, TextId) VALUES (4, 4);
COMMIT; -- Error (FOREIGN KEY violation).

「不一致タイプ」を挿入しようとすると、コミットでも失敗します。

INSERT INTO Document (InstructionId) VALUES (1);
COMMIT; -- Error (FOREIGN KEY violation).

そしてもちろん、Instructionに不正な値を挿入しようとすると失敗します(今回はコミット前)。

INSERT INTO Instruction (InstructionId, TextId) VALUES (5, 6); -- Error (CHECK violation).
INSERT INTO Instruction (InstructionId) VALUES (7); -- Error (CHECK violation).
于 2012-05-06T05:55:32.653 に答える
2

これは、宣言型参照整合性だけでは実行できないと思います。設計にこれらの3つの別個のテーブルがある場合はそうではありません。

すべての挿入/削除/更新操作がそのような要件を強制するトランザクション(ストアドプロシージャ)内で実行されることを確認する必要があります-したがって、Instruction他の2つのテーブルのいずれかに相対行がない行がテーブルに挿入または残されることはありません。


null許容フィールドを使用してもかまわない場合は、3つのテーブルを1つにマージして、CHECK制約を使用できます。

CREATE TABLE Instruction
( InstructionID INT          NOT NULL
, Text          VARCHAR(255) NULL
, Filepath      VARCHAR(255) NULL
, PRIMARY KEY (InstructionID)
, CONSTRAINT Instruction_has_either_text_or_document 
    CHECK (Text IS NOT NULL OR FilePath IS NOT NULL)
) ;
于 2012-05-04T22:36:17.137 に答える
1

ユーザーがテキストを送信した場合、アプリケーションはそれを.txtファイルとして保存できますか?この方法では、ファイルの処理についてのみ心配する必要があります。

于 2012-05-04T21:52:15.273 に答える
0

ここで何かが少し気分が悪い

  1. UserIDこのスキーマに はないため、Instructionテーブルに追加する必要があります。

  2. Instructionユーザーが何もアップロードしない場合、テーブルにはそのユーザーのエントリはありません(すべきです) 。

  3. したがって、問題は、前述のように、これら3つのテーブルに制約を課すことではありません。

  4. この構造をロードするときは、ストアドプロシージャやトランザクションを使用して、子レコードの少なくとも1つにデータが入力されていることを確認してください。ただし、これは、ユーザーが何かをアップロードする必要があるというビジネス要件とは関係ありません。

于 2012-05-05T12:13:18.773 に答える