Очевидно, что принудительное выполнение ограничений, таких как указанное вами, потребует от клиентов иногда выдавать (и механизмы СУБД принимать) что-то, что может быть помечено как «одновременное обновление», то есть более чем одна отдельная таблица является обновляется перед проверкой любых ограничений.
Язык SQL (я имею в виду, стандарт) предлагает поддержку для этого через CREATE ASSERTION. Увы, ни один из существующих в настоящее время движков не поддерживает это утверждение.
Единственный способ, которым это может быть достигнуто с помощью существующих в настоящее время механизмов SQL, - это отложить проверку ограничений до тех пор, пока не будут выполнены все обновления (если, конечно, ваш механизм поддерживает это). Внедрение таких ограничений в код приложения или бизнес-логику, в конечном счете, сводится к тому, что вообще нет ограничения, если ваша база данных является «общей» и может также обновляться другими программами.
Существуют системы, которые предлагают поддержку для применения ваших ограничений, но они не являются системами SQL.
Решение aioobe довольно оригинально, но имейте в виду, что вы можете сделать это только путем дублирования всех столбцов со стороны «много» (/ потомков) до стороны «один» (/ родитель) (потому что в противном случае у вас все еще есть та же проблема между двумя таблицами, за исключением того, что часть "или-больше" исчезла, но проблема не в этом). И если вы сделаете это, вы столкнетесь с большими трудностями, когда:
- написание запросов со стороны «многие» (вы должны следить за тем, чтобы та другая строка, которая находится со стороны «одна», всегда получала UNIONed со стороной «много»),
- принудительное использование ключей на стороне "много" (вам нужно убедиться, что ни один ключ на стороне "много" не будет иметь того же значения, что и тот другой ряд, который находится на стороне "один",
- обеспечение ссылочной целостности, когда указанная таблица сама является вашей «одной или более» стороной (вы должны убедиться, что она также действительна для существования ссылок на эту другую строку, которая находится на стороне «один») .
Таким образом, решение aioobe, хотя и оригинальное, скорее всего, создаст больше новых проблем, чем решит.