Некоторые сотрудники и я начали дискуссию о том, как лучше хранить исторические данные. В настоящее время для некоторых систем я использую отдельную таблицу для хранения исторических данных и сохраняю исходную таблицу для текущей активной записи. Итак, допустим, у меня есть таблица FOO. В моей системе все активные записи будут отправляться в FOO, а все исторические записи - в FOO_Hist. Многие различные поля в FOO могут быть обновлены пользователем, поэтому я хочу вести точный отчет обо всем обновленном. FOO_Hist содержит те же поля, что и FOO, за исключением автоматически увеличивающегося HIST_ID. Каждый раз , когда FOO обновляется, я выполняю оператор вставки в FOO_Hist подобное: insert into FOO_HIST select * from FOO where id = @id
.
Мой коллега говорит, что это плохой дизайн, потому что у меня не должно быть точной копии таблицы по историческим причинам, и я должен просто вставить другую запись в активную таблицу с флагом, указывающим, что это для исторических целей.
Существует ли стандарт для работы с хранилищем исторических данных? Мне кажется, что я не хочу загромождать свои активные записи всеми своими историческими записями в одной таблице, учитывая, что это может быть более миллиона записей (я думаю, в долгосрочной перспективе).
Как вы или ваша компания справляетесь с этим?
Я использую MS SQL Server 2008, но я бы хотел, чтобы ответ был общим и произвольным для любой СУБД.
источник
Я не думаю, что есть какой-то конкретный стандартный способ сделать это, но я думал, что добавлю возможный метод. Я работаю в Oracle и в нашей собственной среде веб-приложений, которая использует XML для хранения данных приложения.
Мы используем то, что называется моделью Master - Detail, которая в простейшем состоит из:
Например, главная таблица
Widgets
часто называется просто с идентификатором. Часто будет содержать данные, которые не изменятся со временем / не являются историческими.Таблица подробностей / истории, например, называется
Widget_Details
вызывающей и содержит как минимум:Таким образом, сущность начинается с того, что у 1 строки в главной и 1 строки в деталях. Деталь, имеющая конечную дату NULL и STATUS_CONTROL 'C'. Когда происходит обновление, текущая строка обновляется, чтобы иметь END_DATETIME текущего времени, а для status_control задано значение NULL (или «A», если желательно). В таблице сведений создается новая строка, которая по-прежнему связана с тем же мастером, с status_control 'C', идентификатором лица, выполняющего обновление, и новыми данными, хранящимися в столбце XMLDATA.
Это основа нашей исторической модели. Логика создания / обновления обрабатывается в пакете Oracle PL / SQL, поэтому вы просто передаете функции текущий идентификатор, ваш идентификатор пользователя и новые данные XML, а внутри все выполняет обновление / вставку строк, чтобы представить их в исторической модели. , Время начала и окончания указывают, когда эта строка в таблице активна.
Хранилище дешево, мы обычно НЕ УДАЛЯЕМ данные и предпочитаем вести контрольный журнал. Это позволяет нам видеть, как выглядят наши данные в любой момент времени. Индексируя status_control = 'C' или используя View, беспорядок не является проблемой. Очевидно, что ваши запросы должны учитывать, что вы всегда должны использовать текущую (NULL end_datetime и status_control = 'C') версию записи.
источник
Я думаю, что вы подходите правильно. Хронологическая таблица должна быть копией основной таблицы без индексов, убедитесь, что у вас есть временная метка обновления в таблице.
Если вы попробуете другой подход достаточно скоро, вы столкнетесь с проблемами:
источник
В SQL Server 2016 и более поздних версиях появилась новая функция, которая называется Temporal Tables и предназначена для решения этой проблемы с минимальными усилиями разработчика . Концепция временной таблицы похожа на сбор данных изменений (CDC), с той разницей, что временная таблица абстрагирует большинство вещей, которые вам приходилось делать вручную, если вы использовали CDC.
источник
Изменить сбор данных: https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-data-capture-sql-server?view=sql-server-2017
Он поддерживается в SQL Server 2008 R2, возможно, поддерживается в SQL Server 2008.
источник
этот вопрос довольно старый, но люди все еще работают над этим вопросом. поэтому, если вы используете oracle, вас может заинтересовать флэшбэк oracle: http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm
источник
Просто хотел добавить опцию, которую я начал использовать, потому что я использую Azure SQL, а использование нескольких таблиц было слишком громоздким для меня. Я добавил триггер вставки / обновления / удаления в свою таблицу, а затем преобразовал изменения до / после в json с помощью функции «FOR JSON AUTO».
Это возвращает представление JSON для записи до / после изменения. Затем я сохраняю эти значения в таблице истории с отметкой времени, когда произошло изменение (я также сохраняю идентификатор для текущей записи о проблеме). Используя процесс сериализации, я могу контролировать обратную засыпку данных в случае изменения схемы.
Я узнал об этом по этой ссылке здесь
источник
Вы могли бы просто разделить таблицы нет?
Стратегии секционированных таблиц и индексов с использованием SQL Server 2008 Когда размер таблицы базы данных увеличивается до сотен гигабайт или более, загрузка новых данных, удаление старых данных и обслуживание индексов может стать более трудным. Просто размер таблицы приводит к тому, что такие операции занимают намного больше времени. Даже данные, которые должны быть загружены или удалены, могут быть очень большими, что делает операции INSERT и DELETE для таблицы нецелесообразными. Программное обеспечение базы данных Microsoft SQL Server 2008 обеспечивает разбиение таблиц, чтобы сделать такие операции более управляемыми ».
источник
Реальный вопрос в том, нужно ли вам использовать исторические данные и активные данные вместе для составления отчетов? Если это так, храните их в одной таблице, разделите и создайте представление для активных записей для использования в активных запросах. Если вам нужно только время от времени смотреть на них (чтобы исследовать юридические проблемы или что-то подобное), поместите их в отдельную таблицу.
источник
JOIN
две таблицы в нескольких исторических отчетах или труднее изменить каждую вставку / обновление / удаление каждой таблицы, чтобы быть в курсе исторических проблем? На самом деле, журнал аудита будет включать даже текущие данные в таблицу истории, поэтому текущая таблица даже не требуется в отчете.Другой вариант - архивировать оперативные данные [ежедневно | ежечасно | независимо]. Большинство механизмов баз данных поддерживают извлечение данных в архив .
По сути, идея состоит в том, чтобы создать запланированное задание Windows или CRON, которое
Многие механизмы баз данных SQL поставляются с инструментом, который можно использовать для этой цели. Например, при использовании MySQL в Linux для задания извлечения можно использовать следующую команду в задании CRON:
источник
Я знаю этот старый пост, но просто хотел добавить несколько пунктов. Стандарт для таких проблем - то, что лучше всего подходит для ситуации. понимание необходимости такого хранения и потенциального использования исторических данных / данных аудита / отслеживания изменений очень важно.
Аудит (в целях безопасности) : используйте общую таблицу для всех ваших проверяемых таблиц. определить структуру для хранения имени столбца, до значения и после поля значения.
Архив / История : для случаев, таких как отслеживание предыдущего адреса, номера телефона и т. Д., Лучше создать отдельную таблицу FOO_HIST, если ваша схема активной таблицы транзакций в будущем существенно не изменится (если ваша таблица истории должна иметь такую же структуру). если вы ожидаете нормализацию таблицы, изменение типа данных, добавление / удаление столбцов, сохраняйте свои исторические данные в формате xml. определите таблицу со следующими столбцами (идентификатор, дата, версия схемы, XMLData). это легко справится с изменениями схемы. но вы должны иметь дело с XML, и это может привести к усложнению поиска данных.
источник
Вы можете использовать функцию аудита MSSQL Server. Начиная с версии SQL Server 2012 вы найдете эту функцию во всех выпусках:
http://technet.microsoft.com/en-us/library/cc280386.aspx
источник
Вы можете создать материализованные / индексированные представления на таблице. На основании ваших требований вы можете сделать полное или частичное обновление просмотров. Пожалуйста, посмотрите это, чтобы создать mview и войти. Как создать материализованные представления в SQL Server?
источник