2

ファイル(画像、PDFなど)を保存する次のテーブルがあります。

CREATE TABLE `tbl_file` (
    `id` INT(10),
    `size` FLOAT,
    `name` VARCHAR(45),
    `type` VARCHAR(16),
    `content` BLOB,
    `date_time` TIMESTAMP,
    PRIMARY KEY (`id`) 
)

ファイル (tbl_order & tbl_payment) を持つテーブルは多数ありますが、ファイル (tbl_file) を格納するために 1 つのテーブルのみを使用したいと考えています。ただし、一部のテーブルでは、各行に複数のファイルが含まれる場合があります。

たとえば、1 つの注文 (請求書、PO、BL、契約書) に対して複数のファイルが存在し、支払いごとに複数のファイルが存在する場合などがあります。

そこで、複数のファイルを持つテーブルごとに次のジャンクション テーブルを作成しました (外部キー コードは含めませんでした)。

CREATE TABLE `tbl_order_file` (
    `order_id` INT(10),
    `file_id` INT(10),
    PRIMARY KEY (`order_id`, `file_id`),
)

CREATE TABLE `tbl_payment_file` (
    `payment_id` INT(10),
    `file_id` INT(10),
    PRIMARY KEY (`payment_id`, `file_id`),
)

ここでの問題は、1 つのファイルを両方のテーブルに関連付けることができることです。問題ではなく利点かもしれませんが、これを行うためのより良い方法があるかどうか、またはファイルを制限して 1 つのテーブルでのみ参照されるようにする方法を見つけたいと思います。

MySQLをinnodbエンジンで使用しています。

4

2 に答える 2

2

これを強制するための制約を宣言する1つの方法は、tbl_fileの各行がファイルのタイプ(「O」または「P」(または将来的には他のタイプ))としてマークされていることを確認することです。

CREATE TABLE `tbl_file` (
    `id` INT(10),
    `file_type` CHAR(1) NOT NULL,  -- must be 'O' or 'P'
    `size` FLOAT,
    `name` VARCHAR(45),
    `type` VARCHAR(16),
    `content` BLOB,
    `date_time` TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY (`id`, `file_type`)
);

次に、各従属テーブルは、そのすべての行にそれぞれのタイプでマークを付けるように強制します。したがって、tbl_order_fileの行は、同じfile_typeを持つtbl_fileの行のみを参照できます。

CREATE TABLE `tbl_order_file` (
    `order_id` INT(10),
    `file_id` INT(10),
    `file_type` CHAR(1) NOT NULL, -- must be 'O'
    PRIMARY KEY (`order_id`, `file_id`),
    FOREIGN KEY (`file_id`, `file_type`) REFERENCES `tbl_file` (`id`, `file_type`)
);

同様にtbl_payment_fileの場合:

CREATE TABLE `tbl_payment_file` (
    `payment_id` INT(10),
    `file_id` INT(10),
    `file_type` CHAR(1) NOT NULL, -- must be 'P'
    PRIMARY KEY (`payment_id`, `file_id`),
    FOREIGN KEY (`file_id`, `file_type`) REFERENCES `tbl_file` (`id`, `file_type`)
);

特にMySQLの1つの問題は、MySQLがテーブル定義でfile_typeの値を制限できるようにするCHECK制約をサポートしていないことです。トリガーまたはアプリケーションコードでそれを行う必要があります。


コメントを再確認してください。

file_typeを使用せずにソリューションを使用したいとします。将来、どのような問題が発生しますか?

さて、元の質問ですでに述べたように、制約なしに、ファイルテーブルの1つの行が複数のジャンクションテーブルによって参照されることを妨げるものは何もありません。また、アプリケーションにとって異常なデータになる可能性があります。

一方、特定のファイルが注文と支払いの両方に関係する場合は、その柔軟性を許可することをお勧めします。複数の参照を維持する機能がない場合は、そのようなファイルの複製コピーを作成して、それらを複数のカテゴリに分類できるようにする必要があります。

もう1つの問題:これらの解決策のいずれも、アプリが子のない行をファイルテーブルに挿入することを妨げません。つまり、ジャンクションテーブルからの参照がないファイルです。

于 2012-11-24T20:50:14.457 に答える
1

まず第一に、テーブル間に多対一の関係がある場合は、 に主キーを作成しないでくださいorder_id。すべてのファイルを 1 つのテーブル ( tbl_file) に配置し、2 つの外部キー フィールドをテーブルに追加します:order_idとは、またはテーブルpayment_idのそれぞれのエントリを参照します。paymentorder

したがって、エントリ (複数のファイルを持つ 1 つの支払いの場合) は次のようになります。

id  payment_id  order_id    size    name        type        content     date_time
1   1           null        434     File.txt    text/plain  <blob>      24.11.2012
2   1           null        131     File2.txt   text/plain  <blob>      24.11.2012
于 2012-11-24T20:40:27.727 に答える