Ответы пользователя по тегу PostgreSQL
  • В Postgresql схема: зачем нужна и как я её могу использовать в своих проектах?

    Melkij
    @Melkij
    PostgreSQL DBA
    В оракле схем разве нет?..

    schema - дополнительный уровень структуризации объектов. Как namespace в программировании. И, к слову, входит в стандарт SQL.

    Вы можете сделать таблицы:
    user_subscriptions
    user_orders
    user_favorites
    Вы можете сделать
    user.subscriptions
    user.orders
    user.favorites
    И в этом нет никакой разницы для СУБД. Но может быть удобно разработчику оперировать не с сотней таблиц одним списком, десятки из которых с одинаковыми префиксами (т.к. относятся к своим сущностям), а отдельные схемы по сущностях.

    Пилить же одну таблицу на несколько смысла при этом не так много, зато добавляется хлопот.
    Если вы хотите давать прямой доступ пользователю к базе - то зачем? Не надо так делать в разделяемой среде. Любую СУБД можно положить каким-нибудь интересным запросом. А в то что люди временами будут писать интересные и сильно творческие запросы - по опыту DBA вам гарантирую. Иногда такого наворотят... 0,5тб временный файлов одним запросом, например. Или сожрать 30гб RAM и увести базу в аварийный рестарт от OOM.
    Ответ написан
    1 комментарий
  • Как в запросе на PostgreSQL добавлять только уникальные значения?

    Melkij
    @Melkij
    PostgreSQL DBA
    on conflict do nothing
    https://www.postgresql.org/docs/current/sql-insert.html
    Ну и уникальный индекс по полю, конечно.

    Если вы на 9.4 в котором on conflict нет - обновляйтесь. 9.4 EOL через полгода.
    Ответ написан
    4 комментария
  • Как можно оптимизировать запрос с COUNT и SUM в PostgreSQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    PostgreSQL 11.0 (Debian 11.0-1.pgdg90+2)

    Спасибо за поддержку в первые пару недель после релиза, но в чём смысл этим заниматься в 2019 году? Чуть ли не единственный ответ что можете ожидать на багрепорт: проверьте сначала на актуальной версии.

    Для данной таблицы создал индексирование следующим образом:

    Зачем?

    Какие на ваш взгляд есть узкие места в этом запросе.

    count на MVCC базе. Для OLAP - ок, пусть себе шуршит.
    Для чего-то более быстрого - прикручивать предварительно агрегированные срезы.

    TREE_ORGANIZATION_ID (varchar)

    см. ltree
    Хотя судя по LIKE CONCAT('%', '\', '27623', '%') - скорее даже массив.
    Ответ написан
    Комментировать
  • Генерировать уникальное значение?

    Melkij
    @Melkij
    PostgreSQL DBA
    create sequence serial_number_seq minvalue 1 maxvalue 999999999;


    Сделать новое число - nextval('serial_number_seq')
    Гарантированно уникально. К строке, если очень хочется, можете привести сами
    Ответ написан
    6 комментариев
  • Запрос с функцией COUNT с помесячный разбивкой?

    Melkij
    @Melkij
    PostgreSQL DBA
    select admin_id
    count(*) filter(where created_at >= '2019-01-01' and created_at < '2019-02-01'),
    count(*) filter(where created_at >= '2019-02-01' and created_at < '2019-03-01'),
    ....
    from tablename where ... group by admin_id

    Или tablefunc

    А называется то что вы хотите получить - PIVOT.
    Ответ написан
    4 комментария
  • Как дать пользователю возможность перезапустить сервис postgresql?

    Melkij
    @Melkij
    PostgreSQL DBA
    Зачем вам рут для поиграться с базой? Postgresql прямо запрещает запуск себя от рута.
    initdb куда скажут себе в хомяке и стартовать оттуда базу через pg_ctl может любой пользователь с доступом к консоли. Порт только себе выбрать любой свободный выше привилегированного диапазона. И играйтесь в своё удовольствие, никаких особых прав для этого не надо.
    Ответ написан
    3 комментария
  • Как использовать в условии запроса псевдоним поля?

    Melkij
    @Melkij
    PostgreSQL DBA
    Никак. В секции where полей из select ещё не существует.

    Продублируйте условие, оберните ещё в один select, сделайте хранимую функцию и вызовите её в where и в select.
    Ответ написан
    1 комментарий
  • Как очистить таблицу?

    Melkij
    @Melkij
    PostgreSQL DBA
    Если truncate выполняется дольше секунды - значит truncate не выполняется вовсе, а ждёт блокировку.

    Посмотрите в pg_stat_activity where state != 'idle' на предмет долгих транзакций.
    Или сразу запросом по pg_locks, например, вот таким: https://github.com/dataegret/pg-utils/blob/master/...

    Нормальный мониторинг - вопрос отдельный, сложный и печальный.
    Ответ написан
  • Как создать таблицу из другой с использованием другого sequence для id столбца?

    Melkij
    @Melkij
    PostgreSQL DBA
    melkij=> create table identity_test (i int primary key generated by default as identity, val int);
    CREATE TABLE
    melkij=> insert into identity_test (val) values (1);
    INSERT 0 1
    melkij=> table identity_test;
     i | val 
    ---+-----
     1 |   1
    (1 строка)
    
    melkij=> create table identity_test_like (like identity_test INCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING DEFAULTS INCLUDING INDEXES);
    CREATE TABLE
    melkij=> \d identity_test_like
                        Таблица "public.identity_test_like"
     Столбец |   Тип   | Правило сортировки | Допустимость NULL | По умолчанию 
    ---------+---------+--------------------+-------------------+--------------
     i       | integer |                    | not null          | 
     val     | integer |                    |                   | 
    Индексы:
        "identity_test_like_pkey" PRIMARY KEY, btree (i)
    
    melkij=> \d identity_test
                                    Таблица "public.identity_test"
     Столбец |   Тип   | Правило сортировки | Допустимость NULL |           По умолчанию           
    ---------+---------+--------------------+-------------------+----------------------------------
     i       | integer |                    | not null          | generated by default as identity
     val     | integer |                    |                   | 
    Индексы:
        "identity_test_pkey" PRIMARY KEY, btree (i)


    include identity нет - identity не скопирован. Всё выглядит корректно.

    Если же вы не про identity, а про синтаксический сахар serial - то его nextval был скопирован потому вы сами это попросили через INCLUDING DEFAULTS.
    Типа данных serial нет. Это синтаксический сахар вокруг поля int, создания sequence и указания nextval в default.
    Ответ написан
    Комментировать
  • Почему пухнет WAL каталог?

    Melkij
    @Melkij
    PostgreSQL DBA
    Если реплика приостанавливает репликацию (видно по waiting в списке процессов для startup процесса) - значит ей мешают запущенные на ней транзакции. Проверьте свой max_standby_streaming_delay.

    В целом почему база может не удалять WAL сверх необходимых:
    - создан слот репликации но его не читают
    - archive_command выполняется с ошибкой
    Ответ написан
  • Ошибка при вызове метода getImportedKeys?

    Melkij
    @Melkij
    PostgreSQL DBA
    Проверяйте версии используемого ПО. Ваша библиотека предоставляющая вызов getImportedKeys очевидно не умеет используемую у вас версию PostgreSQL.
    Последний релиз postgresql где было поле tgconstrname системного каталога - далёкий 8.4
    Ответ написан
  • Как освободить место после удаления базы postgreSQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    pg_upgrade --link ?
    Бесполезный datadir от 9.5 удалили? pg_upgrade создал скрипт delete_old_cluster после обновления для этого.
    Ответ написан
    Комментировать
  • Какова правильная практика использования уникального идентификатора(Postgres SERIAL)?

    Melkij
    @Melkij
    PostgreSQL DBA
    Как Вы поняли в поле "а" вписывается ответ "no" или "yes" .

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

    В моем бизнесе вопросы собраны в Репорт (Репорты разные. В зависимости от Репорта имеют от 10 до 70 вопросов). Таким образом ответы заходящие в таблицу user нужно разделять по Репортам.

    Хотелось бы знать, как из первого вытекает второе.

    Если у вас есть некие "репорты", состоящие из некоторого числа вопросов, а на вопросы отвечают пользователи то совершенно очевидно у вас есть:
    таблица пользователей
    таблица репортов
    таблица вопросов с полем-ссылкой на репорт
    таблица ответов из 3 полей: id пользователя, id вопроса, значение ответа. Primary key на первые два поля.
    Ответ написан
    Комментировать
  • Что происходит с памятью после удалении записи с типом varchar в postgresql?

    Melkij
    @Melkij
    PostgreSQL DBA
    мне сно , при апдейте кортежа в varchar запись удаляется с диска и вписывается на новое место в памяти

    Ммм. Сомневаюсь что действительно что-то ясно.

    Для начала:
    на диске данные существуют ровно в том же виде, что и затем обрабатываются в памяти. Как побочного следствие именно этого, кстати, базы postgresql физически не переносимы на другие процессорные архитектуры, только dump/restore или ещё какую логическую репликацию. А ещё есть забавный фокус выравнивания структур данных в памяти. Из-за чего при разном порядке столбцов в таблице идентичный объём записанных данных может различаться по требуемому месту на дисках.

    postgresql - mvcc база. При удалении строки запись не удаляется. Вообще. Только проставляется xmax и страничка отмечается грязной. Операции обновления строки не существует вовсе. Update - это всегда delete + insert. Обновлённая запись при этом попадает в отличающееся место таблицы, так, что в таблице одновременно существую и старая и новая версии строки. И их может быть много.
    (enterprisedb грозятся доделать zheap в pg13, так что может будет веселее, но в версиях до 11 гарантированно как я описал, в 12 - только если вы смелый человек и будете собирать экспериментальные расширения)
    Итак, далее приходит autovacuum или vacuum, строки которые уже никому не могут быть видны вычищаются и считаются пустым пространством, в том числе по free space map.

    Пишущие операции пытаются найти место под запись:
    - в той же самой странице данных
    - в какой-то странице начиная от начала таблицы
    - в худшем случае создают новую страницу

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

    занимаемой процессом памяти на жестком диске

    Что это такое?
    Если интересен формат датафайлов - то вам дорога в исходники базы. Для ОС выделяются блоки на диске по 8кб и в них хранится какая-то бинарная штука.

    Касательно private памяти backend'а - в postgresql есть менеджер памяти, называемый memory context. backend память запрашивает у ОС блоками, что-то делает что ему надо используя эту память под всякую мелочь или не очень мелочь, затем memory context обнуляется или удаляется и память возвращается ОС. Большинство контекстов существуют не долго, на транзакцию или на запрос, например.
    Отладчик широко распространён - gdb. Без dbg сборки, впрочем, там явно будет ничего не понятно.
    Ответ написан
    Комментировать
  • Существует ли какая нибудь возможность узнать пароль пользователя в Postgres?

    Melkij
    @Melkij
    PostgreSQL DBA
    Пароли скорей всего сохранены как md5. Метод scram-sha-256 появился только в 10 и включая 12 релиз ещё не используется по-умолчанию (проблем с базой нет, сообщество даёт время на реализацию этого протокола в клиентских библиотеках, чтобы не как с mysql 8.0 получилось).

    Хэши паролей md5 можно найти в pg_authid таблице системного каталога, считаются как
    select rolpassword = ('md5' || md5('some password' || rolname)) from pg_authid where rolname = 'username';

    То есть восстановить исходный пароль невозможно. Можно попробовать подобрать коллизию для хэша.
    Ответ написан
    Комментировать
  • Можно ли гарантированно записать информацию в две базы данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    отключение света или kill процесса,

    Отдельно обращаю пристальное внимание на настройки редиса. Он не запишет данные с настройкой fsync по-умолчанию. Дефолтный fsync для AOF режима лога записи у него - раз в секунду. То есть все данные до секунды работы длительности вы можете потерять при крахе ОС.

    Redis не поддерживает протокол двухфазного коммита. И вы не можете сделать durable fsync в два места атомарно.
    Поэтому просто это никак не сделать.
    Что сделать можно - переделать логику, чтобы одна из баз могла при аварии привести данные в консистентный вид используя данные ведущей базы.
    Ответ написан
    Комментировать
  • Как создать индекс в postgresql для view?

    Melkij
    @Melkij
    PostgreSQL DBA
    Никак.
    view не хранит никаких данных, а раз нет данных - то не по чему строить индекс.
    Пример принципиальной проблемы индекса на view: если сделать view вида select foo, avg(bar) from tablename group by foo; - как пересчитывать данные при изменении строк в tablename?

    Индекс может быть создан на материализованном представлении (materialized view) - потому что такое представление данные хранит непосредственно. Но обновлять эти данные требуется вручную запросом REFRESH MATERIALIZED VIEW, который выполнит запрос, запишет его результат в новый heap, затем заменит старый heap новым (если не указан concurrently) либо обновит несовпадающие строки (для concurrently)
    Ответ написан
    4 комментария
  • Как лучше написать SELECT для переводов товара?

    Melkij
    @Melkij
    PostgreSQL DBA
    select ...
    from product as p
    join lateral (
    select title, description from product_translate as pt
    where pt.product_id = p.id order by language_id = ? limit 1
    ) on true
    where ....


    Как обычно мог напутать направление сортировки - допишите desc если перевод есть, но выбирается не он.

    Идея выбирать любой другой язык в случае отсутствия нужного - странная. Но запрос я написал именно такой.
    Если переводов нет вообще - сейчас такой товар не будет выводиться. Если нужен с NULL вместо текста - заменить джойн на left join.
    Ответ написан
    Комментировать
  • Как быстрее записать в базу PosgresQl?

    Melkij
    @Melkij
    PostgreSQL DBA
    Быстрее всего - COPY запросом.
    При том, сразу из csv файла, локального к СУБД.

    Через приложение - сильно лучше тоже COPY. В PDO интерфейс для COPY, впрочем, ужасен.
    Хуже - относительно большими insert
    ещё хуже - кучей запросов в транзакции
    кучей запросов вне общей общей транзакции - очевидно будет очень медленно.
    Ответ написан
    Комментировать
  • Как решить ошибку SQLSTATE[57014]: Query canceled: 7 ERROR: canceling statement due to statement timeout"?

    Melkij
    @Melkij
    PostgreSQL DBA
    Ищите где выставлен statement_timeout. Такая ошибка именно по срабатывании этой настройки. И включать её надо намеренно. Так что ищите где ставится, от конфига СУБД, настроек базы и пользователя до руками сделанного set в приложении.
    Ответ написан
    Комментировать