【问题标题】:Database design 3rd Normal Form数据库设计第三范式
【发布时间】:2015-04-23 00:08:07
【问题描述】:

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

  1. 付款
  2. 信用卡
  3. 贝宝
  4. 比特币

信用卡属性:

  • 卡ID(PK)
  • 类型
  • 号码
  • 过期日期
  • ...

贝宝属性:

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

比特币属性:

  • 比特币ID(PK)
  • ...

付款表属性:

  • 金额
  • ...
  • ...
  • 卡ID (FK)
  • paypalID (FK)
  • 比特币ID (FK)

只能通过卡/贝宝/比特币支付,所以我打破了第三种正常形式,因为如果客户使用卡,那么我知道他没有使用贝宝或比特币。我该如何解决这个问题,这样我就不会破坏第三范式。

【问题讨论】:

  • 每笔 PayPal 交易都是一笔付款,但并非每笔付款都是一笔 PayPal 交易。所以 PayPal 表应该引用适当的付款,而不是相反。
  • 问题是那里存储了贝宝、卡和比特币信息,因为付款是经常性的,也就是每月付款。所以我存储的贝宝信息不是交易,它只是进行交易所需的信息。 (希望这是有道理的)
  • 哦,原来如此,我误会了。

标签: database-design


【解决方案1】:

目前在 SQL 中没有一种完全干净的方式来做到这一点,因为 SQL 平台不支持断言。 (SQL 标准中的 CREATE 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 key、not null 和check(...) 约束保证每一行都有一个支付ID 号和一个“c”。外键约束保证“credit_cards”中的每一行都将引用“scheduled_pa​​yments”中的“c”行。

【讨论】:

    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 2014-07-20
    • 2011-04-15
    • 2011-08-24
    • 2011-05-21
    • 2013-09-27
    • 2013-01-28
    • 2011-11-24
    相关资源
    最近更新 更多