2010-08-23 4 views
2

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

Я предполагаю, что мне понадобится хотя бы 2 таблицы, одна из которых содержит uid и другую, которая содержит ревизии. Затем я присоединяюсь к ним и запрашиваю последнюю версию. Но должен ли я разбить его еще дальше, в зависимости от того, как часто изменяются данные или тип данных? Я смотрю около 40 полей на запись, и только одно или два поля, вероятно, будут меняться за обновление. Также я не могу удалить данные из базы данных, мне нужно иметь возможность оглядываться на все предыдущие записи.

ответ

2

Простой способ сделать это - добавить удаленный флаг, и вместо обновления записей вы установите удаленный флаг в существующую запись и вставьте новую запись.

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

Чтобы получить активную запись, запрос с 'where deleted = 0', влияние скорости будет минимальным, если в этом поле есть индекс.

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

+0

Как бы мог помочь индекс в столбце 'deleted'? Если механизм запроса использует этот индекс, не нужно ли выполнять сканирование таблицы для всех остальных столбцов? Не лучше ли индексировать поле, которое вы ищете, и просто отбросить удаленные строки из результатов поиска? –

+1

Нет, он использовал бы сканирование индекса в удаленном столбце, а затем поиск в других столбцах. Вы можете иметь несколько индексов, а оптимизатор запросов будет использовать статистические данные, собранные в базе данных, для оценки относительной производительности каждого индекса и размещения их в порядке, чтобы сначала использовать индекс, который должен давать наименьшие результаты. Попробуйте использовать EXPLAIN PLAN для некоторых запросов, чтобы узнать, как это работает. Оптимизаторы обычно настолько умны, что им известно, что индекс не стоит использовать, если только 10% записей фактически удалены. –

+0

Итак, позвольте мне повторить. У меня было бы две таблицы, одна из которых с неизменными идентификаторами сотрудников и одна с изменчивой информацией о персонале. Эта таблица сведений о персонале будет иметь индексированное поле (удаленное), которое я установил бы, когда новая запись будет вставлена ​​для этого сотрудника. Когда я хочу запросить самую последнюю версию, я просто ограничиваю, где удалено = 0. Я что-то пропустил? –

2

Я бы использовал отдельную таблицу, потому что тогда у вас может быть уникальный идентификатор, который указывает на все остальные дочерние записи, которые также являются PK таблицы, которые, по моему мнению, делают менее вероятными проблемы с целостностью данных. Например, у вас есть Мэри Джонс, у которой есть записи в таблице адресов, таблице электронной почты и таблице оценки эффективности и т. Д. Если вы добавите запись изменений в основную таблицу, как вы собираетесь переписывать всю существующую информацию? С отдельной исторической таблицей это не проблема.

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

У вас также есть возможность забыть использовать аргумент where deleted = 0 where, необходимый для почти каждого запроса. (Если вы используете поле удаляемого флага, сделайте себе одолжение и установите представление с удаленным = 0 и попросите разработчиков использовать представление в запросах, а не в исходной таблице.)

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

+0

+1 Ты сказал, что я чувствую. :-) –

+0

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

0

@ Предложение Питера Тиллеманса является распространенным способом достижения того, о чем вы просите. Но мне это не нравится.

Структура базы данных должна отражать реальные факты, которые моделируются.

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

Просто подумайте об этом теплом ощущении, которое вы получите, когда наберете select * from employee, и ничего, кроме текущего, правильное доброе придет обратно!

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