Задать вопрос
Ответы пользователя по тегу PostgreSQL
  • 5 запросов для совершения одного действия это плохо?

    @rPman
    Если речь о 'высоконагруженном' сервисе, то лучше все же собрать запрос в один, тем более с помощью к примеру union можно это сделать не добавив накладных расходов

    Каждый запрос это куча телодвижений и ожиданий, которые сразу вылезают когда запросов сотни и тысячи в пределах одной ноды, зачем закладывать это с самого начала когда оптимизация ничего не стоит. Да я знаю про преждевременную оптимизацию но...
    Ответ написан
    Комментировать
  • Можно ли пропускать некоторые id?

    @rPman
    Будет запускать много телеграмм ботов. Хотел чтобы они работали на порте=id. Но не все порты свободны.

    Правильное решение - составные идентификаторы.

    Т.е. идентификатором должны являться одновременно пара портов - id записи и id порта (или устройства).

    Существует практика, когда в один числовой идентификатор запихивают два, самый простой способ - для каждой новой записи увеличивать значение идентификатора не на 1 а на N, где N - максимальное количество устройств (в вашем случае ботов), пусть и с запасом. Т.е. если номер порта P то идентификатор будет равен P+N*seq, пока количество устройств меньше N они не пересекутся и простым делением по модулю N можно из идентификатора извлечь P

    У вас postgres он поддерживает сиквенсы
    Ответ написан
    Комментировать
  • Насколько хорошо/оптимально использовать хранимую процедуру для полинга?

    @rPman
    Изначально неправильный подход к реализации, у которого будут глюки в проблемных местах. К тому же слишком сложный у вас получился вариант.

    Если база данных в своей основе не позволяет нужны вам функционал, как бы вы не извращались, делать его придется снаружи. И лучше чтобы это было 'userspace' а не ядро базы данных или ее расширение, так как стоимость поддержки результата растет экспоненциально.

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

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

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

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

    По окончанию работы счетчика вы должны снова запросить из базы данных список задач которые опоздали или должны быть исполнены сейчас, вычисляя разницу между расчетным количеством исполнений (now - creation_time)/exec_interval и счетчиком исполнений (тут же проверяем лимит количества запусков, и при его превышении задачу удаляем, не забыв доделать нужное количество запусков). Для каждой задачи получаем количество исполнений - запускаем эти задачи и по окончанию каждой итерации увеличиваем счетчик исполнений.

    p.s. разделение задач по разным таблицам в зависимости от длины интервала никак на производительность не повлияют, только усложнят алгоритм
    Ответ написан
  • Как организовать пагинацию, если БД и поисковая машина - это раздельные сервисы?

    @rPman
    Добавление тысяч идентификаторов в sql запрос вида where in (...) это плохая практика, что получается, если вы сначала заполняете in nmemory таблицу идентификаторами (из полнотекстового запроса внешней базы), а потом уже делаете фильтрацию по вашим атрибутам из sql базы, приджойнив это временную табличку?

    зы, пагинацию делать только через - получаете список id всех записей (отфильтрованные и отсортированные как надо), сохранив во временной таблице по сессии пользователя, а затем уже подгружаете данные окнами. Никаких limit для тяжелых запросов!

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

    И конечно кеширование (не нужно кешировать совсем уж конечный результат, но промежуточный, создающий наибольшие накладные расходы - имеет смысл), всего и вся, память стоит гораздо дешевле процессорного времени.
    Ответ написан
    Комментировать
  • По каким критериям выбирать локаль для базы данных postgresql?

    @rPman
    Мультиязычный - без вариантов выбирайте подмножество unicode лучше utf8 или тот же utf 16/32 (последний крут и даже имеет мизерное преимущество по скорости обработки вне базы данных но значительно больший оверхед по занимаемому месту на диске)

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

    А еще с utf8 клиентским приложениям работать проще всего, так как поддержка лучше. Если у вас windows (не web) у вас может быть соблазн использовать ее нативную кодировку UTF-16LE,.. не поддавайтесь на провокации ;)
    Ответ написан
  • Как задать уникальность поля совместно с полем из другой таблицы?

    @rPman
    Универсальный способ для любых БД и выкрутасов, что вы придумаете - создаете таблицу с полем и индексом в нужном вам формате, и заполняете ее триггером. Если фейлится индекс этой таблицы, сфейлится и запрос на изменение подчиненных таблиц, только что сообщение об ошибке будет 'не привычное'.
    Ответ написан
    2 комментария
  • Как хранить транзакции?

    @rPman
    обычно это 2 таблицы: кошельки и переводы (1-м), в некоторых случаях добавляют еще связь кошелька с пользователем (м-1), если у вас не просто валюта а платежка - добавьте понятие счет (предложение заплатить, кстати это самая сложная сущность, в зависимости от ваших хотелок может вырасти в мегаструктуру, типа всякие escrow или регулярные автоплатежи), все остальное кодируется в полях этих таблиц.

    Криптовалюты пошли по другому пути и взяли за правило - пусть все есть список транзакций, а транзакция это код - и вокруг этого наворачивают что хочешь (правда через задницу иногда получается зато универсально). Т.е. там вообще только одна таблица - транзакция, все остальное это кеши (например список непотраченных выходов восстанавливается ресканом списка транзакций)
    Ответ написан
    Комментировать
  • Возможно ли реализовать запуск bash по факту инсерта в БД?

    @rPman
    не надо ничего вызывать , и по крону не надо сканировать базу, достаточно на таблицу вызывать sql LISTEN и pg_get_notify из бакэнда.

    p.s. вариант с bash в тригере плох еще тем, что он отработает даже если транзакция будет отменена по какой-либо причине.
    Ответ написан
    Комментировать
  • Как в SQL (postgresql) можно установить последовательность сортировки?

    @rPman
    Если неохота создавать временную таблицу (а идеологически это верный вариант на такой случай), то вместо использования in пользуйтесь вложенным запросом с values, добавив туда поле для порядка:
    SELECT * FROM
     table t,
     (VALUES (1,'1995','TOYOTA'),(2,'5015','FIAT'),(3,'1010','BMW')) AS v(o,id,make_name)
    WHERE t.id=v.id AND t.make_name=v.make_name
    ORDER BY v.o
    Ответ написан
    Комментировать
  • Postgresql: пустой ответ на запрос при наличии записей: сбой или есть причина?

    @rPman
    Информации мало, но проверьте внимательнее, возможно между запросом и ответом от базы данных стоит еще какой то код, может в нем ошибка?

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

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

    Запустите утилиты проверки целостности базы данных и файловой системы. Банально проверьте работоспособность железа, вдруг у вас оперативная память глючит (правда у вас вылезало бы еще много где косяков) или сбоит контроллер жесткого диска (смотрите логи сервера dmesg хотя бы).
    Ответ написан
    6 комментариев
  • Есть ли возможность в postgres сделать индекс для count запросов?

    @rPman
    Один из общих способов решения, если изменений в базе значительно меньше чем запросов на чтение - собирать необходимые данные тригерами в отдельную табличку, и делать запросы уже в нее.

    p.s. индексы там и так используются, единственное, попробуйте вместо count(*) использовать count(индексируемое поле, используемое в where)
    Ответ написан
  • Насколько сильно LVM может тормозить работу PostgreSQL?

    @rPman
    у LVM сильные просадки скорости записи при использовании снапшотов, каждый новый уменьшает скорость почти в два раза.
    Ответ написан
    Комментировать
  • Как лучше производить синхронизацию с сервером при нестабильном интернете?

    @rPman
    Нестабильный интернет бывает разным, но в общем случае решается прослойкой между клиентами и базой данных (обычное дело, да и ради повышения безопасности, в мир базу данных не открывают), время сейчас такое что наилучшее решение - http/https. В этом случае база данных может быть абсолютно любой, хоть текстовый лог хоть oracle.

    При этом, если используется прослойка, вы можете организовывать репликацию и синхранизацию с несколькими вашими серверами самостоятельно, иногда это даже удобнее и проще чем городить штатную репликацию баз данных, особенно если интернет нестабильный. Т.е. при получении данных от устройств вы отправляете два/много запросов на ваши сервера (асинхронно само собой) и ждете отведенный таймаут (по которому отключаете сбойный сервер из списка и выдаете алерт) после чего отвечаете ок. При возврате в строй сервера, на него заливаются данные с рабочих (лог или поле со временем, если данные не удаляются).
    Ответ написан
    Комментировать
  • Big прайсы, обновлять или удалять и заново записывать?

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

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

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

    Скорее всего будут еще коэффициенты, если площадок много, каждая может вносить свои изменения в цену. И еще, если эти площадки так же выдают вычисленную цену, вам придется перепроверять все цены на вашей площадке, чтобы внезапно не получить отдельные товары по странной цене.
    Ответ написан
    Комментировать
  • В каком формате чисел работать с Bitcoin в PostgreSQL?

    @rPman
    Все зависит от того, где вы будете работать с базой, т.е. на каком языке и какими библиотеками будете пользоваться.
    Универсальный случай - не доверяйте нецелым числам, в какой то момент вы можете получить очень неприятные округления!
    Пользуйтесть целыми числами int64 (и самостоятельно делите на 10^8 при выводе и учитывайте если будете проводить умножения на такие же целочисленные значения , например при умножении на стоимость в другой валюте, которая будет храниться так же)

    Если будете пользоваться php, пользуйтесь строковым представлением числа и методами BCMath - bcadd, bcdiv, bcdiv,..) таким образом даже на 32-битных системах (вам могут попасться такие виртуалки) вы не получите преобразование числа в float
    Ответ написан
    Комментировать