【问题标题】:Database design choice : Order Belongs To Invoice Or Invoice Belongs To a Order数据库设计选择:订单属于发票或发票属于订单
【发布时间】:2017-02-04 18:33:46
【问题描述】:

以前有一个网站销售实物产品...现在他们想销售一些完全不同的服务之王 ....例如向用户帐户收费(购买产品)或购买短信的信用包..类似的东西

所以 db 曾经看起来像这样

order : user_id  ,date , total_price 
order_items : order_id , item_id , quantity , price
invoice : order_id , price , settled 
Invoice_transactions : invoice_id , amount , date

基本上发票属于订单

现在他们要销售服务,所以我们必须创建 2 个orders

product_orders (it used to be orders)
service_orders 

现在我必须选择发票表的设计

我可以添加另一个字段来指示订单的类型

invoice : order_id , order_type , amount
          1        , product    , 10000
          1        , service    , 10000

感觉不太对劲……或者我可以在订单中添加发票编号

invoice :  order_type , amount , date
product_orders : invoice_id , date , total_price
service_orders : invoice_id , service_id , date , total_price

哪一个(如果有的话)似乎是更合理的设计? 这是产品表:

这是服务表的样子:

这里是订单(应该改为产品订单)

这是 service_order 的样子

【问题讨论】:

  • 我怀疑随着时间的推移,一个订单可能会有多个发票,例如,如果第一张发票未付款或订单发生变化。
  • @GordonLinoff 不,这就是交易的用途,我们有 1 张发票,他们可以在一段时间内通过多次交易支付(查看 Invoice_transactions 表)
  • 请为项目/产品和服务添加表架构。我想知道,是否可以将它们合并到一张表中。
  • @PaulSpiegel 服务是向用户帐户收取费用的信用包(基本上他们最终会用该信用购买实物产品……应该说信用而不是服务!)……我没有它的架构但我会创造一些东西
  • @PaulSpiegel 我已经添加了架构,如果有什么遗漏请告诉我

标签: mysql database database-design


【解决方案1】:

我认为产品订单和服务订单的共同点多于差异点。在更大的商业和金融生态系统中,它们可能共享相同的角色/功能。所以我的第一个直觉是为两种订单都有一张桌子。

一对一表格

另一种方法是只使用一个order_ 表,其中有一列指示哪种类型的订单,名称类似于order_type_,其中包含salesproducts 之类的值。

将所有与产品相关的列移动到单独的子表product_info_。将所有与销售相关的列移动到单独的子表service_info_。我会将order_ 表设为两者的父级,尽管从技术上讲,我们有一对一的关系。对于任何给定的order_ 行,我们只有一个product_info_ 行或恰好一个service_info_ 行。

这可能会最大限度地减少数据库中的数据重复和应用程序中的编码。当您需要产品或服务详细信息时,您的应用代码使用标志字段order_type_ 来适当地查询一个或另一个子表。

invoices 表链接到 orders 表。我认为这两种订单的开票方式几乎相同。

订单中的所有字段

另一种选择是简单地将所有产品服务字段包含在order_ 表中。只需忽略服务订单的产品相关字段,并忽略产品订单的服务相关字段。不是最优雅的,但是如果您的字段相对较少,并且可能在列名前加上prod_serv_,这可能是可行的。我当然不止一次这样做了。

【讨论】:

  • thanx ,我在考虑One-To-One tables 选项...它是一个相对较大的系统,需要随着时间的推移进行大量升级和维护,所以我的首要任务是拥有一个干净、明确和灵活的设计。 ..所以除此之外,您认为我应该在发票表或其他方式中有 order_id 吗? (我认为通过重新定义订单,我会像以前一样将 order_id 保留在发票表中)
  • @hretic 您是否开具发票以向客户收取已完成订单的费用?如果是这样,订单会驱动业务,发票会晚一些,所以invoice_ 表应该是order_ 表的子表。通常在计费系统中,您可能会发送多张发票作为单个订单的计费。所以这将是一对多的关系,父订单到子发票。
【解决方案2】:

这完全取决于您想用它实现什么,客户可以在一个订单中同时购买两者吗?最常见的是您对带有 order_type 的发票所做的操作,它将具有最少的重复

【讨论】:

  • 不,他们不能在 1 个订单中购买它们,还有重复的 order_id 值以及我不能对这些表有任何外键约束的事实有点推迟
  • @hretic 在这种情况下,我会选择表格发票中的 order_type
【解决方案3】:

这是我会尝试做的:

types

type_id | name
      1 | product
      2 | service

items 将具有用于产品和服务的公共列。

items: item_id, type_id FK(types.type_id), price, title, ...

带有 FK item_id 的表 productsservices 以及这两种类型不常见的列(如 products.weight)。

type_id 列添加到orders 表中:

order : user_id, date, total_price, type_id FK(types.type_id)

type_id 列添加到表order_items

order_items: order_id, item_id, type_id, quantity, price

FK 将是:

(order_id, type_id) -> orders(order_id, type_id)
(item_id, type_id) -> items(item_id, type_id)

对于那些 FK,不可能在一个顺序中混合不同的类型。

【讨论】:

  • items 是什么表?你是说order_items 吗?
  • @hretic 不。正如我所写,这是一张包含产品和服务常用列的表格。就像 OOP 中的超类 (class Item {...} - class Product extends Item {...} - class Service extends Item {...})。因此,您可以在order_items 中对该表进行 FK。
猜你喜欢
  • 2011-02-10
  • 2015-05-05
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多