數據定義 資料庫 表 擴展 函數 索引 許可權控制 運行分析 運行維護 配置 備份還原 其他 時間處理 psql ...
數據定義
資料庫
-- 創建資料庫
-- database_name,資料庫名稱
-- database_user,用戶名
CREATE DATABASE database_name WITH OWNER = database_user;
CREATE DATABASE database_name OWNER database_user;
-- 複製資料庫
-- database_name,資料庫名稱
-- database_user,用戶名
-- original_database_name,原始資料庫名稱
CREATE DATABASE database_name WITH TEMPLATE original_database_name OWNER database_user;
表
-- 新增列
-- table_name,表名
-- column_name,列名
ALTER TABLE table_name ADD COLUMN IF NOT EXISTS column_name VARCHAR(100) NULL;
擴展
-- 創建 UUID 擴展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- 驗證 UUID 擴展
SELECT uuid_generate_v4();
-- 創建 cube 擴展
CREATE EXTENSION IF NOT EXISTS cube;
-- 創建 earthdistance 擴展
CREATE EXTENSION IF NOT EXISTS earthdistance;
函數
-- 隱式將整形轉換成字元串,但是會有一些問題,參考 https://stackoverflow.com/questions/50025750/postgres-convert-integer-into-text。通常情況下還是建議使用 CAST 函數來實現。
-- 使用場景:在資料庫遷移的時候(比如 Microsoft SQL Server 轉成 PostgreSQL,Microsoft SQL Server 預設是支持的)需要隱式轉換,以達到快速實現的目的
CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));';
CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT;
COMMENT ON FUNCTION pg_catalog.text(integer) IS 'convert integer to text';
CREATE FUNCTION pg_catalog.text(bigint) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int8out($1));';
CREATE CAST (bigint AS text) WITH FUNCTION pg_catalog.text(bigint) AS IMPLICIT;
COMMENT ON FUNCTION pg_catalog.text(bigint) IS 'convert bigint to text';
索引
-- Query the indexes of a table
SELECT * FROM pg_indexes WHERE tablename IN ('table_name');
-- 查詢所有索引
SELECT
i.relname AS indname ,
i.relowner AS indowner ,
idx.indrelid::REGCLASS ,
am.amname AS indam ,
idx.indkey ,
ARRAY(
SELECT
pg_get_indexdef(idx.indexrelid,
k + 1,
TRUE)
FROM
GENERATE_SUBSCRIPTS(idx.indkey, 1) AS k
ORDER BY
k) AS indkey_names ,
idx.indexprs IS NOT NULL AS indexprs ,
idx.indpred IS NOT NULL AS indpred
FROM
pg_index AS idx
JOIN pg_class AS i ON
i.oid = idx.indexrelid
JOIN pg_am AS am ON
i.relam = am.oid
JOIN pg_namespace AS ns ON
ns.oid = i.relnamespace
AND ns.nspname = ANY (CURRENT_SCHEMAS(FALSE));
-- 查詢所有索引,排除系統表
SELECT
U.usename AS user_name,
ns.nspname AS schema_name,
idx.indrelid :: REGCLASS AS table_name,
i.relname AS index_name,
idx.indisunique AS is_unique,
idx.indisprimary AS is_primary,
am.amname AS index_type,
idx.indkey,
ARRAY(
SELECT
pg_get_indexdef(idx.indexrelid,
k + 1,
TRUE)
FROM
GENERATE_SUBSCRIPTS(idx.indkey, 1) AS k
ORDER BY
k ) AS index_keys,
(idx.indexprs IS NOT NULL)
OR (idx.indkey::INT[] @> ARRAY[0]) AS is_functional,
idx.indpred IS NOT NULL AS is_partial
FROM
pg_index AS idx
JOIN pg_class AS i ON
i.oid = idx.indexrelid
JOIN pg_am AS am ON
i.relam = am.oid
JOIN pg_namespace AS NS ON
i.relnamespace = NS.OID
JOIN pg_user AS U ON
i.relowner = U.usesysid
WHERE
NOT nspname LIKE 'pg%';
許可權控制
-- CREATE USER OR ROLE,PostgreSQL 中創建用戶和角色是等效的
-- role_name,用戶角色名稱
-- user_password,用戶密碼
-- user_name,用戶角色名稱
CREATE ROLE role_name WITH CREATEDB CREATEROLE LOGIN PASSWORD 'user_password';
CREATE user user_name PASSWORD 'user_password';
-- 分配所有許可權
-- database_name,資料庫名稱
-- database_user,資料庫用戶
GRANT ALL PRIVILEGES ON database_name TO database_user;
-- 修改表的 Owner
ALTER TABLE table_name OWNER TO database_user;
-- 分配 FUNCTION 的許可權給指定用戶
-- function_name,函數名稱
-- parameter1_type,第一個函數參數類型
-- parameter2_type,第二個函數參數類型
-- database_user,資料庫用戶
GRANT EXECUTE ON FUNCTION function_name(parameter1_type, parameter2_type, ...) TO database_user;
-- 修改 FUNCTION 的 Owner
-- function_name,函數名稱
-- parameter1_type,第一個函數參數類型
-- parameter2_type,第二個函數參數類型
-- database_user,資料庫用戶
ALTER FUNCTION function_name(parameter1_type, parameter2_type, ...) OWNER TO database_user;
運行分析
-- 查詢當前資料庫 TOP 20 大表
SELECT table_name
,pg_size_pretty(pg_relation_size(table_schema || '.' || table_name)) AS size
FROM information_schema.tables
ORDER BY pg_relation_size(table_schema || '.' || table_name) DESC LIMIT 20;
-- 查詢單個表大小
SELECT pg_size_pretty(pg_relation_size(table_name));
-- 查詢資料庫活動的查詢
SELECT current_timestamp - query_start AS runtime
,query_start
,datname
,pid
,query
FROM pg_stat_activity
WHERE query_start IS NOT NULL
ORDER BY 1 DESC limit 20;
運行維護
-- Cancel Processes by pid
SELECT pg_cancel_backend(pid int);
-- Terminate Processes by pid
SELECT pg_terminate_backend(pid int);
-- Kill all existing connections in the original database
-- source_db,資料庫名稱
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'source_db'
AND pid <> pg_backend_pid();
-- garbage-collect and optionally analyze a database
-- table_name,資料庫表名
VACUUM table_name;
VACUUM FULL table_name;
配置
-- 修改 max_locks_per_transaction
ALTER SYSTEM SET max_locks_per_transaction = 300;
-- 重載配置信息,使配置生效
-- pg_hba.conf
SELECT pg_reload_conf();
備份還原
pg_dump -h host_name -U database_user -F c -b -v -f file_path database_name
pg_restore -h host_name -U database_user --no-owner -d database_name file_path
其他
-- Prepare a statement for execution
PREPARE foo(TEXT, TEXT, TEXT) AS
SELECT *
FROM foobar
WHERE foo = $1
AND bar = $2
OR baz = $3
EXECUTE foo('foo', 'bar', 'baz');
DEALLOCATE foo;
時間處理
-- 查詢時間差
SELECT EXTRACT(epoch FROM (begin_time - end_time));
-- Query the last month in format 'YYYYMM'
SELECT to_char(date_trunc('month', current_date - interval '1' month), 'YYYYMM');
psql
# 打開資料庫連接
psql -h host_name -U database_user
# 列出所有的資料庫
\l
# 連接數據
\c database_name