1 基本操作
连接数据库 psql -h localhost -U appuser -d appdb
查看所有数据库 \l
查看所有数据表 \d
查看当前用户与数据库 \c
切换数据库 \c ${databasename}
查询结果的扩展显示命令 \x。示例:
-- 开启扩展显示
\x
-- 执行查询语句
select XXX;
-- 关闭扩展显示
\x
2 反斜杠命令背后的详细信息
Postgres的反斜杠命令,是Postgres的内部命令(非SQL命令),背后是对系统库表查询的封装。在启动psql时,加上-E选项,可以看到反斜杠命令背后查询的哪些系统库表。
如命令\l的底层实现原理,可在psql启动加-E后,输入\l,即可见:
postgres=# \l
********* 查询 **********
SELECT d.datname as "Name",
pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
d.datcollate as "Collate",
d.datctype as "Ctype",
d.daticulocale as "ICU Locale",
CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS "Locale Provider",
pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;
**************************
数据库列表
名称 | 拥有者 | 字元编码 | 校对规则 | Ctype | ICU Locale | Locale Provider | 存取权限
-----------+----------+----------+--------------------------------+--------------------------------+------------+-----------------+-----------------------
appbase | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | | libc |
postgres | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | | libc |
template0 | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(4 行记录)
可见,查看数据库清单的命令\l,背后查询的是pg_catalog.pg_database表,结合pg自带的一些存储过程(functions),拼接成最终的输出表。
同理,查看数据表清单的命令\d,背后查询的是pg_catalog.pg_class表,结合其他信息拼接而成。值得注意的时,此处不同数据库下的pg_catalog.pg_class表,内容有所不同(因为持有不同的数据表)。
在Windows下,psql是一个客户端,不便于增加-E指令。可以通过powershell启动psql(目录:PostgreSQL安装路径\Bin\psql.exe),执行命令 ./psql.exe -U postgres -E 以启动反斜杠命令的详细信息。
3 PostgreSQL数据库的库表关系
PostgreSQL的数据库表是 database-schema-table。比如appdb-public-a_table,或者appdb-pg_catalog-a_table,或者postgres-pg_catalog-pg_database。与MySQL不同,中间多一层schema。
schema用于聚合一个用户的数据库对象如tables, views, sequences, stored procedures, indexes, clusters等等。一个用户一般对应一个schema,该用户的schema名等于用户名,并作为该用户缺省schema。
特定条件下,可以在SQL语句中不声明schema,直接操作数据表。如在postgres库下,以postgres用户执行以下两条SQL语句效果相同。
select * from pg_catalog.pg_database;
select * from pg_database;
4 PostgreSQL中的CONSTRAINT和INDEX
就目前笔者的推断,Constraint和Index字面含义理解为”限制/约束“和”索引“,前者是一个逻辑概念,表示对表内的规则约束;后者是一个实现,本意是用于优化查询效率。但是在部分场景下(如唯一索引),其特征刚好实现了唯一约束的效果。
由此引申出约束和索引的不同,比如PostgreSQL支持局部索引以及局部唯一索引,而局部唯一索引刚好可以实现一种”局部唯一约束“的效果,但PostgreSQL并不支持逻辑上的”局部唯一约束“。可参考:唯一键vs软删除/逻辑删除
5 初始化数据
-- 建用户
create user appuser password '*******';
-- 查看用户
\du
-- 建库(在postgres用户下)
create database appdb owner appuser;
-- 授权
GRANT ALL PRIVILEGES ON DATABASE appdb TO appuser;
-- 切换库
\c appdb;
-- 切换用户
\c - appuser
-- 创建schema,以下2语句效果相同
-- create schema appuser authorization appuser;
create schema authorization appuser;
-- 建表
create table a_table (id serial primary key, user_name character varying(64));
-- 可通过\d查看到a_table的表信息与a_table_id_seq的序列信息
-- 也可在appdb库下,pg_catalog.pg_class中,找到relname='a_table'的行。
-- 建立唯一约束/唯一索引
alter table a_table add constraint ukey_part_user_name_create_time unique(user_name, deleted);
create unique index ukey_user_name_deleted on a_table(user_name, deleted);
-- 建立条件唯一索引
create unique index ukey_user_name_deleted on a_table(user_name, deleted) where deleted = 0;
-- 删除唯一约束/唯一索引
alter table table_name drop constraint "some_name";
drop index "ukey_user_name_deleted";