Вопрос о дизайне данных, круговые внешние ключи - PullRequest
0 голосов
/ 02 мая 2011

Я немного упрощаю это, но у нас есть таблица User и таблица TestResult в большой существующей базе данных sql2008, используемой большим зрелым проектом .net.Пользователям предоставляется множество тестов, и к ним часто обращаются, поэтому для ускорения работы пользовательская таблица содержит CurrentTestResult и PendingTestResult для последнего теста и выполняемого теста соответственно.Также вы не можете просто посмотреть на дату, чтобы найти текущий тест, так как иногда тест может быть признан недействительным, то же самое с ожиданием.

TestResult, конечно, содержит внешний ключ для UserID, а у пользователя есть 2 внешних ключауказывая на TestResult.Так было давно, без особых проблем.Иногда каким-то образом тест прикрепляется к пользователю, хотя это не его тест, поэтому он явно не идеален, и мне все равно нужно отследить дыру.

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

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

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

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

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

D)?

Я уверен, что это довольно распространенный паттерн, есть ли "правильный"Решение?

Ответы [ 2 ]

0 голосов
/ 03 мая 2011

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

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

create table xref (
    user_id integer not null references users (user_id),
    current_test_result whatever not null references tests (test_id),
    pending_test_result whatever references tests (test_id),
    primary key (Hmmmmm)
);

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

0 голосов
/ 03 мая 2011

Вы уверены, что вариант А действительно будет проблемой производительности? Если в вашей тестовой таблице есть индекс, который содержит пользовательский FK, а затем что-то в хронологическом порядке - либо столбец IDENTITY, либо временную метку теста, тогда этот индекс будет очень полезен, когда вы выбираете TOP 2 из таблицы TEST, где user_id = X Вам не нужно беспокоиться о том, что ваши круглые внешние ключи выходят из строя.

...