Является ли хорошей идеей дублировать столбцы в таблицах, чтобы обеспечить проверку ограничений? - PullRequest
2 голосов
/ 05 февраля 2010

Я столкнулся с ситуацией, когда у меня есть две таблицы: A и B. B имеет внешний ключ для A.

A имеет столбец «Подробно», в котором указывается, требуется ли заполнять его раздел «Детали».

Если у меня есть своя структура, то я не могу определить, нужно ли заполнять раздел «Детали» записи в B, т. Е. Не ноль, без присоединения к A. Таким образом, единственный способ для меня запретить кому-либо вставлять или обновлять эти записи в недопустимое состояние - это иметь триггер для соединения с А и проверить его столбец «Подробно».

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

Я мог бы получить это, продублировав столбец «Подробно» в B, а затем установив проверочное ограничение («Подробно» = «Y» И подробности НЕ НУЛЬ ») ИЛИ (« Подробно »=« N »)

Мысли о том, как лучше подойти к этому?

Ответы [ 5 ]

3 голосов
/ 05 февраля 2010

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

Простые бизнес-правила, такие как «всегда иметь ссылку», «не иметь NULL» и т. Д., Могут применяться с ограничениями.

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

Ограничения не являются «лучше» или «хуже», чем триггеры: они представляют собой всего лишь ярлык для правил, которые необходимо часто выполнять.

Для вашей задачи просто используйте триггер.

Однако в Oracle и ограничения, и триггеры реализованы не чисто на основе множеств. Они вызываются в цикле для каждой записи, затронутой операцией DML.

Наиболее эффективным способом было бы создание пакета, который служил бы единой точкой входа для всех DML в вашей таблице и проверял бы Details в этом пакете.

2 голосов
/ 05 февраля 2010

В идеальном мире Oracle и другие СУБД будут поддерживать «утверждения»:

create assertion no_more_than_50_per_user as
check(not exists(select null
                 from a join b on ...
                 where a.detailed = 'Y'
                 and b.details is null
);

Хотя они этого не делают (и не без веской причины: было бы очень сложно реализовать их с точки зрения производительности!)

Как предлагает Quassnoi, вместо этого можно использовать триггеры - но вы должны знать об опасностях в многопользовательской среде. Чтобы быть уверенным в обеспечении согласованности, вам нужно снимать блокировки при проверке данных, чтобы этого не происходило:

(Предположим, что в записи 1 в настоящее время указано подробное = 'N', но все связанные записи B содержат детали, не равные нулю).

user1> Update A set detailed = 'Y' where a_id=1;

Это работает, потому что все связанные строки B содержат детали, не равные NULL.

user2> Update B set details = null where a_id=1;

Это работает, потому что user1 еще не зафиксировал, поэтому триггер user2 видит подробный = 'N'.

user1> commit;
user2> commit;

Теперь у вас есть поврежденные данные. Чтобы предотвратить это, триггер на B должен выбрать строку A «для обновления».

2 голосов
/ 05 февраля 2010

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

0 голосов
/ 05 февраля 2010

Если поле DETAILED должно быть продублировано на B, вы можете использовать внешний ключ для его принудительного применения, например, (B.KEYFIELD, B.DETAILED) ССЫЛКИ (A.KEYFIELD, A.DETAILED). Я не без ума от дублирования поля на B, но, с другой стороны, кажется, что у вас есть данные, которые связаны с B, которые существуют на A. Если бы вы могли удалить DETAILED из A и нажать на B, дизайн мог бы быть очиститель. Некоторые дополнительные детали могут помочь.

Делись и наслаждайся.

0 голосов
/ 05 февраля 2010

Я бы применил такое правило в пользовательском интерфейсе. Если ваши бизнес-правила станут более сложными, у вас в руках будет множество избыточных столбцов в вашей модели, чтобы обеспечить соблюдение всех правил в схеме базы данных.

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