PostgreSQL — «приятные» особенности

Пишу простой документооборот. Получаю море удовольствия.

Имеем такую сущность как “контрагент”. Эти создания бывают как физиками, так и юриками. Чудесно.
Отличаются они достаточно сильно, чтобы было смысл класть их в разные таблицы.

Создаю таблицу contragents, наследую от неё firms и peoples.

Теперь вопрос — что у нас будет с полем contragent_id? Будет ли оно уникальным? Самое интересное что почти будет.

Если оно было SERIAL PRIMARY KEY (что выглядит наиболее разумно), то при наследовании ни у firms, ни у people уникальных индексов не будет. И даже если их создать, то они будут уникальными только для этих такблиц. Таким образом поле contragent_id не является уникальным. Чудненько :(

Самое интересное другое — если провести простой эксперимент с добавлением нескольких записей без указания id в обе таблицы, то они окажутся таки уникальными. Почему?

Всё просто — после наследования они пользуются одной SEQUENCE, до переполнения которой видимость уникальности будет создаваться. А после 2^31 контрагентов в базе данных она посыпется.

Но это ещё не самое интересное — самое заключается в том, что FOREIGN KEY для таких таблиц работать не будет. Вернее будет, но, опять же, либо с указанием на firms, либо на people. Пройтись по индексам двух унаследованных таблиц ему слабо.

Выкручиваюсь тем, что добавил boolean поле is_firm, и теперь везде, где мне нужно ссылаться на контрагентов я имею кучу никому не нужной логики. Неаккуратненько, однако :(

Можно, конечно, поступить по-другому — вынести в эти таблицы реальную разницу между контрагентами, и хранить уже в таблице с контрагентами ссылки на соответствующую фирму/человека (детальная информация). Но тоже неаккуратненько как-то.

Однако многие чудесные возможности постгреса сейчас работают только если ссылочную целостность производить на уровне сервера приложений. “MySQL возвращается?”.

Запись опубликована в рубрике Новости с метками . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Оставьте эти два поля как есть:

Защищено Invisible Defender. Показывать 403 для 308 129 плохих парней.