2010-11-26 1 views
2

Работая над системой управления контентом, я ударил немного о стену. Возвращаясь к моей модели данных, я заметил некоторые проблемы, которые со временем могут стать более распространенными.Первичные ключи, UUID, RecordKey tables, oh my

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

Аудиторский след будет вести учет user_id, record_id, timestamp, action (INSERT/UPDATE/DELETE) и archive (сериализованная копия старой записи)

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

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

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

Изменить, чтобы вопрос был неясным: Будет ли использовать глобальные идентификаторы для решения моей проблемы? Если это так, используя 128-битный UUID (сгенерированный программой или базой данных), что я могу сделать в моем дизайне таблиц, что поможет максимизировать эффективность запросов?

ответ

3

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

Но то, что вы еще не сделали, изображает, какова фактическая причина этого. Вы не сможете убежать от предсказуемого будущего, пока не сделаете это. И если вы сделаете это правильно, не будет кирпичной стены, по крайней мере, не этой конкретной кирпичной стены.

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

  1. Не повторяйте повторную ошибку. Убивание GUID или UUID или 32-байтовый Id iot столбцы для исправления ваших столбцов iot не будут ничего делать, кроме того, чтобы сделать db намного толще, и все обращается, особенно присоединяется, намного медленнее. Стена будет сделана из бетонных блоков, и она ударит вас каждый час.

  2. Вернитесь назад и посмотрите на таблицы и спроектируйте их с целью представления таблиц в базе данных. То есть ваша начальная точка Нет Surrrogate Keys, no Id iot columns. Когда вы закончите, у вас будет очень мало столбцов Id. Не ноль, не все таблицы, но очень мало. Поэтому у вас очень мало кирпичей в стене. Я недавно опубликовал подробный набор шагов требуется, поэтому, пожалуйста, обратитесь к:

    Link to Answer re Identifiers

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

    Требования к аудиту были реализованы в dbs более 40 лет, поэтому шансы ваших пользователей, имеющих какое-то другое требование , которые не изменятся, не очень высоки. Пусть он сделает это правильно. Единственный правильный метод (для Rdb) для таблиц аудита состоит в том, чтобы иметь одну таблицу аудита для каждой проверяемой реальной таблицы. PK будет оригинальной таблицей PK плюс DateTime (сложные клавиши являются нормальными в современной базе данных). Дополнительные столбцы будут UserId и Action. Сама строка будет перед изображением (новое изображение представляет собой единственную текущую строку в главной таблице). Используйте те же имена столбцов. Не упаковывайте его в одну гигантскую строку.

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

  4. Да, один стол RecordKey - это чудовище. И еще один гарантированный метод однопоточной базы данных.

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

2

Как сохранить все локальные таблицы record_id для каждой таблицы и добавить другой столбец table_name (в таблицу аудита) для создания составного ключа?

Таким образом, вы также можете легко фильтровать свой журнал аудита на table_name (что будет сложно с произвольными номерами UUID или порядковыми номерами). Поэтому, даже если вы не пойдете с этим решением, подумайте о том, чтобы добавить колонку table_name в любом случае для запроса журнала позже.

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

+0

Thanks ** Thilo **; Это соображение, которое я сделал, добавив `table_name` и используя его, как вы описали. Разумеется, добавление его в качестве дополнительной части данных для полноты в контрольном журнале могло бы помочь. Но рассмотрите эту ситуацию; Пользователь удаляет модуль блога в пользу более всеобъемлющего, но оба модуля блога используют одну и ту же схему именования для таблиц. Конфликты могут возникнуть, поскольку я не собираюсь каскадировать удаление записей аудита. Вот почему я склоняюсь к какой-то глобальной реализации. – Dan 2010-11-26 05:02:28

+1

Этот конфликт, который вы описываете, не будет проблемой, поскольку у вас все еще есть отметки времени, чтобы узнать, какой модуль используется в какой таблице. Единственная проблема будет заключаться в том, что кто-то устанавливает оба модуля одновременно, но это кажется невозможным, так как база данных также нравится, что ее имена таблиц различны. Фактически, ваша таблица аудита с вышеуказанным подходом будет очень похожа на то, как работают таблицы собственных метаданных базы данных. – Thilo 2010-11-26 05:21:08

+0

Thanks ** Thilo **; Вы правильно относитесь к установкам. Проверка установки модулей на существующие таблицы, пути и т. Д. И в зависимости от степени серьезности, уведомляет пользователя или вообще не работает. – Dan 2010-11-26 08:18:13

2

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

Смежные вопросы