2011-12-23 3 views
3

Я работаю над магазинной системой (в PHP & MySQL), которая экспортирует счета-фактуры во внешнюю систему. Процессы идут примерно так:Являются ли избыточные данные всегда бездействующими

  • Клиента заказывает товар и счет-фактура создается
  • XML генерируется для этого счета-фактуры и отправляется на внешний сервер
  • Внешний сервер обрабатывает XML и реагирующий с другим XML
  • система обрабатывает ответ.

Для каждого XML, которые будут посылаться на внешний сервер записи создается в базе данных, содержащей соответствующий INVOICENUMBER и статус (статус изначально SENT, что указывает на XML отсылается.) После того, как система обрабатывается ответ - статус SUCCESS или ERROR. Теперь проблема заключается в следующем: в какой-то момент я хочу получить список счетов-фактур, которые не имеют записи в таблице запросов со статусом SUCCESS.

EDIT: Если статус ERROR, будет выполнен новый запрос на тот же счет-фактура, поэтому существует вероятность того, что на счет-фактуру будет более одного запроса.

Мой заказ столика имеет столбцы ID и InvoiceNumber, и таблица запроса имеет столбцы ID, InvoiceNumber и Status, так, чтобы получить список упоминал, что я мог бы сделать что-то вроде:

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

это кажется очень субъективным для меня - лично я не считаю его излишним, если он приводит к быстрому запросу и медленному запросу - однако я не являюсь администратором баз данных, и я уверен, что много будет предлагать другую точку зрения – jammypeach

+0

Я бы рассмотрел денормализацию данных, как вы предлагаете, если она избегает тяжелых запросов, хотя вы можете рассмотреть другие способы оптимизации. Есть ли несколько запросов на счет-фактуру (это не на 100% ясно из вашего вопроса)? – liquorvicar

+0

@ liquorvicar; Я обновил свой вопрос; существует вероятность того, что на счет-фактуру более одного запроса. –

ответ

2

когда вы сделаете поле состояния числовой ошибки = 0 и Сукчес = 1 один вы могли бы сделать максимальный статус, сгруппированные по INVOICENUMBER, чтобы увидеть, какие счета не являются

+0

Этот вариант, однако, перешел мне в голову; есть еще несколько статусов («SENT», которые я упоминал в вопросе, но есть и другие). Считаете ли вы, что это будет вариант, чтобы дать им все количество и позволить «УСПЕХУ» быть самым высоким? –

+0

Я думаю, это зависит от количества состояний и того, как вы их объединяете. Если у вас есть только отправка, успех и ошибка, я думаю, вы можете пойти этим путем. Если вы будете добавлять больше состояний в будущем, вам нужно подготовить, что вы не противоречите max с новыми состояниями. –

+0

Я думаю, что буду использовать что-то вроде этого. –

0

война велась по нормализации :-)

Но:
Поскольку вы ищете счета-фактуры, которые не установлены в success, не могли бы вы сделать это?

SELECT InvoiceNumber 
FROM requests 
WHERE status != "SUCCESS" 

(Обратите внимание, не равный символ)

+0

Привет, Patches, спасибо за ваш ответ, но поскольку может быть более одного запроса на счет, это, к сожалению, не сработает. –

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 

Я не уверен, что это будет молниеносно, но я думаю, что это будет быстрее, чем ваш первоначальный запрос (я не тестировал эту теорию!), но что более важно, он не использует вашу таблицу заказов, поэтому не должен влиять на обработку транзакций.

Смежные вопросы