Ответы пользователя по тегу PostgreSQL
  • Как ускорить запрос к базе в формате Postgres sql?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Все сильно зависит от содержания (организации данных) ваших таблиц и от запросов, которые вы к ним делаете. Обычно строятся индексы по тем полям, которые участвуют в основных запросах. Тут самое главное не переборщить и не насоздавать индексов слишком много, иначе будет тормозить вставка.
    Индексы сразу создаются по первичным/вторичным ключам.
    Для анализа базы делайте explain ваших запросов - https://habrahabr.ru/post/203320/

    Ну и если запросов типа LIKE много, то имеет смысл проиндексировать ваши данные в поисковиках типа elasticsearch.
    Ответ написан
    1 комментарий
  • Как подключиться к postgresql используя odbc?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    ODBC - это в винде! А на линуксе есть свой клиент - psql, как раз консольный.
    Если подключаться планируете из винды, то нужно сначала установить в винду драйвер ODBC для постгруса, ну а затем, любой программой к этому драйверу через интерфейс ODBC подконнектиться, например excel.
    Ответ написан
    Комментировать
  • Как организовать отмечание "просмотренных" материалов?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Я бы для этих целей вообще sql не использовал. Это данные, которые, в основном: являются временными, ограниченными (100/1000/10000 записей и т.д), не влияют на основной функционал, могут быть счетчиками, их может быть очень много, их хорошо бы извлекать очень быстро, по ним не нужно делать большой обработки, у них есть "время жизни"...
    Поэтому предложу посмотреть в сторону redis.io который для этого и создан!
    Ответ написан
  • Какие аргументы в пользу использования транзакций в бд?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Ну как бы и без транзакций можно обходиться. Например использовать поле version, которое прибавляется каждый раз при при update.
    Если вся работа с данными сводится к их добавлению, то транзакции и не нужны.
    Но если присутствует цикл select/update, да еще и в несколько потоков, то рано или поздно данные повредятся.

    Простой случай, возьмем поле debit. Попробуем его увеличивать в несколько потоков без транцакций в цикле - select debit from mytable where ID=10, программно прибавляем единичку к полученному debit, затем делаем update mytable set debit=11 where ID=10. Результат приятно удивит.

    Также можно обойтись и без транзакций (точнее использовать так называемые "оптимистические блокировки"), если с полем debit считывать, например, поле version -
    select debit, version as oldversion from mytable where ID=10
    . Тогда update будет выглядеть примерно так
    update mytable set debit =11, version=version+1 where ID=10 and version=oldversion
    . Но при этом придется всегда проверять, изменили ли мы данные или нет.

    ЗЫ. По просьбам трудящихся, про оптимистические блокировки - https://ru.wikipedia.org/wiki/Блокировка_(СУБД)
    Ответ написан
    8 комментариев
  • Чем отличается реляционная БД от обьектно-реляционной?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Вообще-то postressql всегда была именно реляционной, а в последние 2-3 года туда прикрутили в блобы кучу дополнительных индексаторов. И настала возможность делать "объектный" поиск по этим блобам.
    Собственно профит в том, что отдельные поля могут индексироваться на манер текстовых поисковиков, например по json-полям с некоторой агрегацией.
    На мой взгляд, это просто разновидность текстового поиска в реляционной базе, хотя и сильно улучшенного.
    Выгода - хранить json + реляционную информацию, во многих случаях это бывает выгодным. В других - просто взять nosql (elastic/mongo) выгоднее. Ну многие наверное будут отказываться от отдельного solr/elastic.
    Ответ написан
    Комментировать
  • Background task, большая таблица, CURSOR и update, стоит ли открывать 2 сессии?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Вообще-то зря паритесь. Но, есть небольшие но. Не помню как в постгресе, но по аналогии с версионными базами данных (а постгрес как раз оно, по типу оракла), то записи в рамках транзакции копируются с новой версией, а по завершении транзакции просто остаются на месте. Вот откат транзакции, особенно большой, может быть очень болезненным.
    В общем, упереться можно только в два момента, нехватка памяти, и нехватка диска. Когда до этого дойдет, то можно выбирать записи кусочками по 1000 и более штук. Их обрабатывать и коммитить, Далее выбирать следующий кусочек. Так будет легче и для базы и для отслеживания.
    Ответ написан
    Комментировать
  • Кто знает замену MongoDB?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Ну могу посоветовать, как альтернативу, Elasticsearch. Но, боюсь, она вам еще больше не понравится, хотя на мой взгляд очень даже. По моему, у вас просто что-то не то с организацией данных, да и какие проблемы выбрать последние 10 по дате? Это же обыкновенный поиск по индексу, все должно очень быстро работать.

    PS.
    recloudor: И да, как альтернативу сортировке, предлагаю использовать для этого REDIS. При добавлении поста в монгу, добавлять id поста дополнительно и в list REDIS.
    rpush user_posts:id1234 321
    Из редиса доставать ОДНИМ запросом идентификаторы последних n-записей
    lrange user_posts:id1234 10 -1
    Ответ написан
    4 комментария
  • Лучшие технологии для поиска в базе данных через regex?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Я так думаю, что как раз ES здесь очень даже к месту. Тем более, что поиск будет осуществляться по термам слов, и можно будет искать не только "Судья на заседании: Иванова", но и "Судьи в председательстве Ивановой", "судью Иванову" и прочее.

    Попробуйте, ES имеет особенности, но не так уж и страшен.

    PS. Уж как минимум, ES позволит сократить список рассматриваемых документов до разумного минимума, по которому можно и программный regexp сделать.
    Т.е. сначала выбираем из ES все доки с судьями, заседаниями и Ивановой, а уже по результатам поиска делаем фильтрацию своим программным регекспом.
    Ах, да, совсем забыл - есть еще скрипты, которые могут как раз это и сделать на стороне самого ES! Ну и люсиновский поиск поддерживает "точный поиск" фраз, если чо..
    Ответ написан
    1 комментарий
  • Как создать шестидесятидвухричную последовательность в postgresql?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    А по хорошему никак не создать с использованием текстовых символов таблицы ASCII.
    Там всего 36 символов для букв и чисел, так что придется обломаться
    >>> int("1234567890",62)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: int() base must be >= 2 and <= 36
    >>> int("1234567890",36)
    107446288850820L
    >>>

    Или скажите, какой будет 36 и 37 записи?! Ну и 60-я и 61-я конечно.
    Ответ написан
  • Какую СУБД используют программисты JAVA EE?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Да, практически все используют, начиная от sqlite, h2, mysql, postgres и заканчивая oracle, sybase, mssql, teradata и прочими радостями жизни.
    Весь вопрос - подключить правильный драйвер, да для генерации указать диалект.
    Ну а базу выбирают под задачу, также под задачу и переезжают с одних баз данных на другие.
    У меня в свое время в проекте аж одновременно три базы использовалось hsql, mysql и sybase.
    Ответ написан
    Комментировать
  • Как сделать эффективный запрос по диапазону дат?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Так вроде бы проблем нет.
    Отельер в таблице указывает даты, когда номер может быть забронирован.
    типа
    outdate                  indate                room
    20-01-2015           22-01-2015            125

    Делаем просто в два этапа.
    1) выбираем все номера за свободный промежуток
    select * from freerooms where outdate between 20-01-2015 and 23-01-2015 and indate between 20-01-2015 and 23-01-2015

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

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Поддержу про торнадо, но еще более рекомендую посмотреть на cyclone.io
    Это торнадо переписанный под twisted, который как нельзя лучше вам подойдет (это я про https://twistedmatrix.com/ ). У меня так система работает, вся обработка делается в twisted, а отдаю через cyclone по ajax (вебсокетов на клиентах, увы у меня нет :-( )
    А технология называется comet. Реализуется в разных вариантах, у которых есть плюсы и минусы. Смысл в том, что браузер тем или иным образом (comet, websocket, ajax, ajaxp, longframe, longpooling и т.д.) подключается к серверу и ждет прихода события от сервера. Само событие может содержать кучу данных, которые обновились.

    Я бы рекомендовал сделать следующим образом. Поставить сервер очередей типа rabbitmq, а через торнадо/cyclone подключаться к очереди через ajax/ajaxp и/или websockets.

    Ну а если просто нужно слушать очереди сообщений (без хитрой обработки на web-сервере), то можно просто обойтись rabbitmq-stomp.

    В принципе, в циклоне есть несколько примеров:
    - https://github.com/fiorix/cyclone/tree/master/demo... - очереди на основе redis
    - https://github.com/fiorix/cyclone/tree/master/demo... - собственно websocket
    - https://github.com/fiorix/cyclone/tree/master/demo... = чистый ajax
    Ответ написан
    Комментировать
  • Django: SQLite или PostgreSQL?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    postgres конечно! sqlite только для разработки или как встроенная база для малоточного приложения или как замена файлам.
    До кучи
    https://www.digitalocean.com/community/tutorials/s...
    Ответ написан
    6 комментариев
  • Ключи и триггеры postgresql. Что для чего лучше использовать?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    По моему, триггеры - зло! Если уж и пользовать триггеры, то только для валидации данных. Иначе, при больших нагрузках, можете получить непредсказуемое поведение системы, дидлоки, деградацию производительности.
    В вашем же случае поля last_message_id и message_counter можно вычислять дополнительными запросами и в таблице им вообще нечего делать, просто сделайте индекс.
    Готов к дискуссии!
    Ответ написан
    6 комментариев
  • Что почитать про нормализацию БД?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    В принципе учебник для этого не нужен, нормализация - минимизация избыточности данных, имеет 5 форм. Первые три формы нацелены на связанность данных, две последних на улучшение структуры. Очень хорошо описано здесь - citforum.ru/database/dblearn/index.shtml (главы 6 и 7)
    Кратко здесь - support.microsoft.com/kb/283878/ru

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

    А вот и видео неплохое - www.youtube.com/watch?v=1GWx5CZdSCg
    Ответ написан
    Комментировать
  • Как/чем аггрегировать большие объемы данных (а в реалтайме?)?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    А что значит "реалтайм агрегация"? Мы же не можем в реальном времени агрегировать по непонятным условиям... Если хоть какие-то параметры имеются, то можно использовать хранилища key/value типа redis или mongo. А если нужны отчеты в виде графиков, то настоятельно рекомендую посмотреть в сторону graphite. Ну и как минимум можно агрегацию кластеризовать методом map/reduce.
    Ответ написан
    Комментировать
  • Как развернуть несколько отказоустойчивых серверов?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    По пунктам:
    Какие варианты разворачивания здесь будут?

    Применяются средства администрирования и конфигурирования, такие как puppet, chif, ansible. Т.е. один раз создаем сценарий на выбранном инструменте, а потом его "проигрываем" на нужный сервер.

    Плюс нужна синхронизация баз данных PostgreSQL

    Я бы с мастер-мастер не стал делать, настоятельно не стал бы! Лучше запусить несколько баз данных и шардировать данные на них. Про шардинг почитать например здесь - ruhighload.com/index.php/2009/05/06/%D1%88%D0%B0%D...
    А еще лучше некоторые (если не все данные) хранить в базах данных ключ/значение типа memcache/ redis, или в объектных типа hadoop/mongodb.

    Есть ли возможность синхронизировать все файлы между серверами?

    Лучше всего сделать распределенную файловую систему типа glusterfs, GPFS, cephfs, lustre. А самый простой - просто использовать rsync, но это медленно, большой лаг, и, неэффективно.
    Ответ написан
    9 комментариев
  • Какие технологии использовать для частого обновления большого количества строк в БД?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    У Вас выбрана плохая схема обновления рейтингов. При такой схеме, чем больше комментариев, тем с каждым разом будет труднее их обновлять, ведь придется каждый раз пробегать все записи.
    Зачем пересчитывать рейтинг каждый раз для ВСЕХ записей? Попробуйте сделать рейтинг счетчиками, а уж счетчики пересчитывать в проценты или что там у Вас на лету.
    К примеру, изначально:
    запись 1 - счетчик 1
    запись 2 - счетчик 1
    запись 3 - счетчик 1

    Далее, на запись 2 было сделано последовательно 10 комментариев (при каждом комментарии обновляем счетчик записи), стало
    запись 1 - счетчик 1
    запись 2 - счетчик 11
    запись 3 - счетчик 1
    комментарий 1, для записи 2, счетчик, 1
    ...
    комментарий 10, для записи 2, счетчик, 1

    Теперь для составления рейтинга нам достаточно найти только максимум по счетчику, приняв его за 100 процентов, в текущем случае будет 11. И ничего не нужно обновлять по крону, никакого перебора записей нам не нужно.
    Например на 5 записей:
    запись 1 - счетчик 33
    запись 2 - счетчик 78
    запись 3 - счетчик 3
    запись 4 - счетчик 22
    запись 5 - счетчик 15
    Максимум у нас MAX = 78, рейтинг считаем по формуле счетчик зиписи * ( 100 / MAX )
    Итого при выборе максимума и любой из записей будет
    запись 1 - счетчик 33 - рейтинг 42
    запись 2 - счетчик 78 - рейтинг 100
    запись 3 - счетчик 3 - рейтинг 4
    запись 4 - счетчик 22 - рейтинг 28
    запись 5 - счетчик 15 - рейтинг 19

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

    PS. Уф, вот запилил-то... Задавайте вопросы.
    Ответ написан
    3 комментария
  • Как сделать правильную организацию "напоминаний" на уровне БД?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    У меня это так реализовано. Все даты храним в формате таймстампа, это проще для хранения и вычислений. Исключения храним в произвольной форме ключ/значение, у меня реализованы только часы ключами from to. Задания бывают в нескольких состояниях: активная, неактивная, просроченная, будущая, бесконечная.
    Само задание выглядит примерно так (это как раз и есть запись в таблице):
    - старт - дата старта (таймстамп)
    - дельта - смещение реального старта от начала старта (это особенность моего приложения, нафиг не нужна, просто чтобы код не портить)
    - период - период повторения (таймстамп в виде timedelta)
    - продолжительность (должна быть меньше или равна периодутаймстамп в виде timedelta)
    - стоп - дата окончания (может отсутствовать, таймстамп в виде timedelta)
    - count - число повторений от даты старта (если есть, то обязана ставиться дата окончания, int )
    - исключения (например без понедельников или только чётные часы, или время с 10 до 19)
    - активна (да/нет)

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

    Базовый класс (на питоне):
    # функция преобразования питоновского класса datetime в timestamp
    # возвращает timestamp (int)
    def total_seconds(td):
        seconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.**6
        ret = 0 if seconds < 0 else seconds
        return ret
    
    class interval(object):
    # здесь должно быть все понятно
    # self  - указатель на сам класс, особенность питона, на другом языке этот параметр опускаем
    # вместо self на других языках используем this или аналог
        def __init__(self, start, delta, duration, period):
            self.start = start
            self.delta = delta
            self.duration = duration
            self.period = period
    
    # вычисление последнего интервала от нужной даты
    # возвращает две даты от и до
        def last(self, date):
            _start = self.start+self.delta 
            mul = int(total_seconds(date - _start)/total_seconds(self.period))
            at = _start+(self.period*mul)
            to = at+self.duration
            return (at,to)
    
    # является ли интервал активный на нужную дату
    # возвращает true/false
        def isLive(self, date):
            at, to = self.last(date)
            f1 = date >= at
            f2 = date < to
            return f1 and f2
    
    # вычисление следующего интервала от нужной даты
    # возвращает две даты от и до
        def next(self, date):
            at, to = self.last(date)
            return (at + self.period, to + self.period)


    Остальное, не привожу, так как много и надеюсь, допишите сами.
    Ответ написан