2011-01-20 4 views
1

Как сохранить исторические реляционные данные, если строки изменены? В этом примере пользователям разрешено редактировать строки в таблице свойств в любое время. Тесты могут иметь любое количество свойств. Если они изменяют поле «Имя» в таблице «Свойства» или удаляют строку в таблице «Свойства», тестовые строки могут не содержать условий во время теста. Вы изменили бы дизайн таблицы Test, добавив столбец имен свойств и сбросив таблицу сопоставления TestProperty? Столбец имен свойств должен быть чем-то вроде разделительного списка строк. Как обычно обрабатывается проблема?Проблема проектирования реляционных таблиц

3 таблицы:

Test: 
    TestId  AUTONUMBER, 
    Name  CHAR, 
    TestDate DATE 

Property: 
    PropertyId AUTONUMBER, 
    Name  CHAR 

TestProperty: (maps properties to tests) 
    TestId 
    PropertyId 

ответ

1

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

Если вы сделаете это, вам понадобится создать какой-то способ сбора мусора неактивных свойств.

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

+0

Я не думал о том, чтобы сделать строки неактивными. Это отличная идея. –

+0

Кроме того, если вы создаете копии свойств, когда пользователи обновляют имена свойств, вам придется скопировать все значения свойства. Вам также придется решить, что, поскольку это отношение multi-to-multi, если вы хотите, чтобы все остальные тесты использовали новое имя свойства. Если это так, вам придется обновить все остальные записи в TestProperty, дублируя все записи со старым идентификатором свойства и устанавливая дубликаты для использования нового идентификатора свойства. –

1

Похоже, вы используете Test как шаблон для конкретного экземпляра теста, так и сам тест. Может быть, каждый раз, когда пользователь выполняет тест в соответствии со спецификацией в Test, создайте строку, например, TestRun? Это сохранит конкретный Property s, и если записи в Property изменятся позже, последующие TestRun s будут отражать новые изменения.

+0

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

3

Не думаю, что на этот вопрос был дан ответ.

Если изменить значение поля «Имя» в таблице недвижимости ... Вы бы изменить дизайн таблицы Test, добавив столбец имен свойств и удаление таблицы отображения TestProperty?

Определенно нет. Это добавило бы массового дублирования для цели.

Если ваше требование заключается в поддержании целостности значений данных (в свойстве) во время тестирования, правильным (базовым) методом является внедрение таблицы истории. Это должна быть точная копия исходной таблицы плюс один элемент: в PK добавляется столбец TIMESTAMP или DATETIME.

PropertyHistory 
    PropertyId AUTONUMBER, 
    Name  CHAR 
    CONSTRAINT PRIMARY KEY CLUSTERED UC_PK (PropertyId)
PropertyHistory PropertyId INT, AuditedDtm DATETIME, Name CHAR CONSTRAINT PRIMARY KEY CLUSTERED UC_PK (PropertyId, AuditedDtm)
For this to be meaningful and useable, the Test table needs a timestamp as well, to identify which version of ProperyHistory to reference:
TestProperty 
    TestId 
    PropertyId 
    TestDtm  DATETIME

The property names column would have to be something like a delimited list of strings.

That would break basic design rules as well as Database Normalisation rules, and prevent you from performing ordinary Relational operations on it. Never store more than one data value in a single column.

... or drop a row in the Property table

Deletion is something different again. If it is a "database" then it has Integrity. Therfore you cannot delete a parent row if it has child rows in some other table (and you can delete it if it does not have children). This is usually implemented as a "soft delete", an Indicator such as IsObsolete. Это относится к различным SELECTS, чтобы исключить использование строки (для добавления новых детей), но остается доступной в качестве родителя для существующих детей.

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