Обновить

Комментарии 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 может суммарно проиграть по производительности.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
runity.ru
Дата регистрации
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Рунити