2009-04-06 4 views
18

Как создать базу данных, поддерживающую функцию, которая позволит пользователю приложения создавать моментальный снимок своих данных в определенный момент времени, немного похожий на контроль версий.Дизайн базы данных для моментального «моментального снимка» данных?

Это даст пользователю возможность вернуться назад и посмотреть, как выглядели их данные в прошлом.

Предположим, что данные, «снятые снимок», являются сложными и включают в себя объединения нескольких таблиц.

Я ищу способ дать каждому пользователю приложения возможность моментального снимка своих данных и вернуться к нему. Всего снимков базы данных не то, что я ищу.

EDIT: Спасибо за ваши ответы. Ответ на 6NF является убедительным, как и предложение де-нормализовать данные моментальных снимков из-за его простоты.

Уточнение: это не вопрос хранения данных, и вопрос о резервном копировании и восстановлении БД не является вопросом; о том, как построить схему, которая позволяет нам фиксировать состояние определенного набора связанных данных в определенный момент времени. Снимки генерируются пользователями приложения, когда они сочтут это подходящим. Пользователи не моментальный снимок всей БД, только объект данных, они заинтересованы.

+0

SQL Server 2005 или 2008. Однако, если есть еще одна СУБД, которая имеет встроенное решение этой проблемы, я бы очень хотел услышать об этом. Thx – saille

ответ

9

Мы сделали это один раз путем создания отдельных таблиц базы данных, содержащих данные, которые мы хотели снимок, но денормализованным, то есть каждая запись содержала все данные, необходимые, чтобы понять, а не ссылки на идентификаторы, которые могут или может больше не существуют. Он также добавил дату для каждой строки.

Затем мы создали триггеры для конкретных вставок или обновлений, которые сделали соединение во всех затронутых таблицах, и ввели его в таблицы моментальных снимков.

Таким образом, было бы тривиально написать то, что восстановило данные пользователей до определенного момента времени.

Если у вас есть таблица:

пользователь:

id, firstname, lastname, department_id 

отдел:

id, name, departmenthead_id 

ваш снимок таблицы пользователя может выглядеть следующим образом:

user_id, user_firstname, user_lastname, department_id, department_name, deparmenthead_id, deparmenthead_firstname, departmenthead_lastname, snapshot_date 

и запрос что-то l икэ

INSERT INTO usersnapshot 
SELECT user.id AS user_id, user.firstname AS user_firstname, user.lastname AS user_lastname, 
department.id AS department_id, department.name AS department_name 
departmenthead.id AS departmenthead_id, departmenthead.firstname AS departmenthead_firstname, departmenthead.lastname AS departmenthead_lastname, 
GETDATE() AS snapshot_date 
FROM user 
INNER JOIN department ON user.department_id = department.id 
INNER JOIN user departmenthead ON department.departmenthead_id = departmenthead.id 

Это обеспечивает каждую строку снимка правда на тот момент времени, даже если отдел или руководитель отдела изменилось за это время.

0

Oracle, начиная с версии 9i имеют Flashback технологию, которая в Oracle 10g и 11g значительно улучшились, и вы можете увидеть состояние своей базы данных в любой момент истории, если вы включили flashback.

Проверить этот документ: Flashback Overview

0

Вы можете использовать журналы, произведенные РСУБД, чтобы получить снимки ваших данных. Обычно журналы используются для восстановления базы данных. Однако они могут также использоваться для репликации данных через несколько экземпляров РСУБД или для получения моментальных снимков данных.

Чтобы получить снимок ваших данных, просто учтите все журналы, созданные до нужного момента времени. Затем вы воспроизводите эти журналы для получения фактической базы данных с восстановленными данными.

Как получить доступ и «воспроизведение» журналов зависит от конкретного продукта RDBMS, который вы используете.

Другая возможность - использовать временные базы данных. Они имеют встроенные временные аспекты и позволяют «вернуться назад». Ищите «Oracle Flashback Technology», например. http://www.stanford.edu/dept/itss/docs/oracle/10g/appdev.101/b10795/adfns_fl.htm#ADFNS1008

17

Это НЕ ПРОСТО.

Вы по существу запрашиваете временную базу данных (то, что Кристофер Дауна называет шестую обычную форму или 6NF).

Для того чтобы быть 6NF, схема должна быть также 5NF, и, в основном, для каждой точки привязки вам необходимо прикрепить временной диапазон, для которого применима привязка к такому значению. Затем в соединениях соединение должно включать только строки, находящиеся в пределах рассматриваемого временного диапазона.

Временное моделирование сложно - это то, что 6-й адрес нормальной формы - и не поддерживается в текущих РСУБД.

Проблема заключается в детализации. 6-я нормальная форма (как я ее понимаю) поддерживает временное моделирование, делая каждый не ключ (не ключ:, т. Е. Что-либо "на" сущности, которая может измениться без того, чтобы сущность потеряла свою личность) отдельное отношение. Для этого вы добавляете временную метку, временной диапазон или номер версии. Включение всего соединения решает проблему детализации, но это также означает, что ваши запросы будут более сложными и медленными. Это также требует выяснения всех ключей и неключевых атрибутов; это, как правило, большое усилие.

В принципе, везде есть отношение («Ted владеет фондовый сертификат GM с идентификатором 789») при добавлении времени: «Ted владеет фондовый сертификат GM с идентификатором 789 теперь», так что вы можете одновременно сказать, «Фред владеет сертификатом акций GM с номером 789 с 3 февраля 2000 года по вчерашний день». Очевидно, что эти отношения много-ко-многим, (теперь ted может владеть более чем одним сертификатом, а также более одного за всю свою жизнь), и fred может владеть владельцем сертификата сейчас.

Таким образом, у нас есть таблица владельцев и таблица сертификатов акций, а также таблица «многие-ко-многим», которая связывает владельцев и сертификаты по идентификатору. Для таблицы «многие ко многим» мы добавляем start_date и end_date.

Теперь представьте, что каждое государство/провинция/земельные налоги выплачивают дивиденды по сертификатам акций, поэтому для целей налогообложения необходимо зарегистрировать состояние владельца владельца акта.

Если владелец находится, очевидно, может изменяться независимо от владения акциями; ted может жить в Небраске, покупать 10 акций, получать дивиденды, что налоги в Небраске, переехать в Неваду, продавать 5 акций в fred, покупать еще 10 акций.

Но для нас это Ted может перейти в Небраске на некоторое время, купить 10 акций на некоторое время, получить дивиденды на некоторое время, какие налоги Небраска, перейти к Neveda на какое-то время , продать 5 акций fred в некоторый момент, купить еще 10 акций в некоторый момент.

Нам нужно все это, если мы хотим рассчитать, какие налоги необходимы в Небраске и в штате Невада, объединившись в совпадающие/перекрывающиеся диапазоны дат в person_stockcertificate и person_address. Адрес человека уже не один-к-одному, он один-ко-многим, потому что это адрес во временном интервале.

Если ted покупает десять акций, мы моделируем событие покупки с одной датой покупки или добавляем date_bought к каждой акции? В зависимости от вопроса нам нужна модель для ответа.

+1

Родовое решение, безусловно, сложно выполнить, но для достаточно определенного варианта использования и подмножества ваших данных решение, как я описал, может быть приемлемым. –

0

С помощью SQL Server, по крайней мере, вы можете использовать полную регистрацию и сохранять журналы транзакций между каждым набором резервных копий.

Затем вы можете сделать резервную копию момента времени.

Это плохое решение.

Что именно хочет ваш клиент? Это для аналитических целей (т. Е. Вопросы похожи на то, сколько заказов у ​​нас было две недели назад)? Потому что это именно та проблема, которую решает datawarehouse.

1

Наличие моментальных снимков и/или контрольного журнала является общим требованием к базе данных. Для многих приложений создание «теневых» или аудиторских таблиц - это простая и простая задача. Хотя резервные копии на уровне базы данных и журналы транзакций хороши, они не являются системой контроля версий.

В принципе, вам нужно создать теневую таблицу со всеми теми же столбцами, что и базовая таблица, а затем установить триггеры в базовой таблице, чтобы поместить копию строки в теневую таблицу, когда она обновляется или удаляется.

С помощью некоторой логики вы можете воссоздать то, как выглядели данные в данный момент времени. Для простого способа установить это в Sybase см .: http://www.theeggeadventure.com/wikimedia/index.php/Sybase_Tips#create_.27audit.27_columns

Если вам нужно сделать много исторических снимков, вы можете сохранить данные в одной таблице. В принципе, создайте два столбца - добавленный и удаленный столбец. Недостатком является то, что для каждого запроса вы должны добавить предложение where. Конечно, вы можете создать представление, в котором отображаются только активные записи. Это становится немного сложнее, если у вас есть нормализованная база данных с несколькими таблицами, все с историей.

Однако, это действительно работает. У вас просто есть «добавленные» и «удаленные» столбцы для каждой таблицы, а затем ваш запрос имеет момент времени интереса. Всякий раз, когда данные изменяются, вы должны скопировать текущую строку и пометить ее как удаленную.

1

Использование Log Triggers

Все данные изменения фиксируются, что дает возможность запрашивать, как будто в любой момент времени.

0

Возможно, рассмотрите возможность использования решения NoSql, такого как MongoDB, для объединения всех ваших реляционных данных в один документ, затем сохраните этот документ с отметкой времени или номером версии. Такие решения, как Kafka-Connect или Oracle Golden Gate, упрощают реляционные данные по трубопроводам в магазинах NoSql.