Каков наилучший способ справиться с этим ограничением в SQL Server 2005? - PullRequest
0 голосов
/ 14 апреля 2009

У меня есть приложение для опроса на основе SMS, которое принимает домен опроса и ответ.

Я получил запросы на подробный DDL, так что ... База данных выглядит как this

SurveyAnswer.Answer должен быть уникальным для всех активных опросов для этого SurveyDomain. В терминах SQL это всегда должно возвращать 0..1 строк:

select * from survey s, surveyanswer sa
where s.surveyid = sa.surveyid and
      s.active = 1 and
      s.surveydomainid = @surveydomainid
      sa.answer = @answer

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

Ответы [ 5 ]

2 голосов
/ 14 апреля 2009

Поскольку вы покрываете 2 таблицы, у AFAIK есть только 2 способа обеспечить это.

  1. Запустите, как вы предложили.
  2. Индексированное представление с уникальным ограничением по 3 столбцам.

Что касается надежности, я бы выбрал индексированное представление, но единственным недостатком является то, что это будет трудно понять третьим лицам.

1 голос
/ 14 апреля 2009

Можно добавить ограничение, которое реализовано в UDF, например:

alter table MyTable add constraint complexConstraint
check (dbo.complexConstraintFct()=0)

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

Итак, суть: палка с триггерами .

0 голосов
/ 15 апреля 2009

Я думаю, что вы говорите, что для любого активного вопроса кортеж (surveyDomain, surveyQuestion, surveyAnswer) должен быть уникальным?

Или, другими словами, опрос: surveyanswer равен 1: 1, если опрос активен, даже если опрос: surveyanswer установлен на 1: много.

Если это так, ответ - изменить структуру таблицы. Добавление в опрос обнуляемого столбца activeAnswerId эффективно приведет к соотношению 1: 1; вашего существующего ограничения уникальный SurveyId (или уникальный SurveyId, SurvetDomainId) будет достаточно для обеспечения уникальности.

Действительно, если только я не неправильно понял, я удивлен, что в Survey есть колонка Вопроса; Я ожидаю, что Опрос: Вопрос будет 1: много (в опросе много вопросов) или даже много: много, если вопрос может появиться в нескольких опросах.

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

OP комментарии:

нет, вы упускаете это. Опрос: Ответ 1: n. «Вопрос» - это вопрос опроса. Кортеж будет (SurveyDomain.SurveyDomainId, Survey.Answer)

Вы имеете в виду, что для каждого домена есть не более одного ответа? Опять же, глядя на вашу схему, она в лучшем случае вводит в заблуждение. SurveyDomain имеет много опросов (в каждом из которых есть столбец «Вопрос»), а опрос содержит много ответов? ( Схема )

Но если установлен активный бит опроса, должен быть только один ответ?

Является ли опрос неправильным вопросом для вопроса?

Не совсем понятно, что вы пытаетесь смоделировать.

Опять же, если сложно добавить ограничение, это говорит о том, что ваша модель не работает.

0 голосов
/ 14 апреля 2009

Вы не можете сделать это на уровне строк (например, ограничение CHECK), поэтому вам нужно что-то, что может просматривать все строки

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

Индексированное представление предотвращает оператор DML, но выдает техническое сообщение об ошибке. Это дополнительный объект и индексы для обслуживания.

0 голосов
/ 14 апреля 2009

Предполагая, что вы используете хранимые процедуры для выполнения операций DML, вы можете добавить в SP пункт защиты, который добавляет ответы на опросы, чтобы проверить наличие эквивалентного ответа. Затем вы можете либо сгенерировать исключение, либо вернуть код состояния, чтобы указать, что ответ не может быть добавлен.

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