Как вы избегаете добавления полей временных меток в свои таблицы?[закрыто]

StackOverflow https://stackoverflow.com/questions/154964

  •  03-07-2019
  •  | 
  •  

Вопрос

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

Сценарий:У вас огромная база данных (с точки зрения таблиц, а не записей), а затем приходит клиент и просит вас добавить "временные метки" к 80% ваших таблиц.

Я полагаю, что этого можно достичь, используя отдельную таблицу (ВРЕМЕННЫЕ МЕТКИ).Эта таблица должна содержать, в дополнение к очевидному столбцу метки времени, имя таблицы и первичный ключ для обновляемой таблицы.(Я предполагаю здесь, что вы используете int в качестве первичного ключа для большинства ваших таблиц, но имя таблицы, скорее всего, должно быть строкой).

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

ОПЛАТА: - (ваши обычные записи)
ВРЕМЕННАЯ МЕТКА: - {текущая временная метка} + {TABLE_UPDATED, id_of_entry_updated, timestamp_type}

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

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

Твое здоровье, Эдуардо

Это было полезно?

Решение

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

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

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


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

Другие советы

Я использовал дизайн, в котором каждая таблица, подлежащая аудиту, состояла из двух таблиц:

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
)

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

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

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

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

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

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

мм/дд/гг чч: мм:сс Добавлено XXX цена поля мм/дд/гг чч: мм: сс Изменена XXX, мм / дд /гг чч: мм: Запись ss, удаленная XXX

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

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

(Отнеситесь ко всему этому с недоверием, я не администратор базы данных или SQL-гуру)

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

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

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

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

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

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

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

Наше решение заключается в поддержании таблицы "Транзакции" в дополнение к нашей таблице "Сеанса".Все инструкции по ОБНОВЛЕНИЮ, ВСТАВКЕ и УДАЛЕНИЮ управляются через объект "Transaction", и каждая из этих инструкций SQL сохраняется в таблице "Transaction" после ее успешного выполнения в базе данных.Эта таблица "Transaction" содержит другие поля, такие как transactiontType (I для ВСТАВКИ, D для УДАЛЕНИЯ, U для ОБНОВЛЕНИЯ), transactionDateTime и т.д., А также внешний ключ "SessionID", сообщающий нам, наконец, кто отправил инструкцию.С помощью некоторого кода даже возможно определить, кто, что и когда сделал (Гас создал запись в понедельник, Тим изменил цену за единицу во вторник, Лиз добавила дополнительную скидку в четверг и т.д.).

Плюсами этого решения являются:

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

Минусы заключаются в следующем

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

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

Филипп,

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

Если уж на то пошло, то чаще всего это случай "выигрывает тот, у кого больше документации"!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top