数据库规范化设计问题:2个表共享几乎相同的信息

时间:2012-11-29 14:49:42

标签: mysql database oracle database-design relational-database

示例场景:假设我只有两种类型的买家。

买方1:个人买方

买方2:公司买方

买家1的区别属性:FName,LName,Bdate和年龄

买家2的区别属性:Company_Name,Nature_Of_Business和Type_Of_Business

2位买家的

常见是:地址,电子邮件,电话号码,国家/地区

 Db Table Name: Buyer
 Attributes: BuyerID, BuyerType **FName,LName,Bdate,Age**,Company_Name, Nature_Of_Business and Type_Of_Business

我的解释:如果您尝试查看买方表,则合并个人和公司买方的属性,因为它们都是买方,只是根据BuyerType(个人或公司)进行分类< / p>

问题:如果买方类型是公司,那么我的个人属性(即FName,LName等)将被记录为空,反之亦然。我的想法阻止我将它们分开,因为我不想为每个表创建买方的ID。他们应该只有1个BuyerID,无论他们是个人还是公司。

问题:如何构建数据库表来解决此查询:

我想要报告,显示所有买家信息,没有空记录。

听起来很疯狂,但是当生成可能的报告时,如果买方是公司类型,则详细信息可能会给出单个买方字段的空记录

注意:如果我要过滤特定的买方类型,这可以很容易地完成,但事实并非如此。我想要所有人。

2 个答案:

答案 0 :(得分:2)

您可以从出生日期开始计算年龄,因此无需存储年龄。

您有买家表和单独的买家和公司买家表。

Buyer
------
Buyer ID
Buyer Type
Buyer Type ID
Address
Country
Email
Telephone Number

Individual Buyer
----------------
Individual Buyer ID
Last Name
First Name
Birth Date

Company Buyer
-------------
Company Buyer ID
Company Name
Type of Business
Nature of Business

买方类型是指向此买方的特定子表的指标。对于个人而言,“我”和公司的“C”将是定义指标的一种方式。

买方类型ID是个人买方ID或公司买方ID的外键。

获取所有买家信息的SQL将是

SELECT *
FROM Buyer, "Individual Buyer", "Company Buyer"
WHERE "Buyer ID" = 12345
  AND (("Buyer Type ID" = "Individual Buyer ID") AND ("Buyer Type" = 'I'))
   OR (("Buyer Type ID" = "Company Buyer ID") AND ("Buyer Type" = 'C'))

如果您想要多个买方行,请调整WHERE子句。

答案 1 :(得分:0)

您的逻辑架构可能有三个不同的实体:一个包含所有公共字段的抽象买方,以及从中继承的两个子实体:个人买方和公司买方。

如何在物理上实现该架构取决于您。通常,共享相同主键(此处为buyerID)的所有逻辑实体将合并在同一物理表中。

有一个表是有道理的:

  • 效果的角度来看:过滤所需的资源少于加入一般的资源。使用单个表格,DML也会快得多。

  • 完整性的角度来看
  • :当您有多个表时,很容易插入无效数据。例如,如果你有三个表,很难保证一个buyerID 至少一个而最多在子实体中的一行。

我会选择一个有约束的物理表:

CREATE TABLE buyer (BuyerID primary key, BuyerType, 
                    FName,LName,Bdate,
                    Company_Name, Nature_Of_Business, Type_Of_Business,
                    CONSTRAINT individual_chk 
                       CHECK (BuyerType = 2 OR (Company_name IS NULL AND
                                                Nature_Of_Business IS NULL AND
                                                Type_Of_Business IS NULL)
                              ),
                    CONSTRAINT company_chk
                       CHECK (BuyerType = 1 OR (...))
                   )

检查约束还将验证每种类型的必填字段不为空。

如果您需要单独访问个人和企业,则可以创建视图:

CREATE VIEW individual_buyer IS 
   SELECT BuyerID, 
          FName,LName,Bdate
     FROM buyer 
    WHERE buyerType = 1

CREATE VIEW company_buyer IS 
   SELECT BuyerID, 
          Company_Name, Nature_Of_Business, Type_Of_Business
     FROM buyer 
    WHERE buyerType = 2