【问题标题】:Database Design feedback数据库设计反馈
【发布时间】:2011-06-21 15:09:47
【问题描述】:

一张发票可以包含 1 个或多个订单,如何归档?

发票示例:

OrderID |      Order Date    |   Amount
   31            10/02/2011         £1.50
   43            12/02/2011         £1.50
   74            13/02/2011         £5.00
                                   =======
                            Total   £8.00 

如果 Total 为负数(例如:-8.00),则表示客户欠我钱。 没有减号,我付给客户一些钱。

这是我想出的:

订单表

CREATE TABLE IF NOT EXISTS `orders` (
  `OrderID` int(11) NOT NULL AUTO_INCREMENT,
  `Total` decimal(6,2) NOT NULL,
  `OrderDate` datetime NOT NULL,
  `Status` int(11) NOT NULL,
  `userID` int(11) NOT NULL,
  `InvoiceID` int(11) NOT NULL,
  PRIMARY KEY (`OrderID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

发票表

CREATE TABLE IF NOT EXISTS `invoice` (
  `InvoiceID` int(11) NOT NULL DEFAULT '0',
  `InvoiceDate` datetime NOT NULL,
  `Amount` decimal(6,2) NOT NULL,
  `Status` int(11) NOT NULL,
  PRIMARY KEY (`InvoiceID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

invoice.Status(0 正在处理,1 发票已发送,2 已取消,3 已完成) 或者还有什么更好的状态?

付款表

CREATE TABLE IF NOT EXISTS `payment` (
  `PaymentID` int(11) NOT NULL AUTO_INCREMENT,
  `InvoiceID` int(11) NOT NULL,
  `Amount` decimal(6,2) NOT NULL,
  `DatePayment` datetime NOT NULL,
  `PaymentType` int(11) NOT NULL,
  PRIMARY KEY (`PaymentID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

payment.PaymentType =(1:从客户那里收到的付款(欠款),2:发送给客户的付款)

数据库结果:

mysql> select * from orders;
+---------+-------+---------------------+--------+--------+-----------+
| OrderID | Total | OrderDate           | Status | userID | InvoiceID |
+---------+-------+---------------------+--------+--------+-----------+
|       1 | 20.00 | 2011-06-18 15:51:51 |      1 |    123 |         1 |
|       2 | 10.00 | 2011-06-19 15:51:57 |      1 |    123 |         1 |
|       3 |  5.00 | 2011-06-20 15:52:00 |      1 |    123 |         1 |
+---------+-------+---------------------+--------+--------+-----------+

mysql> select * from invoice;
+-----------+---------------------+--------+--------+
| InvoiceID | InvoiceDate         | Amount | Status |
+-----------+---------------------+--------+--------+
|         1 | 2011-06-30 15:55:21 |  35.00 |      1 |
+-----------+---------------------+--------+--------+

mysql> select * from payment;
+-----------+-----------+--------+---------------------+-------------+
| PaymentID | InvoiceID | Amount | DatePayment         | PaymentType |
+-----------+-----------+--------+---------------------+-------------+
|         1 |         1 |  35.00 | 2011-06-29 15:56:16 |           1 |
+-----------+-----------+--------+---------------------+-------------+

我走对了吗?有什么可以改进/改变或建议?

谢谢。

【问题讨论】:

  • 看起来不错 - 我建议在 ordersinvoices 上都有 Status 有点令人困惑。如果订单的状态可以独立于发票,那就没问题了。
  • 感谢您在原始问题中包含架构。很多人没有。我没有看到它们在这里定义,所以不要忘记索引你的外键(orders.userIDorders.InvoiceIDpayment.InvoiceID)。
  • 根据费用的应用方式,orders 上的Total 可能还不够。您可能需要CostQuantity。此外,您可能需要向Invoice 收取额外费用,例如运输,处理。换句话说,发票金额将是总订单成本 * 数量 + 运输 + 处理。
  • @Blazes 发票只能包含已完成的订单(例如:order.status = 1)。
  • 谢谢Wiseguy,下次我会做的:)

标签: mysql sql database database-design


【解决方案1】:

好的,你这里有一些严重的问题。订单有多个项目,发票有多个订单,付款可能适用于多个订单和发票。订单可能会出现在多张发票上(如果他们不立即付款,这很常见)。

所以你需要的是链接表。您应该从具有订单 ID 和发票 ID 的 ORDERINVOICE 表开始。然后是带有 paymentid 和 Order id 的 ORDERPAYMENT 表。

您还需要考虑到,在订购情况下,您必须记录当时发生的订单详情。这意味着虽然您应该将 user_id 链接到当前用户,但您应该记录下订单时的用户姓名、帐单地址和送货地址。您稍后将需要此信息来处理有关订单的任何问题。此外,您需要确保将订单的详细信息存储在一个名为 ORDERDETAILS 的单独表中,该表存储各个行项目、订单时的价格和订购项目的名称。出于会计原因,您将需要此信息。在任何情况下,您都不希望依靠连接到产品表来计算过去订单的价格。这将导致您的财务记录不准确。

【讨论】:

  • 感谢 HLGEM 的建议,不确定我是否理解清楚.. 你能发布数据库设计表的示例吗?那我就更好理解了。谢谢。
  • 我明白你对 ORDERINVOICE 表的意思... ORDERPAYMENT 表不应该带有 paymentid 和 InvoiceID(不是 OrderID)吗? ... 关于存储详细用户名、帐单地址、产品名称和产品成本的记录的订购情况 - 有 3 个选项可以执行此操作:版本控制(类型 2)、历史表(类型 4)或重复数据到订单表..哪个更好?
  • 我会说 orderid 和 paymentID 因为您支付的是订单上的物品而不是发票。如果我在您付款之前向您开了三次发票,这笔钱将记入订单而不是特定发票。当然不是所有三张发票。您可以通过尚未付款的订单项目确定未来发票的未付款项。我更喜欢将商品的数据放在订单表中。它不是真正的重复信息(它是销售时的信息),因此不再是非规范化,而不是具有相同日期的两个订单不会是重复数据。
  • 啊,现在我明白了,谢谢。只是一个快速的问题。商品价格和产品名称总是定期变化——不需要审计价格历史表或愿景数据?
  • 始终记录下订单时产品的价格和名称。如果它在未来发生变化,那与订单无关。如果您还没有支付发票,但被告知价格是 100 美元,如果您收到 150 美元的发票,因为订单和发票之间的价格发生了变化,您会不会生气?如果您将这些详细信息记录在订单详细信息表中,则不需要版本控制表或价格历史记录表。
【解决方案2】:

看起来不错。

我唯一要添加的是付款表中的一些详细信息,例如交易 ID/支票号码。这样,您就可以将所有付款详细信息放在一起。

【讨论】:

  • 这是个好主意,谢谢。如您所知,发票可以包含 1 个或多个订单。每 2 周生成发票的最佳方式是什么?使用将扫描订单然后插入发票表然后“更新”order.invoice_id 的 Cron 作业? .......或者当我将订单状态更改为1(orders.status = 1)然后更新orders.invoice_id(它首先从发票表中检查)
  • 如果您有可能在不同的时间表上为不同的客户开具发票,那么创建一个客户端配置表来保存时间表。但是,可以,使用每隔一段时间启动的 cron 作业来查看何时需要生成发票。
  • 谢谢@Chris Lively,你认为我应该有“OrderInvoice”表,其中包含 OrderID 和发票 ID?所以我不需要订单表中的 InvoiceID。
  • @user791022: 如果您有允许部分支付订单的情况,那么是的,您需要 OrderInvoice 表。例如,如果订单金额为 1000,但您现在要向他们收费 500,以后再向他们收费 500。但是,您应该切勿在多张发票上放置完全相同的“账单”。例如,如果订单金额为 1000,而您开具了 1000 的发票,那么稍后为完全相同的 1000 订单创建了一张新发票。如果您允许/这样做,您的会计师会对您大喊大叫。
  • @user791022:我刚刚遇到simpleinvoices.org。您可以查看网站的功能。
【解决方案3】:

在我看来没问题,这也是我会做的。

(我认为付款与订单相关联,但如果您打算将其与发票相关联,这很好)

问候, MN

【讨论】:

    【解决方案4】:

    在不了解您的要求的情况下,到目前为止一切顺利。

    确保将您的发票状态和付款类型解码存储在查找表中,以便它们可以在数据库中强制执行,而不必依赖程序员对其进行正确编码。

    【讨论】:

    • 我再解释一下。客户上网并选择一家商店。他们从特定商店下订单。他们的订单存储在 orders 和 order_items 表中。下个月我想从一个将显示订单列表的 StoreID 生成发票(例如:orders.StoreID)。在发票上会告诉我商店欠我多少钱或我需要支付多少。它计算来自 orders.totals 的所有订单
    猜你喜欢
    • 1970-01-01
    • 2014-04-17
    • 2011-08-12
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多