2011-12-23 91 views
3

我正在开发一个类似于商店的系统(在PHP & MySQL中),它将发票导出到外部系统。这个过程就像这样;冗余数据总是不可行

  • 客户订单的产品,发票创建该发票生成
  • XML和发送到外部服务器
  • 外部服务器处理XML并响应与另一个XML
  • 系统处理响应。

对于每一个真实被发送到一个记录中包含相应invoicenumber和状态数据库中创建(状态最初是SENT,表示XML被发送。)该系统已经处理了之后,外部服务器XML回复状态为SUCCESSERROR。现在,问题是;在某些时候,我想要获取请求表中没有记录且状态为SUCCESS的发票清单。

编辑:如果状态为ERROR会有同一张发票上一个新的请求,所以有可能会有每张发票多个请求。

我的订单表中的列IDInvoiceNumber,并请求表中的列IDInvoiceNumberStatus,所以得到的清单中提到,我可以这样做:

SELECT InvoiceNumber 
FROM orders AS a 
LEFT JOIN requests AS b 
    ON a.InvoiceNumber = b.InvoiceNumber 
WHERE NOT EXISTS (SELECT ID 
         FROM requests 
         WHERE status = "SUCCESS" 
          AND request.InvoiceNumber = a.InvoiceNumber) 

然而,第二个选择是是为订单表(即requestSucces)创建最初为0的额外列,如果系统处理相应发票的成功响应,则将其设置为1。这将导致更容易和更便宜的查询来获得需要(重新)发送的发票清单(SELECT invoiceNumber FROM orders WHERE requestSuccess = 0),但是该领域在技术上将是多余的。

我的问题是:什么会更好;以使用冗余字段为代价来使用简单查询,或者使用较重的查询并且不会冗余地污染数据库。当然;如果你们中的任何一个人知道更好的解决方案,而不使用更好的冗余。

+0

这对我来说似乎很主观 - 我个人并不认为它是多余的,如果它导致快速查询与慢速查询 - 但是我不是DBA,我相信大量会提供不同的观点 – jammypeach 2011-12-23 09:49:08

+0

我会考虑按照您的建议去规范化数据,尽管您可能会考虑其他优化方法。每张发票是否有多个请求(它不是100%清晰的)? – liquorvicar 2011-12-23 09:56:30

+0

@livvvicar;我更新了我的问题;每张发票可能有多个请求。 – 2011-12-23 10:02:20

回答

2

时,你的状态字段数字错误= 0和更迭= 1一个你可以做的invoicenumber分组一个最大状态,看看哪些发票没有

+0

然而,这个选项让我想起了,还有更多的状态(我在问题中提到过“SENT”,但还有其他的)。你认为给他们一个数字并让'SUCCESS'成为最高的选择是一种选择吗? – 2011-12-23 10:13:16

+0

我认为这取决于州的数量以及你如何组合它们。如果你只有发送,成功和错误,我认为你可以这样做。如果你将来会增加更多的状态,你必须准备好不会与新状态的最大冲突 – 2011-12-23 10:26:19

+0

我想我会使用类似的东西。 – 2011-12-23 10:30:19

0

战争已经打了过来正常化:-)

但是:
既然你要寻找的是没有被设置为success发票,不能这样做?

SELECT InvoiceNumber 
FROM requests 
WHERE status != "SUCCESS" 

(注意,不等于符号)

+0

嗨修补程序,感谢您的答复,但由于可能有多个请求每发票这不会工作,不幸的是。 – 2011-12-23 10:03:38

0

鉴于从您提供的信息似乎有永远是你的请求表中的每个发票的至少一个项目,你可以让你从这样的查询需要的数据:

SELECT InvoiceNumber 
FROM Requests AS r_error 
LEFT JOIN Requests AS r_success 
ON (r_error.InvoiceNumber=r_success.InvoiceNumber AND r_error.status!='SUCCESS' 
    AND r_success.status='SUCCESS') 
WHERE r_success.InvoiceNumber IS NULL 

我不确定它会闪电般快,但我认为它会比最初的查询更快(我没有测试过这个理论!),但更重要的是它不使用您的订单表,因此不应该影响您的交易处理。