Пишу простой документооборот. Получаю море удовольствия.
Имеем такую сущность как “контрагент”. Эти создания бывают как физиками, так и юриками. Чудесно.
Отличаются они достаточно сильно, чтобы было смысл класть их в разные таблицы.
Создаю таблицу contragents, наследую от неё firms и peoples.
Теперь вопрос — что у нас будет с полем contragent_id? Будет ли оно уникальным? Самое интересное что почти будет.
Если оно было SERIAL PRIMARY KEY (что выглядит наиболее разумно), то при наследовании ни у firms, ни у people уникальных индексов не будет. И даже если их создать, то они будут уникальными только для этих такблиц. Таким образом поле contragent_id не является уникальным. Чудненько :(
Самое интересное другое — если провести простой эксперимент с добавлением нескольких записей без указания id в обе таблицы, то они окажутся таки уникальными. Почему?
Всё просто — после наследования они пользуются одной SEQUENCE, до переполнения которой видимость уникальности будет создаваться. А после 2^31 контрагентов в базе данных она посыпется.
Но это ещё не самое интересное — самое заключается в том, что FOREIGN KEY для таких таблиц работать не будет. Вернее будет, но, опять же, либо с указанием на firms, либо на people. Пройтись по индексам двух унаследованных таблиц ему слабо.
Выкручиваюсь тем, что добавил boolean поле is_firm, и теперь везде, где мне нужно ссылаться на контрагентов я имею кучу никому не нужной логики. Неаккуратненько, однако :(
Можно, конечно, поступить по-другому — вынести в эти таблицы реальную разницу между контрагентами, и хранить уже в таблице с контрагентами ссылки на соответствующую фирму/человека (детальная информация). Но тоже неаккуратненько как-то.
Однако многие чудесные возможности постгреса сейчас работают только если ссылочную целостность производить на уровне сервера приложений. “MySQL возвращается?”.