Pull to refresh

Comments 22

Как по мне, это просто синтаксический сахар. Мне ближе вариант с тремя таблицами в MySQL.

По сравнению с вариантом 3 таблиц не только. Тут есть контроль целостности, а так же богатый список операторов на пересечения, свободность и прочее. На КСВ может это не так очевидно. Система бронирования в отелях может быть более показательна, но я хотел делать слишком сложный пример.

Ну ок, согласен. С постгресом, не особо работал. Мускуль, наше всё.

Вы заблуждаетесь. Если БД не поддерживает диапазоны, то она так же ничего не знает о том, могут ли они пересекаться. Поэтому в плане запроса будут сканироваться все начала диапазонов меньшие и равные искомому значению или все концы диапазона большие или равные искомому значения, в зависимости от их очередности в индексе. А в случае GIST БД по индексу сразу находит нужную запись.

Ну в данном случае, я полагаюсь на формат работы как с MongoDB, когда многие действия, происходят на стороне самого приложения, а не в БД. Пока ещё не сталкивался с необходимостью, оперировать диапазонами.

Последний вариант с постгресом всё-равно требует нормализации.
А так да, постгрес хорош.

Нормализации с разнесением по 3 таблицам? С ходу в голову приходит только такой вариант.

Да, ровно такой же, как и с мускулем, только без доп. колонок from/to. Что уже неплохо =)

Если использовать не два int4range, а box type - получится нормализация )

А можно немного идею раскрыть? Какая схема БД при этом получается?

Вместо двух полей age и experience будет одно поле age_and_experience box

X координата возраст, а Y - стаж. И ищем прямоугольник, внутри которого требуемая координата, используя GIST индекс.

Оччень интересный вариант. Т.е. у нас будет 2ое поле в котором прямоугольники не могут пересекаться и даже соприкасаться. Т.е. у нас все сведется к 2 полям в таблице: age_and_experience box и value number. Обязательно попробую и этот вариант. Спасибо за идею!

В общем я сделал вариант и с box. К сожалению в настоящее время Хабр пока не дает отредактировать статью и добавить туда этот вариант. Но данная заметка есть в формате видео. Если интересно, оно публичное. Ссылка на схему D: https://www.youtube.com/watch?v=LOtEC68d1Aw&t=725s

Зря не упомянули в видео причину, почему я предложил вариант с box. Она в комментарии ниже:
"в целях обучения, промолчать о варианте с box я просто не смог. Все же
поддержка геометрических типов данных и их индексации - одна из сильных
сторон PostgreSQL"

Ну я в секции ответов про это рассказал. Там да, были вопросы про производительность.

Так-то да, но может выстрелить нечаяно =)

На практике, я бы тоже нормализовал в три таблицы, почему и поставил + Вашему комментарию. Но, в целях обучения, промолчать о варианте с box я просто не смог. Все же поддержка геометрических типов данных и их индексации - одна из сильных сторон PostgreSQL

Как видим, в этом случае получается 50 записей (их можно сократить до 20, предлагаю подумать и написать в комментариях как это сделать).

Думаю для возраста 16-21 и стажа 0,1,2 коэффициент одинаковый, и их можно объединить в 1 запись. И тогда получится 20 записей.

При варианте с 3 таблицами, похоже никто не мешает вставить повторяющиеся диапазоны и в таблицу возраста и в опыта. Контроля уникальности нет. Тогда этот вариант можно заменить 1 таблицей: id, age_from, age_to, experience_from, experience_to, coefficient.

Думаю для возраста 16-21 и стажа 0,1,2 коэффициент одинаковый, и их можно объединить в 1 запись. И тогда получится 20 записей.

Это решение очевидно, думаю, автор имел в виду именно его. Более того, если прибегнуть к экстремальному сжатию диапазонов, то количество записей можно уменьшить до 16.

Но вот правильность такого "сжатия" - крайне сомнительна. Если в следующем году большие дяди решат, что для какой-то ячейки исходной таблицы надо подвинуть коэффициент на сотку, то внесение корректировки потребует минимум двух действий вместо одного (в обоих вариантах реализации), с количеством корректируемых записей от 2 до 5 в зависимости от использованного сжатия.

К тому же при таком сжатии сложнее хранить историю, вернее, работать с прошлыми периодами...

Предложенный вариант с 1 таблицей тоже не помешает вставить повторяющиеся диапазоны, т.к. на уровне РСУБД это будут int + уникальный индекс. Но он позволит создать диапазон 22-22 при существовании диапазона 16-24.

В этом и суть отдельного типа данных range. Кроме цифр (границ диапазона) PostgreSQL еще и знает, что это диапазоны и может контролировать консистентность данных из коробки. Плюс он дает над ними еще и арифметику (которая будет полезна при составлении расписаний).

Хочу добавить, что время индексации GIST заметно превышает время индексации BTREE. Поэтому, для таблиц с большими объемами вставок или модификаций ключевых значений, GIST может суммарно проиграть по производительности.

Sign up to leave a comment.