几个月前,当我开始设计应用程序数据库架构时,我被告知不要将相同的数据/计算数据存储在数据库中的多个位置(规范化)。如果我这样做,当我在一个地方更新数据而在另一个地方不更新时,我会产生一系列错误。所以我做了一个订单表和订单详细信息表。像这样的东西..
-- orders table
+-----+---------+----------+
| ID | clintID | date |
+-----+---------+----------+
| 1 | 1 |2018-02-22|
| 2 | 1 |2018-02-23|
| 3 | 2 |2018-02-24|
+-----+---------+----------+
-- orderDetail table
+-----+---------+------------+----------+----------+
| ID | orderID | itemNumber | quantity | unitPrice|
+-----+---------+------------+----------+----------+
| 1 | 1 | 12345 | 3 | 100.75 |
| 2 | 1 | 12346 | 3 | 100.75 |
| 3 | 2 | 12347 | 3 | 100.75 |
| 4 | 2 | 12345 | 3 | 100.75 |
| 5 | 3 | 12347 | 3 | 100.75 |
| 6 | 3 | 12345 | 3 | 100.75 |
+-----+---------+------------+----------+----------+
为了使查询对我来说更容易,我创建了一个 View “allOrdersSummary”,例如
-- allOrdersSummary
SELECT
orders.*, SUM(orderDetail.quantity * orderDetail.unitPrice) totalAmount
FROM orders INNER JOIN orderDetail ON orders.ID = orderDetail.orderID
GROUP BY orders.ID;
我后来使用这个 View 进行查询,但现在我开始得到 MAX_JOIN_SIZE错误。
因此,我想到将计算出的总订单金额与订单表 ID、clintID、日期、totalAmount
一起保存,每当我更改 orderDeatils
表中的内容时,我都会更新订单表中计算出的 totalAmount
列,我不知道这是好是坏!
这个问题-我不知道这是否被认为是一个问题-多次遇到,例如要知道发出请求的客户端的未读消息,我必须这样做sum(messages) 未读消息在哪里 = ? isRead = 0
A) 我应该在订单表中为计算出的 totalAmount
创建另一列吗?或者在数据库中计算 totalAmount
是很正常的事情每次需要时都从 orderDetails
表中获取吗?
B) 如果您建议在订单表中再创建一列,那么每次 orderDetails
表中发生更改时更新该列的最佳方法是什么?每当我更新 orderDetails
表时,我是否应该在 PHP 层更新它,或者这需要存储过程?
最佳答案
是的,根据数据库中的其他数据存储预先计算的值是正常的。但不一定是你提到的原因。我从来没有遇到过 MAX_JOIN_SIZE
的问题。
存储计算值的主要(也可能是唯一)原因是速度。因此,您对不经常更改的值执行此操作,并且可能会在使用大量数据的查询中使用这些值,因此如果您不使用它们,则可能会太慢。
例如:如果您想知道数据库中所有订单的平均值,如果您已经有了订单总计,那么查询会快得多。
为什么以及如何更新这些值完全取决于您。然而你必须保持一致。如果您使用 MVC 模式,那么将其集成到 Controller 中是有意义的。或者简单来说:每当提交的表单可能会更改其中一个值(其中计算出预先计算的值)时,您都需要重新计算它。
这清楚地表明了“正常化”并未完全得到维持。它不是很漂亮,但有时是值得的。当然,您可以争辩说,计算出的值代表"new"信息,因此不会违反“标准化”。
关于php - 如何在orders、ordersDetails模式中保存、处理订单总金额?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48925422/