假设您有一个租赁电影的业务,并且您正在为数据库设计架构。客户必须选择计划,交付类型和billingTerm(每月,每三个月,每六个月)。该计划有一个基本价格,并决定客户每月可以租多少部电影,以及一次有多少部电影。交付类型将根据客户的选择更改价格(常规交付将为计划价格添加一定的价值,加急的将增加更高的价值。将交货类型和结算条款信息存储在计划表,还是在客户表中?
假设有以下表格:
billingTerms(id, billEveryXMonths, discount)
deliveryTypes(id, type, price)
方法一:
plans(id, name, price, billingTermsId, deliveryTypeId, monthlyLimit, atHomeLimit)
customers(id, name, planId)
这种方法要简单得多,但基本上最终会复制计划,除了一个属性。排列和组合的数量大于只有两个计划。
方法二是在客户表中存储计划ID,交货类型和开票条款:
plans(id, name, price)
customers(id, name, planId, billingTermId, deliveryTypeId)
此外,monthlyLimit和atHomeLimit必须链接到控制表,该控制表每月跟踪客户活动。
答案 0 :(得分:1)
您希望使数据库架构尽可能接近“真实世界”。因此,在这种情况下,由于交付类型和结算条款与个别客户相关联,而不是与计划相关联,因此您可以将它们包含在客户表中。
我不确定你为什么要考虑将类型和术语放入计划记录中,但你确实说“这种方法更简单”。你能详细说明你的意思吗?对我而言,似乎会让人感到困惑。原因如下:
假设您为您的客户提供了五种不同的计划,那么您的计划表中就有五个计划。当您创建任何类型的数据输入屏幕时,您只需从数据库中提取计划选项并显示它们。如果以后您决定添加新计划,则只需将其添加到数据库中,如果您的视图代码编写正确,它就可以正常工作。
但是,如果您要在计划表中包含所有排列,那么您无法使用此方法,您必须在演示文稿屏幕上对计划进行硬编码,然后在添加新计划时对其进行修改
此外,如果您将期限和类型与计划分开,那么您可以创建修改客户的程序,而不必修改客户的计划选择。这自然是正确的事情,因为在这种情况下客户没有修改他们的计划选择。
希望这是有道理的。
答案 1 :(得分:1)
每个属性的功能依赖性是什么?
如果每个计划始终具有相同的计费期限,则计费期限取决于计划,并且应该是计划表的属性。
如果每个客户都有不同的结算期限,无论计划如何,那么结算期限取决于客户,并且应该是客户表的属性。
但是,如果每个计划都有默认的结算条款,但可以逐个客户地覆盖,那么有几个选择:
在每个表中放置结算条款,并让使用它的查询执行合并(cust.billing_term_id,plan.billing_term_id)以确定哪个是正确的。
拥有一个关联实体Customer_X_Plan(customer_id(pk),plan_id(pk),billing_term_id),您可以在其中存储有关每个客户与其计划相关的属性的正确信息。
每个都有权衡;这就是为什么它是设计而不是工程设计。
答案 2 :(得分:1)
计划和客户是不同的实体。作为一个客户,我可能想要一个计划给我,另一个计划给我的孩子。
如果您将计划信息放在客户表中,我无法订购两个计划。如果我改变计划,你就无法记录历史。
归一化。
答案 3 :(得分:1)
您尚未指定任何键或依赖项,因此这些都是猜测。我想在计划表中,Id和/或计划名称决定了价格。因此,我猜第一个模型会创建一个非密钥依赖项,这是您应该尝试避免的。假设普通表格是你的指南,那么我猜第二个选项是更好的设计。
也许你怀疑的原因是因为你没有在每种情况下都确定了密钥和依赖关系。这样做通常是一个好主意,因为确保您的表格至少达到BCNF / 5th Normal Form将立即消除很多设计问题。