Каков наилучший метод / варианты для истечения срока действия записей в базе данных? - PullRequest
5 голосов
/ 18 марта 2009

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

Итак, мой вопрос, как лучше всего истечь запись.

Я часто добавляю столбец date_expired, который является полем даты и времени. Обычно я запрашиваю либо где date_expired = 0, либо date_expired = 0 OR date_expired > NOW(), в зависимости от того, истекает ли срок действия данных в будущем. Аналогично этому, я также добавил поле вызова expired_flag. Если для этого параметра установлено значение true / 1, запись считается просроченной. Это, пожалуй, самый простой способ, хотя вам нужно помнить о необходимости включать выражение expire в любое время, когда вам нужны только текущие элементы.

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

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

Есть ли другие решения или модификации, которые лучше?

Я использую MySQL (с PHP), поэтому я не знаю, есть ли у других баз данных более эффективные методы для решения этой проблемы.

Ответы [ 9 ]

3 голосов
/ 18 марта 2009

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

2 голосов
/ 18 марта 2009

Мне нравится опция expired_flag, а не опция date_expired, если скорость запроса важна для вас.

1 голос
/ 18 марта 2009

Я всегда использовал подход ValidFrom, ValidTo, где каждая таблица имеет эти два дополнительных поля. Если ValidTo Is Null or > Now(), то вы знаете, что у вас есть действительная запись. Таким образом, вы также можете добавить данные в таблицу до ее публикации.

1 голос
/ 18 марта 2009

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

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

  1. Активный
  2. Удалено
  3. Подвесной
  4. InUse (вроде псевдоблокирующего механизма)

Установите столбец как tinyint (это SQL Server ... не уверен в эквиваленте MySQL). При желании вы также можете настроить соответствующую справочную таблицу с парами ключ / значение и ограничением внешнего ключа между таблицами.

1 голос
/ 18 марта 2009

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

По моему опыту, мы обычно просто используем бит "Active" или дату-время DateExpired, как вы упомянули. Это работает довольно хорошо, и действительно легко справиться и запросить.

Здесь есть соответствующая запись, которая предлагает несколько других вариантов. Может быть вариант CDC?

Таблица истории SQL Server - заполнить через SP или Trigger?

1 голос
/ 18 марта 2009

Я думаю, что добавление столбца date_expired - самый простой и наименее инвазивный метод. Пока ваши INSERTS и SELECTS используют явные списки столбцов (они должны быть, если нет), это не влияет на существующие операции CRUD. Добавьте индекс в столбце date_expired, и разработчики могут добавить его в качестве свойства для любых классов или логики, которые зависят от данных в существующей таблице. В целом лучшее соотношение цены и качества. Я согласен, что другие методы (например, архивные таблицы) в лучшем случае проблематичны.

0 голосов
/ 18 марта 2009

Посмотрите на алгоритмы SCD «Медленно меняющиеся измерения». Здесь есть несколько вариантов из мира хранилищ данных.

Ни один не является «лучшим» - каждый отвечает на различные требования.

Вот краткое изложение.

Тип 1 : новая запись заменяет оригинальную запись. Никаких следов старой записи не существует.

  • Тип 4 - это вариант, который перемещает историю в другую таблицу.

Тип 2 : Новая запись добавляется в таблицу измерений клиента. Чтобы различать, требуется пара столбцов «действительный диапазон дат». Это помогает иметь флаг «эта запись является текущей».

Тип 3 : Исходная запись изменяется с учетом изменений.

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

Вы можете узнать больше об этом, если будете искать «Медленно меняющееся измерение».

http://en.wikipedia.org/wiki/Slowly_Changing_Dimension

0 голосов
/ 18 марта 2009

В моих таблицах обычно есть несколько полей: creation_date, last_modification, last_modifier (от пользователя fk), is_active (логическое или число, в зависимости от базы данных).

0 голосов
/ 18 марта 2009

Очень хороший подход Oracle к этой проблеме - разделы . Я не думаю, что MySQL имеет что-то подобное, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...