Wolfnsex
@Wolfnsex
Если не хочешь быть первым - не вставай в очередь!

Как правильно хранить/выбирать данные в PostgreSQL?

Доброго времени суток уважаемые!

В продолжение моих предыдущих вопросов,
[PostgreSQL] Как привести строки в INT и другие типы данных?
Как привести массив чисел из поля VARCHAR к типу INTEGER в PostgreSQL?

Суть проблемы: есть некоторый набор данных (от 1 до 1000+) записей, строго привязанных к другой записи (простая связь, один ко многим). В виду того, что эти данные имеют смешанный тип (могут быть как строками, со всеми вытекающими) так и числами. Данные храняться в формате VARCHAR, в виду выше описанных причин.

При этом, работать с этими данными нам нужно в зависимости от ситуации и как со строками и как с числами. То есть, если условие поиска задано как "искать по строкам" - мы ищем по всему сразу и по строкам и по числам, буд-то это всё строки (формально оно так и есть). Если условие стоит по поиску диапазонов, например:
... WHERE n >= 10 AND n <= 100;

то нам нужно выбирать нужно только числа и соответственно сравнивать их.

Как я вижу решения проблемы:
Вариант 1 Мы храним строчные данные в таблице для строк, числовые данные в таблице для чисел (и судя по всему, для дробных придётся завести персональную таблицу), и в зависимости от условий поиска делаем выборку из двух таблиц. Тут есть мелкие проблемы:
а) Данные раздроблены
б) Система будет работать так, что определяя формат входных данных, будет записывать их в нужную таблицу, при этом есть некоторая вероятность, ошибочного определения, т.к. не факт что "333555" - это сумма чего либо, а не номер телефона или что-то иное, отличное от суммы.

Вариант 2.1 Мы храним все данные в одной таблице, в формате VARCHAR, и по косвенному признаку делаем отделяем числа, например так:
SELECT field1::integer FROM table1 WHERE field1 ~ E'^\\d+$' AND field1::integer > 3;


в этом варианте меня смущает регурялка... Она хоть и очень маленькая, но всё же регулярка.

Вариант 2.2 Мы добавляем ещё одно поле-флаг (число -> true/false), которое будет определять, что храниться в этой строке, число или строка. Соответственно, поиск по строкам работает в штатном режиме, а поиск по числам - работает уже не в формате регулярного выражения, а основываясь на флагах.

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

Подскажите пожалуйста, какой из вариантов лучше, насколько лучше и почему? Какие объективные плюсы и минусы у каждого подхода могут быть? Насколько медленно примитивные регулярки будут тормозить работу системы и/или насколько они лучше/хуже вариантов с дополнительным полем?

P.S. Я понимаю, что можно "взять и проверить", но будучи не имея представлений о том, как и почему БД будет себя вести в зависимости от ситуаций и не имея возможности моделировать такие ситуации на разном железе с разным набором (объёмом) данных - хотелось бы услышать мнение человека, который понимает как оно работает логически.
  • Вопрос задан
  • 805 просмотров
Пригласить эксперта
Ответы на вопрос 3
sim3x
@sim3x
Третья_нормальная_форма

И тк ты не знаешь какой набор полей у тебя в действительности есть
не знаешь какие запросы у тебя превалируют
не знаешь набор типов полей
...
непонятно, что означает "лучше", "быстро" и тд
Ответ написан
darthunix
@darthunix
Знаю PostgreSQL, Ubuntu, DICOM и медицину.
Мне кажется, что все проблемы от того, что вы храните совершенно разные сущности в одной колонке. До тех пор, пока вы их не разложите по разным местам, вы будете страдать. И даже регулярки/флаги/попытки сохранить числа отдельно от строк проблему не решат на 100% - вы сами привели пример, когда не ясно, сумма лежит в строке или телефон. У вас что-то не так в самой схеме хранения.... Предметную область знаете только вы, так что вам решать, что и где)
Если это динамические атрибуты, то возможно стоит посмотреть в сторону jsonb, залитого gin. Но нужно детальнее понять, какая аналитика будет над этими полями и почему важны именно числа.
Ответ написан
Комментировать
zoroda
@zoroda
Необычный Fullstack
Присоединюсь к Денис Смирнов. В вашем случае возможно лучшим решением будет JSONB. Из минусов - денормализация данных. Если нужен контроль ссылочной целостности внутри данных JSONB, то задача сильно усложнится. Её можно решить, например, развешиванием триггеров с функциями контроля.
Если же этим контролем можно пренебречь, то рекомендую присмотреться к JSONB.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы