2015-04-23 40 views
1

我有很多表,其中有4個是這些數據庫設計第三範式

  1. 付款
  2. 信用卡
  3. 比特幣

信用卡屬性數據庫:

  • CardId中(PK)
  • 類型
  • EXPIREDATE
  • ...

貝屬性:

  • paypalID(PK)
  • 帳戶
  • ...

比特幣屬性:

  • bitcoinID(PK)
  • ...

付款表屬性:

  • ...
  • ...
  • CardId中(FK)
  • paypalID(FK)
  • bitcoinID(FK)

的支付只能通過兩種卡/貝寶/比特幣,所以我打破3日支付正常的形式,因爲如果客戶使用卡,那麼我知道他沒有使用貝寶或比特幣。我該如何解決這個問題,以便我不打破第三種正常形式。

+0

每一個PayPal交易的付款,但並不是每個付款是PayPal交易。所以PayPal表應該引用適當的付款,而不是其他方式。 – IMSoP

+0

的事情是,我在那裏存儲貝寶,卡和比特幣信息,因爲付款是經常性的每月付款。所以我存儲的PayPal信息不是一個交易,它只是進行交易所需的信息。 (希望有道理) –

+0

哦,我明白了,我誤解了。 – IMSoP

回答

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

primary keynot nullcheck(...)約束 「credit_cards」 保證每一行都會有一個支付的ID號和 'C'。外鍵約束保證「credit_cards」中的每一行都會引用「scheduled_pa​​yments」中的'c'行。