Mysql 数据库规范化设计问题:两个表共享几乎相同的信息
示例场景:假设一个产品屋只有两种类型的买家 买方1:个人买方 买方2:公司买方 买家1的不同属性:FName、LName、b日期和年龄 买方2的不同属性:公司名称、业务性质和业务类型 两位买家的常见信息是:地址、电子邮件、电话号码、国家/地区Mysql 数据库规范化设计问题:两个表共享几乎相同的信息,mysql,database,oracle,database-design,relational-database,Mysql,Database,Oracle,Database Design,Relational Database,示例场景:假设一个产品屋只有两种类型的买家 买方1:个人买方 买方2:公司买方 买家1的不同属性:FName、LName、b日期和年龄 买方2的不同属性:公司名称、业务性质和业务类型 两位买家的常见信息是:地址、电子邮件、电话号码、国家/地区 Db Table Name: Buyer Attributes: BuyerID, BuyerType **FName,LName,Bdate,Age**,Company_Name, Nature_Of_Business and Type_Of_Bus
Db Table Name: Buyer
Attributes: BuyerID, BuyerType **FName,LName,Bdate,Age**,Company_Name, Nature_Of_Business and Type_Of_Business
我的解释:如果您尝试查看表Buyer,则个人和公司Buyer的属性都会合并,因为它们都是买家,只是根据BuyerType(个人或公司)进行分类
问题:如果买方类型为公司,则我的个人属性(即FName、LName等)将记录为空,反之亦然。我的想法阻止我将它们分开,因为我不想为每个表创建买家ID。无论是个人还是公司,他们都应该只有一个BuyerID
问题:如何构造DB表来解决此查询:
我想要一份显示所有买家信息且没有空记录的报告
听起来很疯狂,但是当生成可能的报告时,如果买方是公司类型,则详细信息可能会给出单个买方字段的空记录
注意:如果我过滤特定的买家类型,这可以很容易做到,但事实并非如此。我想要全部。您可以从出生日期开始计算年龄,因此无需存储年龄 您有一个买家表和单独的个人买家和公司买家表
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
买方类型是指向该买方特定子表的指示器。”个人的“I”和公司的“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子句。您的逻辑模式可能有三个不同的实体:一个包含所有公共字段的抽象买家,以及从中继承的两个子实体:个人买家和公司买家
如何实际实现该模式取决于您。通常,共享同一主键的所有逻辑实体(此处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 (...))
)
检查约束还将验证每种类型的必填字段是否不为null
如果需要分别访问个人和业务,则可以创建视图:
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
抱歉,我不太明白这一点:
我不想为每个表创建买家ID
。买家可以是个人或公司,还是应该只是其中之一?这可能会对您有所帮助。@MostyMostacho这意味着,通过为个人买家和公司买家创建两个单独的表,将导致买家ID的重复,因为他们都是买家。感谢他们不会被复制,因为他们将是不同的买家,他们完全可以不同。不过你没有回答我的问题:)@MostyMostacho对不起,我的英语不太好。那么你的意思是可以建造两个表买家(个人和公司)?如果是这样的话,最接近的可能性将是个人买家具有ID#1,公司买家也具有ID#1。你们如何在报告中协调一致?嗯,我不明白他们为什么要协调一致。他们应该被喜欢在一起吗?如果是这种情况,那么我将创建一个“抽象买家”表,然后为其他每个表创建一个。当然,每个表都有自己的ID,并且会有所不同。您所称的对账
只是一个外键,它将每个子表链接到父表。只要一个简单的内部连接就足够了:)检查我提供的链接我已经清楚地解释了如何做。谢谢。我将把它看作是一个解决方案,但将用样本数据进行实验,以便彻底测试它。我真的很感激。我关心的是在生成报告的过程中。我想我错过了询问表的连接问题。当我想查询买方表时,该表将列出“个人”和“公司”的买方记录及其相应的个人信息,这是如何工作的?因为当我基本上加入表时,我只能从“个人”和“公司”获取ID,但很难从个人表、公司名和业务性质中获取名字和姓氏。我现在正在做报告,但已经花了2天的时间来分析并回复您,也许您仍然可以回答我的报告问题。非常感谢。我真的很感谢你的帮助。很好的开始。我成功地得到了我需要的东西,但尽管没有错误,我还是得到了一个警告:“未知表状态:表类型”。没有必要,但如果你知道这意味着什么,可能会让我知道。非常感谢吉尔伯特先生。哦,对不起,。我刚发现。需要选择买家。*、个人买家。*、公司买家。*而不仅仅是选择*以避免警告。