Eu tenho uma lista de produtos. Cada um deles é oferecido por N fornecedores.
Cada fornecedor cita um preço para uma data específica. Esse preço é efetivo até que o provedor decida estabelecer um novo preço. Nesse caso, o provedor fornecerá o novo preço com uma nova data.
O cabeçalho da tabela MySQL atualmente se parece com:
provider_id, product_id, price, date_price_effective
A cada dois dias, compilamos uma lista de produtos / preços efetivos para o dia atual. Para cada produto, a lista contém uma lista classificada dos fornecedores que possuem esse produto específico. Dessa forma, podemos solicitar determinados produtos a quem quer que oferecer o melhor preço.
Para obter os preços efetivos, eu tenho uma instrução SQL que retorna todas as linhas que possuem date_price_effective >= NOW()
. Esse conjunto de resultados é processado com um script ruby que faz a classificação e a filtragem necessárias para obter um arquivo parecido com este:
product_id_1,provider_1,provider_3,provider8,provider_10...
product_id_2,provider_3,provider_2,provider1,provider_10...
Isso funciona bem para nossos propósitos, mas ainda sinto que uma tabela SQL provavelmente não é a melhor maneira de armazenar esse tipo de informação. Tenho a sensação de que esse tipo de problema foi resolvido anteriormente de outras maneiras mais criativas.
Existe uma maneira melhor de armazenar essas informações além do SQL? ou, se estiver usando SQL, existe uma abordagem melhor do que a que estou usando?
fonte
Respostas:
Para itens que variam com base no tempo (como poder responder a coisas como "qual era o preço de X na data D" ou "qual vaca estava no confinamento Q na data E"), recomendo a leitura do livro "Desenvolvendo o Tempo Aplicativos de banco de dados em SQL ". Enquanto este livro está esgotado, o autor graciosamente disponibilizou o PDF do livro e o CD associado em seu site.
http://www.cs.arizona.edu/~rts/publications.html (procure o primeiro item em "livros").
Para uma breve introdução online, consulte:
fonte
Eu certamente armazenaria a data efetiva no banco de dados. Afinal, é provável que as pessoas desejem executar consultas para ver como o preço mudou ao longo do tempo ou fazer uma verificação cruzada de esquisitices em pedidos em relação à tabela histórica de preços do produto. Dependendo do tipo de consulta que você está executando e da frequência das alterações de preço, pode fazer sentido ter tabelas separadas para o preço atual e os preços históricos.
Na maioria dos sistemas que armazenam preços, você deseja uma coluna de data de vencimento, além da data efetiva, para facilitar a determinação de qual preço está atualmente em vigor, uma vez que evita o problema de ter que olhar para a linha anterior ou seguinte para descobrir qual preço estava em vigor em um determinado momento. Não sei ao certo o que sua
NOW() >= date_price_effective
condição está fazendo - presumivelmente, isso retorna o preço atual junto com todos os preços históricos anteriores que me parecem estranhos. Eu pensaria que o "preço efetivo" seria o preço atual que seria definido por algo comoNOW() BETWEEN date_price_effective AND date_price_expired
Também não tenho certeza de como seu arquivo deve ser. Não está claro para mim o que
provider_1
representa - o preço provider_id = 1? - ou como você está solicitando os dados do provedor - por queprovider_1
aparece primeiroproduct_id_1
e terceiro noproduct_id_2
.fonte
Se eu entendi sua declaração do problema corretamente, você precisa de uma maneira de lidar com dados geracionais (ou seja, a tabela contém várias linhas para cada par provider_id / product_id, cada qual com sensibilidade à data). Nesse caso, você está procurando o preço mais recente de um produto com um valor date_price_effective menor ou igual a hoje. Esse tipo de situação é fácil de lidar usando uma subseleção SQL.
Um preço é efetivo desde que tenha o maior valor date_price_effective menor ou igual à data em que a consulta é executada. Um valor date_price_effective maior que hoje é uma data efetiva futura. O código listado acima retorna os dados da linha para cada par provider_id / product_id que possui o valor date_price_effective mais próximo, mas não depois da data em que a consulta é executada. A solução agrupa automaticamente os preços em períodos efetivos. A chave primária para esta tabela seria o triplo {id_fornecedor, id_produto, data_effetivo_de_projeto};
fonte