数据库规范化 - 相同的字段,不同的表

时间:2013-12-09 21:10:45

标签: mysql sql database-design normalization

假设我有2张桌子。广告系列和广告商。这些表中的每一个都有一些完全相同的字段(这些不是完整的字段列表,我只显示相同的字段):

修改 正如评论中所述,我将更密切地解释关系。 每个广告客户都有0到多个广告系列。 1个广告系列仅属于1个广告客户。还有另一张桌子,我们称之为“优惠”。创建新优惠时,需要增加所有计数列(campaign.monthly_count,campaigns.total_count,advertisers.monthly_count,advertisers.total_count)。限制列是计数列不能超过的特定上限。

广告系列

monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

广告客户

monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

问题是:是规范化的数据库设计还是有更好的方法做事?

我在想另一张这样的桌子:

限制

campaign_id (int)
advertiser_id (int)
monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

但是这样一个引用的列总是空的,我不能使用外键。

或者另一种选择可能是这样的:

limits_campaigns

campaign_id (int)
monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

limits_advertisers

advertiser_id (int)
monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

这样我就不得不在查询中编写更多连接,但我可以使用外键。

是否有其他选项似乎更合适,如果不是哪种设计最佳?

P.S。:更具体地说,我正在使用MySQL InnoDB引擎。

3 个答案:

答案 0 :(得分:1)

还有另一种方法:
有一个名为limitable-entity的基表(我的命名不满意)与广告系列和广告客户的一对一关系。
可限制实体将是generalization pattern in database design的实施
enter image description here

答案 1 :(得分:0)

正如你自己发现的那样,这样做:

campaign_id (int)
advertiser_id (int)
monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

您有两个主键。即使您只使用campaign_id作为主键,这也是不可能的,因为主键的非空和/或唯一约束。

您可以使用的是复合主键:

item_id (int)
item_type (int)
monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

primary key(item_id, item_type)

然后你可以有一个参考表 Ref_Item_Type:

1 campaign
2 advertiser
3 whatever
N ...

然后您可以将复合主键作为外键引用,如果要获取所有项目,则不必进行任何连接/联合。

CREATE TABLE SecondaryTable (
  AutoID int,
  Key1 int,
  Key2 int
)


ALTER TABLE SecondaryTable 
ADD CONSTRAINT FK_Whatever FOREIGN KEY (Key1, Key2) REFERENCES PrimaryTable (item_id, item_type)

答案 2 :(得分:0)

根据您的意见:

表广告客户:

advertiser_id PK
monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

表格广告系列,参考其所属的广告客户

campaign_id PK
advertiser_id FK
monthly_limit (int)
total_limit (int)
monthly_count (int)
total_count (int)

关于计数,你应该用你的业务逻辑控制它。