15_sovetov
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| 15_sovetov [2021/08/24 09:21] – chifek | 15_sovetov [2023/09/14 06:06] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 87: | Line 87: | ||
| pg_class — системная таблица, | pg_class — системная таблица, | ||
| + | ==== Перечень подключенных пользователей ==== | ||
| + | Чтобы узнать имя, IP и используемый порт подключенных пользователей, | ||
| + | |||
| + | < | ||
| + | SELECT datname, | ||
| + | </ | ||
| + | |||
| + | ==== Активность пользователя ==== | ||
| + | |||
| + | Чтобы узнать активность соединения конкретного пользователя, | ||
| + | |||
| + | < | ||
| + | SELECT datname FROM pg_stat_activity WHERE usename = ' | ||
| + | </ | ||
| + | |||
| + | ===== Работа с данными и полями таблиц ===== | ||
| + | |||
| + | |||
| + | ==== Удаление одинаковых строк ==== | ||
| + | |||
| + | |||
| + | Если так получилось, | ||
| + | |||
| + | дублирующиеся строки, | ||
| + | ситуации, | ||
| + | Рассмотрим таблицу с данными покупателей, | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Удалить все дубликаты поможет следующий запрос: | ||
| + | |||
| + | < | ||
| + | DELETE FROM customers WHERE ctid NOT IN | ||
| + | (SELECT max(ctid) FROM customers GROUP BY customers.*); | ||
| + | </ | ||
| + | |||
| + | |||
| + | Уникальное для каждой записи поле ctid по умолчанию скрыто, | ||
| + | |||
| + | Последний запрос требователен к ресурсам, | ||
| + | |||
| + | |||
| + | Теперь рассмотрим случай, | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Если допустимо удаление дубликатов без сохранения всех данных, | ||
| + | |||
| + | < | ||
| + | DELETE FROM customers WHERE ctid NOT IN | ||
| + | (SELECT max(ctid) FROM customers GROUP BY customer_id); | ||
| + | </ | ||
| + | |||
| + | Если данные важны, то сначала нужно найти записи с дубликатами: | ||
| + | |||
| + | < | ||
| + | SELECT * FROM customers WHERE ctid NOT IN | ||
| + | (SELECT max(ctid) FROM customers GROUP BY customer_id); | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | Перед удалением такие записи можно перенести во временную таблицу или заменить в них значение customer_id на другое. | ||
| + | |||
| + | Общая форма запроса на удаление описанных выше записей выглядит следующим образом: | ||
| + | |||
| + | < | ||
| + | DELETE FROM table_name WHERE ctid NOT IN (SELECT max(ctid) FROM table_name GROUP BY column1, [column 2,] ); | ||
| + | </ | ||
| + | |||
| + | ==== Безопасное изменение типа поля ==== | ||
| + | |||
| + | Может возникнуть вопрос о включении в этот список такой задачи. Ведь в PostgreSQL изменить тип поля очень просто с помощью команды ALTER. Давайте для примера снова рассмотрим таблицу с покупателями. | ||
| + | |||
| + | Для поля customer_id используется строковый тип данных varchar. Это ошибка, | ||
| + | |||
| + | < | ||
| + | ALTER TABLE customers ALTER COLUMN customer_id TYPE integer; | ||
| + | </ | ||
| + | |||
| + | Но в результате выполнения получим ошибку: | ||
| + | |||
| + | < | ||
| + | ERROR: column “customer_id” cannot be cast automatically to type integer | ||
| + | SQL state: 42804 | ||
| + | Hint: Specify a USING expression to perform the conversion. | ||
| + | </ | ||
| + | |||
| + | Это значит, | ||
| + | |||
| + | < | ||
| + | ALTER TABLE customers ALTER COLUMN customer_id TYPE integer USING (customer_id:: | ||
| + | </ | ||
| + | |||
| + | В результате всё прошло без ошибок: | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Обратите внимание, | ||
| + | |||
| + | Например, | ||
| + | |||
| + | < | ||
| + | ALTER TABLE customers ALTER COLUMN customer_id TYPE varchar USING (customer_id || ' | ||
| + | </ | ||
| + | |||
| + | В результате таблица примет следующий вид: | ||
| + | |||
| + | {{: | ||
| + | |||
| + | ==== Поиск «потерянных» значений ==== | ||
| + | |||
| + | Будьте внимательны при использовании последовательностей (sequence) в качестве первичного ключа (primary key): при назначении некоторые элементы последовательности случайно пропускаются, | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Рассмотрим два варианта поиска. | ||
| + | |||
| + | **Первый способ** | ||
| + | |||
| + | Выполним следующий запрос, | ||
| + | |||
| + | < | ||
| + | SELECT customer_id + 1 | ||
| + | FROM customers mo | ||
| + | WHERE NOT EXISTS | ||
| + | ( | ||
| + | SELECT NULL | ||
| + | FROM customers mi | ||
| + | WHERE mi.customer_id = mo.customer_id + 1 | ||
| + | ) | ||
| + | ORDER BY customer_id; | ||
| + | </ | ||
| + | |||
| + | В результате получим значения: | ||
| + | |||
| + | Если нужно найти не только первое вхождение, | ||
| + | |||
| + | < | ||
| + | WITH seq_max AS ( | ||
| + | SELECT max(customer_id) FROM customers | ||
| + | ), | ||
| + | seq_min AS ( | ||
| + | SELECT min(customer_id) FROM customers | ||
| + | ) | ||
| + | SELECT * FROM generate_series((SELECT min FROM seq_min), | ||
| + | EXCEPT | ||
| + | SELECT customer_id FROM customers; | ||
| + | </ | ||
| + | |||
| + | В результате видим следующий результат: | ||
| + | |||
| + | **Второй способ** | ||
| + | |||
| + | Получаем имя последовательности, | ||
| + | |||
| + | < | ||
| + | SELECT pg_get_serial_sequence(' | ||
| + | </ | ||
| + | |||
| + | И находим все пропущенные идентификаторы: | ||
| + | |||
| + | < | ||
| + | WITH sequence_info AS ( | ||
| + | SELECT start_value, | ||
| + | ) | ||
| + | SELECT generate_series ((sequence_info.start_value), | ||
| + | FROM sequence_info | ||
| + | EXCEPT | ||
| + | SELECT customer_id FROM customers; | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Подсчёт количества строк в таблице ==== | ||
| + | |||
| + | Количество строк вычисляется стандартной функцией count, но её можно использовать с дополнительными условиями. | ||
| + | |||
| + | Общее количество строк в таблице: | ||
| + | |||
| + | < | ||
| + | SELECT count(*) FROM table; | ||
| + | </ | ||
| + | |||
| + | Количество строк при условии, | ||
| + | |||
| + | < | ||
| + | SELECT count(col_name) FROM table; | ||
| + | </ | ||
| + | |||
| + | Количество уникальных строк по указанному полю: | ||
| + | |||
| + | < | ||
| + | SELECT count(distinct col_name) FROM table; | ||
| + | </ | ||
| + | |||
| + | ==== Использование транзакций ==== | ||
| + | |||
| + | Транзакция объединяет последовательность действий в одну операцию. Её особенность в том, что при ошибке в выполнении транзакции ни один из результатов действий не сохранится в базе данных. | ||
| + | |||
| + | Начнём транзакцию с помощью команды BEGIN. | ||
| + | |||
| + | Для того, чтобы откатить все операции, | ||
| + | |||
| + | А чтобы применить — команду COMMIT. | ||
| + | |||
| + | ==== Просмотр и завершение исполняемых запросов ==== | ||
| + | |||
| + | Для того, чтобы получить информацию о запросах, | ||
| + | |||
| + | < | ||
| + | SELECT pid, age(query_start, | ||
| + | FROM pg_stat_activity | ||
| + | WHERE query != '< | ||
| + | ORDER BY query_start desc; | ||
| + | </ | ||
| + | |||
| + | Для того, чтобы остановить конкретный запрос, | ||
| + | |||
| + | < | ||
| + | SELECT pg_cancel_backend(procpid); | ||
| + | </ | ||
| + | |||
| + | Для того, чтобы прекратить работу запроса, | ||
| + | |||
| + | < | ||
| + | SELECT pg_terminate_backend(procpid); | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Работа с конфигурацией ===== | ||
| + | |||
| + | ==== Поиск и изменение расположения экземпляра кластера ==== | ||
| + | |||
| + | Возможна ситуация, | ||
| + | |||
| + | < | ||
| + | SHOW data_directory; | ||
| + | </ | ||
| + | |||
| + | Изменим расположение на другое с помощью команды: | ||
| + | |||
| + | < | ||
| + | SET data_directory to new_directory_path; | ||
| + | </ | ||
| + | |||
| + | Но для того, чтобы изменения вступили в силу, требуется перезагрузка. | ||
| + | |||
| + | ==== Получение перечня доступных типов данных ==== | ||
| + | |||
| + | Получим перечень доступных типов данных с помощью команды: | ||
| + | |||
| + | < | ||
| + | SELECT typname, typlen from pg_type where typtype=' | ||
| + | </ | ||
| + | |||
| + | typname — имя типа данных. | ||
| + | typlen — размер типа данных. | ||
| + | |||
| + | |||
| + | ==== Изменение настроек СУБД без перезагрузки ==== | ||
| + | |||
| + | Настройки PostgreSQL находятся в специальных файлах вроде postgresql.conf и pg_hba.conf. После изменения этих файлов нужно, чтобы СУБД снова получила настройки. Для этого производится перезагрузка сервера баз данных. Понятно, | ||
| + | |||
| + | < | ||
| + | SELECT pg_reload_conf(); | ||
| + | </ | ||
| + | |||
| + | Но, к сожалению, | ||
| + | |||
| + | Мы рассмотрели команды, | ||
| + | |||
| + | ===== Ссылки ===== | ||
| + | |||
| + | Источник [[https:// | ||
15_sovetov.1629796907.txt.gz · Last modified: 2023/09/14 06:06 (external edit)