2008-09-30 4 views
14

У меня есть вопрос относительно двух дополнительных столбцов (timeCreated, timeLastUpdated) для каждой записи, которую мы видим во многих решениях. Мой вопрос: есть ли лучшая альтернатива?Как вы не добавляете поля timestamp в свои таблицы?

Сценарий: у вас есть огромная БД (с точки зрения таблиц, а не записей), а затем приходит клиент и просит добавить «временную привязку» к 80% ваших таблиц.

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

Чтобы представить это, предположим, этот базовый сценарий. Мы бы две таблицы:

ОПЛАТА: - (ваши обычные записи)
TIMESTAMP: - {текущий временной метки} + {TABLE_UPDATED, id_of_entry_updated, timestamp_type}

Обратите внимание, что в этой конструкции не нужны те, два «дополнительных» столбца в вашем родном объекте оплаты (который, кстати, может сделать это через ваше решение ORM), потому что теперь вы индексируете TABLE_UPDATED и id_of_entry_updated. Кроме того, timestamp_type расскажет вам, есть ли запись для вставки (например, «1»), обновление (например, «2») и все, что вы можете добавить, например «удаление».

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

Приветствия, Эдуардо

ответ

12

Пока вы на нем, также записывайте пользователя, внесшего изменения.

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

Если вы используете SQL Server, новая версия 2008 поддерживает то, что они называют Change Data Capture, что должно забрать большую боль, о которой вы говорите. Я думаю, что у Oracle может быть что-то подобное.

Обновление: Очевидно, Oracle называет это тем же, что и SQL Server. Или, скорее, SQL Server называет это то же самое, как Oracle, так как внедрение Oracle, пришел первый;)
http://www.oracle.com/technology/oramag/oracle/03-nov/o63tech_bi.html

1

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

Logging записи изменений в отдельном файле означает, что вы можете показать несколько изменений в записи, как:

мм/дд/гг чч: мм: сс Добавил XXX мм/дд/гггг чч: мм: ss Поле ЦЕНА Изменено на XXX, мм/дд/гггч hh: мм: ss Запись удалена XXX

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

5

Я думаю, что я предпочитаю добавлять временные метки к отдельным таблицам. Присоединение к таблице timestamp на составном ключе - одна из которых является строкой - будет медленнее, и если у вас будет большой объем данных, это в конечном итоге станет реальной проблемой.

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

+0

соединение не обязательно должно использовать строку как часть предложения «ВКЛЮЧЕНО». Если это первая часть индекса, она может быть проверена только один раз за запрос в зависимости от того, насколько хорош оптимизатор. – BCS 2008-09-30 20:45:46

+0

Но если он хранит временные метки из разных таблиц в одной большой таблице TIMESTAMP, ему потребуется дифференцировать временные метки INVOICE от, например, временных меток USERACCOUNT, так что это не должно быть: ON TIMESTAMP.id_of_entry И tablename = 'INVOICE «? – Dana 2008-09-30 20:49:55

+0

Я считаю, что у вас есть точка, Дана. Однако, поскольку имена таблиц уникальны, вы думаете, что я могу уйти с простым хэшем (например, используя ascii-представление имен таблиц, чтобы сделать его int)? Таким образом, я бы завершил индексирование двух полей int. что вы думаете? – esegura 2008-09-30 21:07:41

0

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

1

Если вы устанавливаете отметку времени вещи, чтобы бежать из триггеров, чем каких-либо действий, которые могут Зачет триггер (Чтение?) может быть зарегистрирован. Также могут быть некоторые преимущества блокировки. не

(Возьмите все, что с зерном соли, я не DBA или SQL гуру)

10

Я использовал дизайн, где каждая таблица для аудита были две таблицы:

create table NAME (
    name_id int, 
    first_name varchar 
    last_name varchar 
    -- any other table/column constraints 
) 

create table NAME_AUDIT (
    name_audit_id int 
    name_id int 
    first_name varchar 
    last_name varchar 
    update_type char(1) -- 'U', 'D', 'C' 
    update_date datetime 
    -- no table constraints really, outside of name_audit_id as PK 
) 

A создается триггер базы данных, который заполняет NAME_AUDIT каждый раз, когда что-либо делается до NAME. Таким образом, у вас есть запись каждого изменения, внесенного в таблицу, и когда. Приложение не знает об этом, так как оно поддерживается триггером базы данных.

Он работает достаточно хорошо и не требует каких-либо изменений в коде приложения для реализации.

1

Да, мне нравится этот дизайн и используйте его с некоторыми системами. Как правило, некоторые варианты:

LogID int 
Action varchar(1)  -- ADDED (A)/UPDATED (U)/DELETED (D) 
UserID varchar(20) -- UserID of culprit :) 
Timestamp datetime -- Date/Time 
TableName varchar(50) -- Table Name or Stored Procedure ran 
UniqueID int   -- Unique ID of record acted upon 
Notes varchar(1000) -- Other notes Stored Procedure or Application may provide 
0

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

Один недостаток - это отчетность и/или отображение множества разных марок на экране. Если вы делаете это так, как мы это делали, это вызвало много стыков. Кроме того, задние окончание изменений было болью.

0

Наше решение состоит в том, чтобы сохранить таблицу «Транзакции» в дополнение к нашей таблице «Сессия». Команды UPDATE, INSERT и DELETE управляются через объект «Транзакция», и каждая из этих инструкций SQL хранится в таблице «Транзакция», как только она была успешно выполнена в базе данных. В этой таблице «Транзакция» есть другие поля, такие как transactiontType (I для INSERT, D для DELETE, U для UPDATE), transactionDateTime и т. Д. И внешний ключ «sessionId», сообщая нам, наконец, кто отправил инструкцию. Даже через некоторый код можно определить, кто и что (когда Гас создал запись в понедельник, Тим изменил Стоимость единицы во вторник, Лиз добавила дополнительную скидку в четверг и т. Д.).

Pros для этого решения являются:

  1. вы сможете сказать «что, кто и когда», и показать его своим пользователям! (Вам потребуется код для анализа заявления SQL)
  2. , если данные репликации и репликации не удается, вы можете восстановить базу данных с помощью этой таблицы

Cons являются

  1. 100 000 данных обновления в месяц означают 100 000 записей в Tbl_Transaction
  2. Наконец, эта таблица имеет тенденцию быть 99% от объема вашей базы данных

Наша чо лед: все записи старше 90 дней автоматически удаляются каждое утро

-1

Philippe,

Не просто удалить эти старше 90 дней, переместить их первый в отдельную БД или записать их в текстовый файл, сделать что-то чтобы их сохранить, просто выведите их из основной производственной БД.

Если когда-либо доходит до него, чаще всего это случай «с наибольшим количеством документов»!

1

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

Если ваш код сломался на уровне GUI из-за добавления полей, которые вы не хотите видеть, вы неправильно записываете код в свой графический интерфейс, который должен указывать только минимальное количество столбцов, которые вам нужны, и никогда не выбирать * ,