我正在设计一个系统的数据库,该系统将处理基于订阅的产品,标准的一次性定价购买产品以及可变服务的计费。
客户可以与许多域相关联,域可能有许多订阅,设置定价产品或与之相关的计费变量服务。
我不确定是否将这些类别中的每一个分别放入他们自己的“订单”表中,或者找出将它们全部编译到单个订单表中的解决方案。
需要有关订阅的某些信息,例如开始日期或到期日期,这与独立产品无关。可变服务可以是任何价格,因此拥有单个产品表意味着我将不得不添加一个新产品,该产品可能永远不会再次使用或者可能会以不同的成本。
解决这个问题的最佳方法是什么,并且最好的方法是将每个分成单独的订单表?
答案 0 :(得分:3)
你看过子类型 - 它可能适合你。我的意思是一个中央“订单”表,其中包含公共属性和可选的“是一对”/特定订单表的一对一关系。特定订单表包含仅特定于该类订单的属性,以及返回到中央订单表的外键。
这是尝试充分利用“两个”世界的一种方式,我指的是(a)报告共同事物的适当集中程度和(b)正确的专业化水平。增加的细微差别是以额外加入的成本为代价,但为您提供灵活性和报告。
虽然我有点偏向于亚型,但是有些人认为除非你的订单子类型非常不同,否则将它们分开可能是不值得的。有一些看似很好的讨论here on dba.stackexchange以及here。话虽这么说,书籍(或至少章节)已写在这个主题上!
答案 1 :(得分:0)
与任何数据模型一样,“最佳”方式取决于您的需求。由于您未指定有关特定需求的大量详细信息,因此很难说下注模型是什么。
但是,一般来说,您需要考虑必要的详细程度。例如,如果所有订阅的费用相同且在当月1日结算,则在订单表中添加is_subscription ENUM ('Y', 'N')
字段可能就足够了。但是,如果订阅的结算日期和价格有所不同,您也需要存储该信息。在这种情况下,最好有一个单独的订阅表。
另一个考虑因素正是“订单”在您的模型中所代表的含义。一种解释是订单包括一个交易中包含的所有购买,包括一次性购买,可变服务和订阅。然后,已完成的订单将生成帐单,并且订阅将在该月的正确日期自动开帐单,而不会进行新订单。
答案 2 :(得分:0)
你的目标应该是让一个数据库设计没有硬连线到有关其内容的细节上,如果确实如此(必须),它就会以核心数据库设计中的专业化方式进行。
每个订单都有一些共同的字段。将它们放在一个表中,并让它引用相应(专用)表中的其他行。这就是你的DB规范化。
当ID, OrderID, ItemType, ItemID
确定表ItemType
引用时,您可以让主表包含ItemID
。我建议反对这一点,但必须承认我有时会使用它。
最好是拥有这些表格:
Clients: ID, Name, Address, Phone
Sellers: ID, Name, CompanyAlias
Orders: ID, ClientID, SellerID, Date, Price
OrderItems: ID, OrderID, DiscountAmount, DiscountPercentage,
ProductDomainID, ProductBottleID, ProductCheeseID, ..
现在OrderItems
是神奇发生的地方。前四个字段我自己解释。其余的是指一个你不会改变或删除任何东西的表:
Products_Cheese ID, ProductCode, ProductName, Price
如果您确实需要针对特定订单的变体产品,请添加字段VariantOfID
,否则为NULL。然后参考该ID。
OrderItems
表可以添加字段而不会干扰已建立的数据库结构。只是限制自己在除{1}之外的所有NULL
字段中使用Product*ID
值。但是进一步说,你甚至可能有想要组合两个或多个字段的场景。例如,添加ExtraSubscriptionTimespanID
旁边设置的ExtraServicelevelagreementID
或ProductCheeseID
字段。
这样,如果您使用ProductCheeseID
+ ExtraSubscriptionTimespanID
+ ExtraServicelevelagreementID
,则客户可以订购奶酪订阅SLA ,并且您的数据库结构不会重复
这种基本设计对替代性想法和解决方案持开放态度。但保持你的结构分离。不要制作一张包含你可能需要的所有领域的大桌子,一旦你以后需要改变某些东西,事情就会破碎。
答案 3 :(得分:0)
在设计数据库表时,您希望关注实体所代表的内容,并且具有两个或更多略微不同的版本,这些版本基本上是相同的实体,这使得架构难以维护。订单是订单,它们只是针对不同客户的不同产品的不同订单类型。你需要一些链接表来使它全部工作,但是你必须以某种方式建立这些关联,并且它有不同的实体类型。对于一个非常粗略的起点,这个怎么样?
答案 4 :(得分:0)
解决这个问题的最佳方法是什么,并且最好的方法是将每个分成单独的订单表?
这取决于。它会随着时间而改变。因此,这里的关键部分是您创建订单模型,并将它们的存储分开,只编写处理这些模型的代码。
完成后,您可以随着时间的推移开发和更改数据库结构,以存储和查询您需要存储的所有信息,并且需要进行查询。
这是一般建议。
更具体的是,您仍然需要将模型映射到数据结构。有很多方法可以解决这个问题,例如:单个表并非始终使用所有列(平面表),子类型表(对于每种类型使用新表)或主表与公共字段和子类型表包含其他列甚至属性表。所有这些方法都有利有弊,Stackoverflow的答案很可能是完全讨论这些问题的错误地方。但是,您可以在此处找到有关您的问题的深入的入门级讨论:
实体 - 属性 - 值(第6章);第13页 SQL反模式 - 避免数据库编程的陷阱 Bill Karwin 。