Задать вопрос
Ответы пользователя по тегу PostgreSQL
  • Функция копирования строки БД PostgreSQL, как правильно написать?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    insert into tablename (field1, field2, field3) 
    select field1, field2, 'new values instead field3'
    from tablename
    /*where*/
    Ответ написан
  • Стоит ли делать составные внешние ключи в БД?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    1. внешние ключи должны быть там и те, чтобы гарантировать ссылочную целостность. Должна быть ссылка сочетанием именно двух параметров - значит должна быть ссылка сочетанием пары параметров. Лучше или хуже сюда не применимо. Два разных fk и один составной имеют различное поведение.
    2. для какой именно СУБД? Postgresql следуя стандарту SQL обязывает ссылаться только на уникальное поле. Mysql отступает и в этом вопросе от стандарта и позволяет проверять неуникальное индексированное поле.
    3. см. coding standart конкретного проекта. Обычно никто не обижается против именования: имя таблицы _ имена полей _fk
    4. можно упереться в предел размера индексируемого поля. У postgresql это 1/3 размера странички памяти = 2730 байт по дефолту, у mysql - зависит от кучи факторов.
    Ответ написан
    Комментировать
  • Как реализовать работу баз данных с разными дисками?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Ответ написан
    Комментировать
  • Как преобразовать 1e-06 в 0,000001 в модели Yii?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Числа тождественно равны. Ну, насколько это возможно для by design приблизительного double.

    Если надо пользователю показывать в формате десятичной дроби - то внимание на слово "показывать". Значит это вопрос к вьюхе, а не модели. Штатный number_format, например, можно использовать.
    Ответ написан
    1 комментарий
  • Как увеличить скорость скрипта работающего с БД?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Возьмите профилировщик и посмотрите, на чём именно теряете время.

    О каком классе СУБД вообще речь?
    Например, если речь о транзакционной РСУБД, строки объёмные, то можно сделать так:
    create temporary table updatetable(guid uuid not null)
    пачками этак по 1000 guid вычитываете guid'ы из источника и записываете в эту временную табличку.
    select guid from updatetable where not exists (select 1 from normaltable where normaltable.guid = updatetable.guid)
    Так получили список guid, которых в целевой БД нет. Сходили в источник за полной версией всех данных этих guid, пачками записали в целевую БД.
    Ответ написан
  • Как подставить значения одной колонки в другие, отсортировав по содержимому этих колонок?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    У вас табличка ожидаемого результата не соответствует исходным данным.

    Ну, например, так:
    with origtable (name, math, physic, chemie) as (values ('Вася', 80, 52, 69), ('Коля', 50, 90, 95), ('Петя', 62,98, 42)) 
    , orders as (
    select name, 
    row_number() over (order by math desc) as mathid,
    row_number() over (order by physic desc) as phid,
    row_number() over (order by chemie desc) as chid
     from origtable
    )
    select m.name as "математика", p.name as "физика", c.name as "химия" from orders as m                              
    join orders as p on m.mathid=p.phid
    join orders as c on m.mathid=c.chid
    order by m.mathid;


    математика | физика | химия 
    ------------+--------+-------
     Вася       | Петя   | Коля
     Петя       | Коля   | Вася
     Коля       | Вася   | Петя
    Ответ написан
    1 комментарий
  • Какую функцию агрегации использовать в запросе с GROUP BY?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Ожидал получить в выборке не более одной строки с каждым ref_id

    GROUP BY ref_id, id

    С чего бы это вы ожидали увидеть только один ref_id, если явно сказали затем группировать по id?
    С учётом названия и того, что postgresql в принципе согласился запрос выполнить - id является первичным ключом. А группировка по первичному ключу ожидаемо результат не изменит.

    select  distinct on (ref_id)  ref_id,  id,  created_at from tablename  order by ref_id, created_at desc;
    Ответ написан
    3 комментария
  • PostgreSQL - как архивировать старые записи в большой таблице?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Как разделить таблицу, горячие данные оставить на SSD, холодные - на HDD. Для этого во-первых партицирование для разделения таблицы на две. https://habrahabr.ru/post/273933/ (как обычно, внимание на комменты и pg_partman)
    Затем, до миграции данных (или сразу при создании партиций), перенос архивных в другой tablespace www.postgresql.org/docs/current/static/sql-createt... stackoverflow.com/a/11228536 на HDD.
    Затем миграция данных на партиции.
    Вообще-то, это уже может быть вполне достаточно. 1-2млн строк * 365 дней это не запредельно много. Хотя не указан характер данных.

    Прозрачный для приложения перенос таблиц на другую железку - FDW, foreign data wrapper. Чем актуальнее postgresql - тем лучше. Пилится штука весьма активно по части оптимального распределения запроса. Дружит ли уже с партицированием - честно, не в курсе.

    Прозрачно отправить запрос на две базы и склеить - элементарно view с union all из локальной таблицы и FDW. Только это неинтересный вариант, зачем для запроса на горячие данные дёргать холодную часть базы?

    Вдобавок, можете посмотреть в сторону postgresql-xl, greenplum. Первый года полтора назад был не вполне production-ready, сейчас не знаю, второй используется даже в банковской сфере, но как мне помнится катастрофически не годится для OLTP, только OLAP нагрузка.
    Ответ написан
    1 комментарий
  • Как правильно убить postgresql idle процессы?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    pgbouncer держит всегда запущенными некоторый пул коннектов (дефолтно, во всяком случае, не в курсе, можно ли его попросить долговременно не держать коннекты вообще). Если вы их утилизируете не все - то будут idle.
    А так же это могут быть и старые коннекты, если инициатор соединение ещё не закрыл сам или оно ещё не было закрыто по таймауту. Например, приложение может иметь собственный пул коннектов.

    И, разумеется, pgbouncer обрабатывает только те коннекты, которые адресованы именно ему. СУБД он не трогает вовсе, pgbouncer - стороннее приложение, для postgresql - это просто ещё один клиент.
    Ответ написан
    Комментировать
  • Стоит ли делать на nosql highload с несколькими млрд строк, чтобы уйти от add column?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    А зачем останавливать репликацию и прочие странные вещи для добавления колонки в postgresql?
    Добавляете default null колонку. Транзакционно, мгновенно. Если колонка не должна быть null - то после добавления колонки меняете ей default, затем небольшими пачками обновляете имеющиеся строки, затем drop null.
    Ответ написан
    6 комментариев
  • SQLSTATE[22001]: String data, right truncated: 7?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Текущая транзакция будет отменена.
    Ответ написан
    Комментировать
  • Есть ли аналоги функции to_char в PostgreSQL?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    lpad?
    Не очень понятно, что именно функция делает.
    В любом случае, можно написать свою реализацию.
    Ответ написан
    Комментировать
  • Как корректно сделать запрос с оператором IN в PGSQL?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Покажите SQL, а не как вы его генерируете.
    Скорей всего IN ('123,321,456,654'), что, конечно, числом не является. Вопрос не имеет отношения к pg и имеет только к вашей библиотеки доступа, как подставить в in список значений.
    Ответ написан
    Комментировать
  • Как выбрать записи, которые созданы за какую то дату, если дата создания храниться в timestamp?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Выборка промежутка будет работать по индексу по этому полю, который зачастую уже есть и всё равно нужен для других запросов.

    Другие варианты возможны - явное приведение к дате ::date, штатные функции обработки датывремени date_trunc, date и любая stable хранимка. И эти способы тоже могут работать по индексу, но специально созданному функциональному индексу именно для этого выражения.
    Ответ написан
  • Как попасть в среду postgres на debian?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Рутовый доступ к базе предоставляется для пользователя postgres (системный, без пароля, авторизоваться можно через sudo):
    sudo -u postgres psql
    Ответ написан
    1 комментарий
  • Как верно проектировать базу данных?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Если нужна таблица - должна быть таблица.

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

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    with vertex_cost as (
    select fid_id, sum(vertex_cost) as vertex_cost /*min, max аналогично*/ from vertex group by fid_id
    ),
    edge_cost as (
    select fid_id, sum(edge_cost) as edge_cost /*min, max*/ from edge group by fid_id
    )
    select id, name, vertex_cost, edge_cost
        from fig
        left join vertex_cost vc on fig.id=vc.fig_id
        left join edge_cost ec on fig.id=ec.fig_id

    Если у фигур косты есть всегда - то заменить left join на join. Сейчас фигура будет возвращена всегда, но с NULL.

    Если надо предварительно пофильтровать сами фигуры:
    with figures as (
    select id, name from figures where name like 'foo%'
    ),
    vertex_cost as (
    select fid_id, sum(vertex_cost) as vertex_cost /*min, max*/ from vertex where fig_id in (select id from figures) group by fid_id
    ),
    edge_cost as (
    select fid_id, sum(edge_cost) as edge_cost /*min, max*/ from edge where fig_id in (select id from figures) group by fid_id
    )
    select id, name, vertex_cost, edge_cost
        from figures
        left join vertex_cost vc on figures.id=vc.fig_id
        left join edge_cost ec on figures.id=ec.fig_id
    Ответ написан
    Комментировать
  • Как в postgresql на Ubuntu посмотреть содержимое таблицы с "_" в названии?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    С чего вы взяли, что проблема в символе _ в названии? Хотите сказать, что другие такие же синтаксически некорректные запросы работают?

    Откройте любой материал по SQL и сравните с тем, что вы написали.
    Если разницу не видите где-то в промежутке между словом select и именем таблицы - сходите погулять или поспать или ещё чего поделать постороннего.
    Ответ написан
    1 комментарий
  • Почему медленная выборка в партицированных таблицах Postgresql?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Покажите explain analyze. Судя по cost в explain, само выполнение запроса корректно.

    Рабочая версия - время жрет сам планировщик. 7к партиций - это очень много. Об этом есть даже заметка в мануале (о чём там только нет заметок, но попробуй их заметь)
    All constraints on all partitions of the master table are examined during constraint exclusion, so large numbers of partitions are likely to increase query planning time considerably. Partitioning using these techniques will work well with up to perhaps a hundred partitions; don't try to use many thousands of partitions.

    https://www.postgresql.org/docs/9.4/static/ddl-par...

    У postgresql партицирование сделано довольно странно и, вообще-то говоря, не предназначенными для этого средствами. Если у вас достаточно большая таблица, чтобы почувствовать бонусы от партицирования, то лучше ограничьтесь парой десятков разделов. Вот ещё статья тематическая есть: https://habrahabr.ru/post/273933/
    Ответ написан