数据库设计第3范式

时间:2015-04-23 00:08:07

标签: database-design

我有一个包含许多表的数据库,其中4个是

  1. 付款
  2. 信用卡
  3. 贝宝
  4. 比特币
  5. 信用卡属性:

    • cardID(PK)
    • EXPIREDATE
    • ...

    PayPal属性:

    • paypalID(PK)
    • 帐户
    • ...

    比特币属性:

    • bitcoinID(PK)
    • ...

    付款表属性:

    • 金额
    • ...
    • ...
    • cardID(FK)
    • paypalID(FK)
    • bitcoinID(FK)

    付款只能通过卡/ paypal /比特币支付,所以我打破第3范式,因为如果客户使用卡,那么我知道他没有使用paypal或比特币。我怎样才能解决这个问题,这样我就不会破坏第三范式。

1 个答案:

答案 0 :(得分:1)

今天在SQL中没有完全干净的方法,因为SQL平台不支持断言。 (在SQL标准中创建ASSERTION)但是可以设计表以支持合理的约束,即使不支持断言。

将所有预定付款的常用属性“向上”推送到“scheduled_pa​​yments”表中。

create table scheduled_payments (
  pmt_id integer primary key,
  pmt_amount numeric(14, 2) not null
    check (pmt_amount > 0),
  pmt_type char(1) not null
    check (pmt_type in ('b', 'c', 'p')),      -- (b)itcoin, (c)redit card, (p)aypal.
  other_columns char(1) not null default 'x', -- Other columns common to all payment types.
  unique (pmt_id, pmt_type)
);

-- Tables for Bitcoin and PayPal not shown, but they're very similar
-- to this table for credit cards.
create table credit_cards (
  pmt_id integer primary key,
  pmt_type char(1) not null default 'c'
    check (pmt_type = 'c'),
  foreign key (pmt_id, pmt_type) 
    references scheduled_payments (pmt_id, pmt_type),
  other_columns char(1) not null default 'x' -- Other columns unique to credit cards.
);

“credit_cards”中的primary keynot nullcheck(...)约束保证每一行都有一个付款ID号和一个'c'。外键约束保证“credit_cards”中的每一行都引用“scheduled_pa​​yments”中的“c”行。