【问题标题】:Database Design: Explain this schema数据库设计:解释这个模式
【发布时间】:2011-06-07 11:52:54
【问题描述】:

完全披露...在这里狂热地尝试了解有关数据库的更多信息,因此我正在投入时间并尝试从源头获得此答案,但无济于事。

databaseanswers 的 Barry Williams 已发布此架构。

Clients and Fees Schema

我正在尝试了解此架构中地址表的拆分。我很清楚,地址表包含给定地址的详细信息。 Client_Addresses 和 Staff_Addresses 表让我着迷。

1) 我理解主外键的使用,如图所示,但我假设当使用这些外键时,您在同一张表中没有常驻主键(在本例中为 date_address_from)。有人可以解释这两者的原因并用语言表达这实际上是如何工作的吗?

2) 为什么要使用 date_address_from 作为主键,而不是像 client_address_id 这样的 PK?如果有人在一天内输入了两个地址,他的设计会发生冲突吗?如果是或不是,是什么?

3) 沿着规范化路线...由于 Client_Addresses 和 Staff_Addresses 表中的 date_address_from 和 date_address_to 都相同,因此这些字段是否应该不包含在主地址表中?

【问题讨论】:

标签: database database-design primary-key foreign-key-relationship database-schema


【解决方案1】:

这 2 个额外的表格使您可以拥有每个人的地址历史记录。

您可以将它们放在一张桌子上,但是由于员工和客户是分开的,因此最好也将它们分开(b/c 客户 id =1 和员工 id =1 不能在同一张桌子上使用地址)。

设计问题没有“单一”的解决方案,您可以使用 1 个人表,然后在员工和客户之间添加一列。但主要思想是数据库应该清晰、可读和高效,而不是保存表格。

大约 2 - pk 组合,包括 clientID、AddressID 和 from。 因此,如果有人在美国居住 6 个月,然后在以色列居住 6 个月,然后返回美国,到同一个地址 - 您只需要地址表中的 2 个地址和 client_address 中的 3 个地址。

将 from_Date 作为键的一部分的想法是正确的,尽管它不能保证数据完整性 - 因为您还需要手动检查同一个人的记录之间没有重叠的日期。

大约 3 - 没有(看 2)。

【讨论】:

  • 感谢 Dani 的回复,您的回答以及 dportas 确实为我解决了问题。
【解决方案2】:

查看数据模型,我认为:

1) PF 表示该字段既是表的主键的一部分,又是其他表的外键。

2) 同样的,Staff_Addresses 的主键是 {staff_id,address_id,date_adderess_from} 而不仅仅是 date_adderess_from

3) 同 2)

【讨论】:

    【解决方案3】:

    1) 在每个表中,主键是由三个属性组成的复合键:(staff_id, address_id, date_address_from) 和 (client_id, address_id, date_address_from)。这大概意味着客户/员工到地址的映射预计会随着时间而改变,并且这些改变的历史会被保留。

    2) 没有明显的理由在这些表中创建新的“id”属性。复合键可以充分发挥作用。为什么要在同一日期为同一客户创建两次相同的地址?如果您这样做了,那么这可能是修改设计的理由,但这似乎不太可能。

    3) 否。明显的目的是它们是将地址映射到客户/员工的适用日期 - 而不是仅适用于地址的日期。

    【讨论】:

    • @ dportas 只是想进一步澄清你在这里的意思。日期是否以 Dani 在回答这个问题时所说的方式映射到客户,一个在不同时间拥有多个住所的人?您对 1 和 2 的回答确实为我解决了问题。谢谢
    【解决方案4】:

    参考 Staff_Addresses 表,date_address_from 上的主键基本上可以防止多次输入相同的 staff_id/address_id 的记录。现在,我不是 DBA,但出于性能原因/更快的索引,我喜欢我的 PK 是整数或 guid。如果我要这样做,我会创建一个新列,例如 Staff_Address_Id,并将其设为 PK 列,并对 staff_id/address_id/date_address_from 设置唯一约束。

    至于您最后关心的问题,Addresses 表实际上是一个通用的地址存储结构。它不应该关心某人居住在那里的日期范围。最好留给地址的具体实现,例如客户/员工地址。

    希望这会有所帮助。

    【讨论】:

    • Sergei,关于使用整数作为主键,我的想法与您在这里的思路相同。在做了这么多年硬件之后,是时候掌握这些编程知识了,从我目前学到的知识来看,你发布的内容似乎是共识。感谢您的意见。
    • 这里没有明确的理由添加单个整数代理键。假设键被索引,那么添加额外的约束也意味着额外的索引。这不太可能对性能有好处,因为每次插入/删除行时都必须更新附加索引。
    【解决方案5】:

    3) 沿着 归一化......因为两者 date_address_from 和 date_address_to 在 Client_Addresses 中是相同的 和 Staff_Addresses 表应该那些 字段只是不包含在 主地址表?

    没有。但是你确实发现了一个问题。

    设计师认为客户和员工是完全不同的两件事。 “完全不同”是指它们没有共同的属性。

    这不是真的,是吗?客户和员工都有地址。我敢肯定他们中的大多数人也有电话。

    想象一下,员工中的某个人也是客户。那个人的名字存储了多少个地方?那个人的地址?你能听到 Rogers 先生在后台说:“你能拼出 'update anomaly' 吗?……我知道你会的。”

    问题在于设计师将客户和员工视为不同类型的人。他们不是。 “客户”描述了服务提供商(通常不是零售商)和客户之间的业务关系,客户可能是个人也可能是公司。 “员工”描述了公司与个人之间的雇佣关系。不是不同类型的人——不同类型的关系。

    你知道如何解决这个问题吗?

    【讨论】:

    • 几乎忘记了另一个观察——地址没有行。邮寄标签有线条。
    • @Mike。是的,还有一百多个这样的问题。
    • @Mike,感谢您在这里发人深省。 “你知道怎么解决吗?”我一直在努力思考这个问题。在查看了数据库的其余部分以及它最初尝试捕获的内容之后,我认为必须对许多表进行重新设计才能捕获您可能提出的建议。可以安全地假设您在这里没有提到这一点吗?如果是这样,经过进一步思考,我想出了一个连接表,它将一个人识别为“客户”、“员工”成员,甚至两者兼而有之。你在想别的吗?还是有其他建议?
    • @swisscheese:如果您的意思是“建模邮寄标签而不是地址有好处吗?”,那么答案是“是”。如果您的企业关注的实体是邮寄标签,那么为邮寄标签建模是个好主意。另一方面,如果您的业务涉及地址,那么对地址进行建模是一个好主意。有些企业需要同时建模。
    • @swisscheese:我说得太早了。我应该说我说的几乎和 performanceDBA 一样。我是说您可能需要实现一个超类型“Parties”以及两个子类型“Organizations”和“People”(pr“Persons”)。我假设有些客户是个人,有些客户是公司。
    【解决方案6】:

    评估

    首先是审核,然后是具体答案。

    1. 这不是数据模型。这不是数据库。这是一桶鱼,每条鱼都画成一个长方形,一条鱼的鳍被另一条鱼的鳃夹住,有一条线。有大量的重复,也有大量的缺失元素。完全不值得拿它作为例子来学习任何关于数据库设计的东西。

    2. 根本没有标准化;文件非常不完整(见迈克的回答,还有一百个这样的问题)。 other_detailseg.s 让我大开眼界。每个元素都需要被识别和存储:StreetNo, ApartmentNo, StreetName, StreetType等,而不是line_1_number_street,它是一个组。

      • 应将客户和员工规范化为 Person 表,并标识所有元素。

      • 是的,如果客户可以是个人或组织,则需要超类型-子类型结构来正确支持它。

    3. 所以这实际上是,技术上准确的术语,是一堆平面文件,其中包含字段组的描述。与数据库或关系数据库相距光年。还没有准备好进行评估或检查,更不用说构建一些东西了。在关系数据模型中,这将是大约 35 个规范化表,没有重复的列。

    4. Barry 在网络上有(等待它)超过 500 个“模式”。当您尝试使用第二个“模式”时,您会发现(a)它们在用途和目的方面完全不同(b)它们之间没有共同点(c)假设两者都有一个客户文件;它们将是不同形式的客户档案。

      • 他需要先对整个单一的“模式”进行标准化,

      • 然后在 500 个部分或主题领域中呈现单一规范化数据模型。

      • 我已经写信给他。没有回应。

    5. 还需要注意的是,他使用了一些无法识别的图表惯例。这些漂亮有趣的图片的问题在于它们传达了一些 的东西,但它们没有传达关于数据库或设计的重要 的东西。学习者感到困惑并不奇怪。经验丰富的数据库专业人员不清楚。有一个用于建模关系数据库和数据模型中的符号的标准是有原因的:它们传达了所有设计的细节和微妙之处。

    6. Barry 还没有读到很多内容:命名约定;关系;基数;等等,太多了,无法一一列举。

    网络上到处都是垃圾,任何人都可以“发布”。那里有数以百万计的好看和不好看的“设计”,不值得一看。或者更糟糕的是,如果你看,你会学到完全错误的“设计”方法。在学习数据库和数据库设计方面,最好找一个有资质、有能力的人,向他们学习。

    回答

    1. 他正在使用复合键而没有拼写出来。 client_addresses 的 PK 是 client_idaddress_id, date_address_from)。这不是一个坏键,显然他希望永远记录地址。

      • 将地址保存在单独的文件中的想法很好,但是他没有提供存储规范化地址所需的任何字段,因此“模式”将以 地址完全重复;在这种情况下,他可以删除地址,然后将这些行连同他们的other_details 一起放回客户和员工文件中,然后删除三个除了占用磁盘空间之外完全没有其他用途的文件。

      您正在考虑关联表,它解决了数据库中的多对多关系。是的,这些列是两个父表的 PK。这些不是关联表或文件;它们包含数据字段。

    2. 不是PK,是PK的第三要素。

      一个人一天内在多个地址注册的想法是不合理的;只数他们睡得最多的一个地址。

    3. 其他人已经回答了。

    不要期望在此图中识别任何数据库或设计或规范化的证据。

    【讨论】:

    • 好的,请仔细阅读您的帖子,感谢您的补充见解。我读过关于巴里的好与坏,通过你的详细解释,我明白你来自哪里。就像我说的那样,数据库的世界对我来说是新的,但它不是。了解我所缺少的知识确实引起了我的注意,因此如果您能指出任何好的信息来源,我将不胜感激,不幸的是,我知道我不相信可以从中学习的 DB 窥视。但总是对新朋友开放。看到一个设计良好的大型数据库示例来工作会很酷(续)
    • (续)你或其他人知道它在哪里吗?哪里有人愿意分享这些信息?如果不公开在这里,也许直接和我在一起?我了解制作布局良好的数据仓库的艺术和经验以及围绕它的主观性质。因此,任何愿意分享此类信息的书籍、网站和人都请通过我的方式。我可以继续阅读理论和设计原则,但看到一个实际可行的例子会很有帮助。
    • @swisscheese。你会发现“好东西不便宜,便宜的东西不好吃”,这就是为什么 99% 的免费信息都是垃圾以及为什么大型组织为专业服务付费的原因。我在银行和金融领域实施了几个大型的长期数据库,所有客户都保密。我被允许展示那些 10 岁的,但只有硬拷贝。您可能会通过(转到我的个人资料并)阅读任何答案数据库来获得一些价值;然后问问题。这是one with links,可以帮助您入门。
    • @swisscheese。 1)SO不是数据库驱动的,posts和cmets都是爬取的。只有当评论者使用@Handle 打开评论时,我们才会收到 cmets 通知。 2) 如果您愿意,您可以取消选择一个答案,然后选择另一个答案。 3)数据库书籍。只阅读教科书、Codd & Date、Inmon。远离 Ambler、Martin、Kimball 和(对于 Dbs)任何 OO 类型。
    • @swisscheese。我的荣幸。我对你的态度没有意见。只需阅读有关该主题的尽可能多的具体信息,并提出具体问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 2016-06-29
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    相关资源
    最近更新 更多