Мне нужно будет отслеживать изменения цен на товары, чтобы я мог запросить в БД цену товара на определенную дату. Информация используется в системе, которая вычисляет прошлые аудиты, поэтому она должна возвращать правильную цену для правильного продукта на основе даты покупки.
Я бы предпочел использовать postgres при создании базы данных.
Мне нужно с дизайном базы данных, но также приветствуются любые и лучшие рекомендации.
database-design
best-practices
Гуннар Норред
источник
источник
prices
создайте таблицуprices_history
с похожими столбцами. Hibernate Envers может автоматизировать это для васОтветы:
Если я правильно понимаю сценарий, вы должны определить таблицу, в которой сохранен временной ряд Price ; поэтому, я согласен, это во многом связано с временным аспектом базы данных, с которой вы работаете.
Бизнес правила
Давайте начнем анализировать ситуацию с концептуального уровня. Так что, если в вашей сфере бизнеса,
тогда это означает, что
IDEF1X - схема показана на рисунке 1 , хотя и очень упрощена, изображает такой сценарий:
Описательная логическая схема
И следующая схема логического уровня SQL-DDL, основанная на упомянутой диаграмме IDEF1X, иллюстрирует выполнимый подход, который вы можете адаптировать к вашим собственным точным потребностям:
Price
Таблица имеет составной первичный ключ, состоящие из двух колонок, т.е.ProductNumber
(сдержанные, в свою очередь, в качестве внешнего ключа , который делает ссылку наProduct.ProductNumber
) иStartDate
(указывая конкретную Дату , в которой определенный продукт был куплен в определенной Цене ) ,В случае, если товары приобретаются на разных Цены в тот же день , вместо
StartDate
колонки, вы можете включать в себя один помеченный , какStartDateTime
что держит Instant , когда данный продукт был куплен в точном цена . ПЕРВИЧНЫЙ КЛЮЧ должен быть объявлен как(ProductNumber, StartDateTime)
.Как показано, вышеупомянутая таблица является обычной, потому что вы можете объявить операции SELECT, INSERT, UPDATE и DELETE, чтобы напрямую манипулировать ее данными, следовательно, она (a) позволяет избежать установки дополнительных компонентов и (b) может использоваться во всех основные платформы SQL с некоторыми изменениями, если это необходимо.
Образцы манипулирования данными
В качестве примера некоторые манипуляции операции , которые кажутся полезными, давайте скажем , что вы вставили следующие данные в
Product
иPrice
таблицы, соответственно:Так как
Price.EndDate
точка извлекаемых данных, то вы должны получить ее через точно производную таблицу, которая может быть создана как представление , чтобы создать «полный» временной ряд, как показано ниже:Затем следующая операция, которая выбирает непосредственно из этого представления
поставляет следующий набор результатов:
Теперь, давайте предположим , что вы заинтересованы в получении целые
Price
данные дляProduct
прежде всего идентифицируютсяProductNumber
1750 поDate
2 июня 2017 года . Видя, чтоPrice
утверждение (или строка) является текущим или эффективным в течение всего интервала, который проходит от (i) егоStartDate
до (ii) егоEndDate
, тогда эта операция DMLдает следующий набор результатов
который обращается к указанному требованию.
Как показано,
PriceWithEndDate
представление играет первостепенную роль в получении большей части извлекаемых данных и может быть ВЫБРАНО ИЗ довольно обычным способом.Учитывая, что вашей платформой предпочтений является PostgreSQL, этот контент с официального сайта документации содержит информацию о «материализованных» представлениях , которые могут помочь оптимизировать скорость выполнения с помощью механизмов физического уровня, если указанный аспект становится проблематичным. Другие системы управления базами данных SQL (СУБД) предлагают физические инструменты, которые очень похожи, хотя может применяться другая терминология, например, «индексированные» представления в Microsoft SQL Server.
Вы можете увидеть обсуждаемые примеры кода DDL и DML в действии в этой скрипте db <> и в этой скрипте SQL .
Связанные ресурсы
В этом разделе « Вопросы и ответы» мы обсуждаем бизнес-контекст, который включает изменения цен на продукцию, но имеет более широкий охват, поэтому вы можете найти его интересным.
Эти сообщения о переполнении стека охватывают очень важные вопросы, касающиеся типа столбца, который содержит данные о валюте в PostgreSQL.
Ответы на комментарии
Метод, который я предлагаю выше, обращается к бизнес-сфере с ранее описанными характеристиками , следовательно, применение вашего предложения об объявлении
EndDate
столбца (который отличается от «поля») названной базовой таблицыPrice
будет означать, что логическая структура базы данных будет не отражать концептуальную схему правильно, и концептуальная схема должна быть определена и отражена с точностью, включая дифференцирование (1) базовой информации от (2) выводимой информации.Кроме того, такой порядок действий привел бы к дублированию, поскольку
EndDate
затем его можно было бы получить с помощью (a) производной таблицы, а также с помощью (b) названной базовой таблицыPrice
с таким образом дублированнымEndDate
столбцом. Хотя это и возможно, если практикующий врач решит следовать указанному подходу, он или она должны решительно предупредить пользователей базы данных о неудобствах и недостатках, которые с этим связаны. Одним из таких неудобств и неэффективностей является, например, настоятельная необходимость разработки механизма, который всегда обеспечивает , чтобы каждоеPrice.EndDate
значение равнялось значениюPrice.StartDate
столбца непосредственно следующего ряда для имеющегосяPrice.ProductNumber
значения.Напротив, работа по созданию рассматриваемых производных данных, как я выдвинул, честно говоря, вовсе не особенная, и она должна (i) гарантировать правильное соответствие между логическим и концептуальным уровнями абстракции базы данных и (ii) ) обеспечить целостность данных, оба аспекта, которые, как отмечалось ранее, имеют решающее значение.
Если аспект эффективности, о котором вы говорите, связан со скоростью выполнения некоторых операций с данными, то этим нужно управлять в соответствующем месте, то есть на физическом уровне, например, с помощью выгодной стратегии индексации, основанной на (1 ) конкретные тенденции запросов и (2) конкретные физические механизмы, предоставляемые СУБД использования. В противном случае, отказ от соответствующего концептуально-логического отображения и компрометация целостности данных легко превращает надежную систему (т. Е. Ценный организационный актив) в ненадежный ресурс.
Разрывные или несвязанные временные ряды
С другой стороны, существуют обстоятельства, когда сохранение
EndDate
каждой строки в таблице временных рядов не только более удобно и эффективно, но и востребовано , хотя это, конечно, полностью зависит от требований конкретной бизнес-среды. Один пример такого рода обстоятельств возникает, когдаЯ представил указанный сценарий на диаграмме IDEF1X, показанной на рисунке 2 .
В этом случае, да, гипотетическая
Price
таблица должна быть объявлена способом, подобным этому:И да, эта логическая структура DDL упрощает администрирование на физическом уровне, поскольку вы можете создать стратегию индексирования, которая охватывает
EndDate
столбец (который, как показано, объявлен в базовой таблице) в относительно более простых конфигурациях.Затем операция SELECT, как показано ниже
могут быть использованы для получения целых
Price
данных дляProduct
главным образом идентифицированыProductNumber
1750 наDate
2 июня 2017 года .источник
Я верю, что вы захотите посмотреть на временные таблицы . Они предоставляют функциональные возможности для выполнения именно того, что вы ищете, и доступны в Postgres с соответствующими расширениями.
Эта концепция также выглядит довольно независимой от БД, поскольку она предлагается на различных платформах RDBMS .
источник
Я дал здесь ответ, который относительно прост и не требует специальных расширений для базы данных (поэтому будет работать с любой базой данных).
источник