Нормализовать 3 таблицы базы данных - PullRequest
0 голосов
/ 17 февраля 2012

Здравствуйте! У меня проблема с разделением трех типов оплаты: НАЛИЧНЫЕ, КРЕДИТ, БАНК

Каждый из них имеет разные данные.Данные определяются пользователем, что означает, что при оплате кредитной картой (например, вы должны ввести данные своей кредитной карты, банковские реквизиты, денежные данные (валюта и т. Д.))

  1. Бизнес-процесс: пользовательвыберет свой тип оплаты в поле со списком:
  2. Затем пользователь введет данные этого типа оплаты.

Это то, что я пробовал:

PaymentType (PaymentType_ID (PK), PaymentTypes)

... ..... ...... .........

тогда я застрял.Я не знаю какПожалуйста, помогите мне.Если вы ответите, объясните мне, пожалуйста.Я не хочу снова задавать тот же вопрос здесь.Если я сталкиваюсь с подобной ситуацией.

*** Я не могу объединить их все в 1 таблицу, потому что они разные столбцы.У них разные конкретные детали ...

1 Ответ

0 голосов
/ 28 марта 2012

Все три типа оплаты имеют несколько общих черт.Все они имеют номер счета, сумму, временную метку, тип платежа и какой-либо идентификатор транзакции.Все общие атрибуты находятся в одной таблице.(Некоторые типы данных намеренно наивны, потому что они зависят от приложения, и я не знаю ваше приложение.)

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)
);

Уникальное ограничение для {action_id, payment_type_code} позволяет SQL использовать этопара столбцов в качестве цели для ограничения внешнего ключа.Очень важно не допустить перепутывания строк из нескольких таблиц.

Каждый платеж имеет разные атрибуты в зависимости от типа платежа.И каждый платеж может быть только одного типа.

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 не позволяют, например, вставить кредитные реквизиты для оплаты наличными.Это было бы возможно - и это было бы плохо, если бы ограничение внешнего ключа использовало только идентификатор транзакции.

Как правило, вы не каскадно обновляете илиудаляет для финансовых транзакций.Вместо этого исправьте ошибки, вставив компенсирующую транзакцию.

Чтобы сделать это более удобным для пользователей и кода приложения, создайте три обновляемых представления, которые соединяют таблицу платежей с деталями.Как сделать их обновляемыми, зависит от вашей базы данных.

create view credit_payments_all as
select p.transaction_id, p.account_code, p.amount_usd, 
       p.payment_type_code, p.transaction_timestamp,
       c.other_credit_columns
from payments p
inner join payment_credit c on c.transaction_id = p.transaction_id

-- Rules, triggers, stored procedures, functions, or whatever you need
-- to make this view updatable.

Тогда любой код, которому нужно вставить кредитную транзакцию, можно просто вставить в представление credit_payments_all.

...