数据库设计第三范式
Database design 3rd Normal Form
我有一个包含很多表的数据库,其中 4 个是
- 付款
- 信用卡
- 贝宝
- 比特币
信用卡属性:
- 卡ID(PK)
- 类型
- 人数
- 过期日期
- ...
贝宝属性:
- paypalID (PK)
- 帐号
- ...
比特币属性:
- bitcoinID (PK)
- ...
支付 Table 属性:
- 金额
- ...
- ...
- cardID (FK)
- paypalID (FK)
- bitcoinID (FK)
付款只能通过 card/paypal/bitcoin 支付,所以我打破了第三范式,因为如果客户使用卡,那么我知道他没有使用贝宝或比特币。我该如何解决这个问题,以免破坏第三范式。
今天 SQL 中没有完全 干净的方法来执行此操作,因为 SQL 平台不支持断言。 (在 SQL 标准中创建断言)但是你 可以 设计你的 table 以支持合理的约束,即使不支持断言。
将所有计划付款共有的属性 "up" 推入 table "scheduled_payments"。
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_payments".
中的 'c' 行
- CREATE ASSERTION
- Similar design problem related to persons and organizations
- Similar design problem related to blogs
我有一个包含很多表的数据库,其中 4 个是
- 付款
- 信用卡
- 贝宝
- 比特币
信用卡属性:
- 卡ID(PK)
- 类型
- 人数
- 过期日期
- ...
贝宝属性:
- paypalID (PK)
- 帐号
- ...
比特币属性:
- bitcoinID (PK)
- ...
支付 Table 属性:
- 金额
- ...
- ...
- cardID (FK)
- paypalID (FK)
- bitcoinID (FK)
付款只能通过 card/paypal/bitcoin 支付,所以我打破了第三范式,因为如果客户使用卡,那么我知道他没有使用贝宝或比特币。我该如何解决这个问题,以免破坏第三范式。
今天 SQL 中没有完全 干净的方法来执行此操作,因为 SQL 平台不支持断言。 (在 SQL 标准中创建断言)但是你 可以 设计你的 table 以支持合理的约束,即使不支持断言。
将所有计划付款共有的属性 "up" 推入 table "scheduled_payments"。
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_payments".
- CREATE ASSERTION
- Similar design problem related to persons and organizations
- Similar design problem related to blogs