Выражение ограничений данных в SQL - PullRequest
0 голосов
/ 02 февраля 2009

Я пишу заявку на планирование для моей жены, и я столкнулся со следующим вопросом.

У меня есть схема, которую можно описать в терминах ActiveRecord следующим образом:

  • Каждый ресурс имеет и принадлежит многим событию s
  • Каждое событие имеет и принадлежит ко многим ресурсам с, и имеет много интервалов времени с
  • Каждый интервал времени принадлежит событию и имеет три атрибута: день , время начала и конец -время .

Я хочу наложить следующие ограничения на мои данные:

    A. For each <i>timespan</i>, <i>timespan.start-time &le; timespan.end-time</i>
    B. For each <i>event</i>, for each <i>t_a</i>, <i>t_b</i> &isin; <i>TIMESPANS(event)</i>, 
       either <i>t_a = t_b</i>
           or <i>t_a.day &ne; t_b.day</i>
           or <i>t_a.end-time &le; t_b.start-time</i>
           or <i>t_a.start-time &ge; t_b.end-time</i>
    C. For each <i>resource</i>, for each <i>e_a</i>, <i>e_b</i> &isin; <i>EVENTS(resource)</i>,
       either <i>e_a = e_b</i>
           or for each <i>t_a</i> &isin; <i>TIMESPANS(e_a)</i> and <i>t_b</i> &isin; <i>TIMESPANS(e_b)</i>,
              either <i>t_a.day &ne; t_b.day</i>
                  or <i>t_a.end-time &le; t_b.start-time</i>
                  or <i>t_a.start-time &ge; t_b.end-time</i>

(A) гарантирует, что временные промежутки правильно сформированы, (B) гарантирует, что события не конфликтуют друг с другом, и (C) обеспечивает, чтобы ресурсы не были перепланированы.

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

Есть ли способ выразить эти ограничения в SQL?

EDIT: Поэтому я обнаружил, что мне нужно было выражение CREATE ASSERTION в SQL (по крайней мере, для тех, которые не могут быть охвачены простым CHECK), но это не похоже ни на одну СУБД, поддерживающую его () по крайней мере, по состоянию на 2005 год )

1 Ответ

2 голосов
/ 02 февраля 2009

A легко выражается в CHECK CONSTRAINT в вашей таблице временного интервала, поскольку каждая строка может проверить себя на согласованность, не проверяя другие строки.

B и C более сложны и требуют считывания информации из других таблиц. В этом случае (по крайней мере, в SQL Server) можно использовать пользовательскую функцию (передавая ей значения из текущей строки) для проверки других таблиц или использовать TRIGGER, который будет проверять другие таблицы.

Примечание: при написании такого триггера помните, что триггер срабатывает один раз для оператора SQL. Если в этом операторе INSERT s или UPDATE s несколько строк, таблица INSERTED будет содержать несколько строк, которые должны быть проверены на соответствие ограничениям вашего домена с использованием соответствующего метода, такого как JOIN.

Кстати: у Джо Селко недавно была хорошая статья об ограничениях.

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