我认为这是常见的事情......你有一个数据库服务器,并且你想在其中存储客户联系信息。
您需要此人的姓名,地址,电话等。
存储地址和电话的最佳做法是什么?假设OLTP ......
多人可能拥有相同的电话号码(例如妻子和丈夫,或母亲和女儿)。
多人共用一个家庭。
对于上面提到的特定模型,这样做会很好,但是我不知道如何在非正规化的情况下优化这个模型。
例如:
因此,如果我像白皮书那样设计它,我的personid
表格和我的address
表格中都会有phone
。但是,由于多人可能共享同一地址,因此这是不可行的。一个人可能有多个地址甚至没有地址。所以我觉得我需要一个人 - >地址映射表以及电话的映射表,否则我将对这两个表进行非规范化,并且在两个共享同一电话/地址的人的异常情况下会有一些重复。
无论如何,我在提出这个问题时的观点是因为看起来很难找到这种类型的“最佳实践”,但它似乎只是在任何类型的应用程序或数据库中出现的类型
答案 0 :(得分:6)
将Contact
可能包含许多相关Phone
或Address
实体的一对多关系中的地址和电话号码标准化非常有意义。
但是,没有必要在联系人数据库中以多对多关系规范化地址和电话号码,因为这些不是您自己有兴趣合作的实体,它们本身就是唯一实体的优点。事实上,我会说在你的情况下,将它们标准化到那个水平并不是一个好的设计。
如果您在房地产,租赁或电话服务中建立业务模型,即使没有人与之关联,您也可以关注房产和电话号码,那么将它们建模到这个级别是有意义的。在多对多设计中避免重复地址和电话号码比让他们再次输入地址更有效,并且避免这些重复没有真正的好处。另外,无论如何,你最终会得到重复项(至少对于地址,除非你使用邮局例程实时擦除它们),所以谁将要经历并匹配'123 Ascot Wy#5'到'123 Ascot Way Apt 5'?那里有什么价值?
将这种深度归一化的通常原因并不适用。假设您确实创建了一个PhoneNumber
表和多对多关系所需的PersonPhoneNumber
表。您有三个人使用相同的电话号码,他们都正确链接到它。现在,他们中的一个打电话给你,告诉你他正在改变他的电话号码。您确定是否要更改实际的PhoneNumber
记录并同时更新其他两个人的号码?如果他们不和他一起移动怎么办?很快你会发现你的数据搞砸了。您也可以将FirstName
表的名字和名称标准化为LastName
表的姓氏!然后当“Joey”长大并将其名字改为“Joe”时,所有其他Joeys将获得自动升级。但是哎呀......“乔”已经存在,就像你正在改变上面三个人中的一个人的电话号码那样......真是一团糟。
另一方面,您会使用PhoneID
作为电话号码的代理键吗?但是电话号码是实际上作为自然键的好东西之一,它们几乎甚至要求被用作自然键。然后,您的Phone
表变得毫无意义,因为它不会对有关该电话号码的任何其他信息进行编码。它只是一个电话号码列表,已经出现在引用表中。不要使用这样的Phone
表。如果您想知道两个人是否共用同一个电话号码,您只需加入或按列分组即可!在我看来,如果电话号码与单调递增的PhoneID
相关联,那么它就会产生一层抽象。
如果您阅读A Universal Person and Organization Model,您会看到电话号码和地址实际上不是需要建模到多对多关系级别的实体的视角 - 它们更像是“智能定位器” “将邮件路由到收件人。你为什么要迫使三个不同的人的定位器(a.k.a。电话号码)相同?定位器有助于找到人,而不是找到响铃的物理电话。你不会在乎手机或其他人可能会回答的问题 - 你只关心这样一个事实:一旦回答,可能会联系到感兴趣的人。
答案 1 :(得分:1)
归一化。
归一化直到疼痛。
再次标准化,直到它难以忍受。
然后调整您的查询;设计你的指数;衡量你的表现;如果此时您没有其他选项,则将最小值最小化以满足性能选项。
请记住,在一个查询上加速性能的每个非规范化本身都会降低(几乎)tat表集上的每个操作的性能。如果测量实际上显示出明显的性能改进,则只保留denormalizaiton。
请记住,规范化程度越高,指数越小;索引行中的索引行越多,数据库执行的速度就越快。是的,创建了很多非常小的表 - 它们永久保存在缓存中,因此几乎可以自由访问。