すべての3つの支払いタイプは共通点がいくつかあります。それらはすべて口座番号、金額、タイムスタンプ、支払いタイプ、およびある種の取引識別子を持っています。すべての共通属性は1つのテーブルに格納されます。 (彼らは、アプリケーションに依存している、と私はあなたのアプリケーションを知らないので、データ型のいくつかは、意図的にナイーブです。)
create table payment_types (
payment_type_code char(2) primary key,
payment_type varchar(8) not null unique
);
insert into payment_types values
('Ca', 'Cash'),('Cr', 'Credit'),('Ba', 'Bank');
create table payments (
transaction_id integer primary key,
account_code varchar(5) not null, -- references accounts, not shown
amount_usd numeric(5,2) not null,
payment_type_code char(2) not null references payment_types (payment_type_code),
transaction_timestamp timestamp not null default current_timestamp,
unique (transaction_id, payment_type_code)
);
{TRANSACTION_ID、payment_type_code}上で一意制約がSQLはのペアを使用することができます列を外部キー制約のターゲットとして使用します。それは、いくつかのテーブルの行を混在させないために重要です。
お支払い方法によっては、お支払い方法が異なる場合があります。そして、それぞれの支払いは1つのタイプのみにすることができます。
create table payment_cash (
transaction_id integer primary key,
payment_type_code char(2) not null default 'Ca' check (payment_type_code = 'Ca'),
foreign key (transaction_id, payment_type_code)
references payments (transaction_id, payment_type_code),
other_cash_columns char(1) not null
);
create table payment_credit (
transaction_id integer primary key,
payment_type_code char(2) not null default 'Cr' check (payment_type_code = 'Cr'),
foreign key (transaction_id, payment_type_code)
references payments (transaction_id, payment_type_code),
other_credit_columns char(1) not null
);
create table payment_bank (
transaction_id integer primary key,
payment_type_code char(2) not null default 'Ba' check (payment_type_code = 'Ba'),
foreign key (transaction_id, payment_type_code)
references payments (transaction_id, payment_type_code),
other_bank_columns char(1) not null
);
payment_type_codeのデフォルト値とチェック制約により、たとえば現金支払いのクレジット詳細を挿入することができません。そのはである可能性があります。 - 外部キー制約でトランザクションIDだけが使用されていると、バッド・シングになります。
一般的に、金融取引の更新や削除はカスケードしません。代わりに、補償トランザクションを挿入してエラーを修正します。
これをユーザーやアプリケーションコードにもっとやさしくするには、支払いテーブルを詳細に結合する3つの更新可能なビューを作成します。それらを更新可能にする方法は、dbmsによって異なります。
クレジットトランザクションを挿入する必要があるコードは、credit_payments_allビューに挿入するだけです。
お支払い方法には異なる詳細はありません。 *お支払いには異なる詳細があります。 –