postgres操作指南

安装使用

mac可以通过命令行用brew来安装或者直接下载安装包来安装,网上资料很多,这里就不介绍了。

如果通过brew来安装的,可以通过brew services start/stop postgres来开启或停止。

还有一种方法是通过docker来跑,这里以mac桌面版为例,创建启动脚本pg-docker-compose.yml:

# Use postgres/example user/password credentials
version: '3.1'

services:
  pgsql:
    image: postgres:12
    restart: always
    privileged: true
    ports:
      - '5432:5432'
    environment:
      POSTGRES_USER: 'postgres'
      POSTGRES_DB: 'postgres'
      POSTGRES_PASSWORD: 'postgres'
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - /Users/xxx/docker/postgres/data:/var/lib/postgresql/data/pgdata

通过 docker-compose -f pg-docker-compose.yml up -d启动docker。打开就能看到容器已经启动了,如下所示:
postgres操作指南_第1张图片

接下来可以通过pgAdmin来进行数据库访问和操作。具体安装过程这里不介绍。

安装完成之后,创建数据库连接,以上面的docker启动的数据库为例,连接参数如下:
postgres操作指南_第2张图片
postgres与mysql有点不一样,mysql的table是database的下级元素,而postgres的database下面还有schemas,其中public是默认的schema,schema下面才是table。
postgres操作指南_第3张图片

在需要操作的表格上右键,选择不同的script,可以进行数据操作。其中,PSQL Tool是客户端命令行(如果安装了postgres服务端而没有安装pgAdmin,可以直接通过psql来开启命令行)。
postgres操作指南_第4张图片

上面的SQL栏可以查看table的建表语句。
postgres操作指南_第5张图片

postgres常用命令:

操作 含义
\l 列出所有databases
\c 当前用户和连接的表
\c databaseName 切换数据库
\c - username 切换用户
\dn 查看数据库中所有schemas
\du 查看数据库中所有role及其权限
\dt 查看数据库中所有表
\d tableName 查看某个表的描述
\d+ tableName 查看某个表的基本信息
\di 查看索引
\df 查看存储过程
\encoding 查看编码

角色权限

点开Login/FGroup ROles可以查看role和其属性,包括每个role的权限,如下所示:

postgres操作指南_第6张图片
可以看出,postgres是一个super用户,拥有所有权限。
查看当前登录用户并创建一个新用户:
在这里插入图片描述
可以看到新用户test只有login权限。

注意关键字role和user的区别,如create user会自动赋予用户登录权限,而create role不会。

切换到test用户(注意必须与登录用户的密码相同才能切换,否则要修改db连接密码重新登录),然后创建新用户:
在这里插入图片描述此时会发现无法创建新的role,因为当前登录用户test不具有创建role的权限。

重新切换回super用户,修改test用户的权限:
在这里插入图片描述
然后切换到test用户就可以创建新角色了:postgres操作指南_第7张图片
切换到新用户test1,尝试删除本身:
在这里插入图片描述
因为test1只有login权限,所以不能删除role。可以切换到具有createrole权限的test用户来删除:
在这里插入图片描述
如果当前用户拥有删除role权限但报错:

cannot be dropped because some objects depend on it

说明这个不能删除的role拥有其他对象。但是drop role并没有cascade删除指令,只能先删除其拥有的其他对象,再删除role:

drop owned by xx cascade;
drop user xxx

注意:执行此操作需保证要删除的role所拥有的其他objects确实是可以删除的。

test用户虽然具有创建role和db的权限,但是不能创建public模式。将postgres的权限赋予test,然后查看用户权限信息:
postgres操作指南_第8张图片

此时可以看到:test是postgres的一个成员,因此具有创建public模式的权限:
在这里插入图片描述
如果执行某项操作报错:

ERROR: must be member of role "xx"

则同样地,将xx权限赋予给当前用户:

grant xx to current_user

这样当前用户就成为xx的成员,可以将当前用户所拥有的一些table或者schema转让给xx。

数据迁移和校验

查询所有表的记录数

select schemaname, relname, n_live_tup from pg_stat_user_tables order by n_live_tup desc;

可以使用以下命令进行数据dump:

pg_dump -Fc -v -b -h localhost -p 5432 -U postgres -E UTF8 -d postgres > test.dump

生成原始数据的校验文件:

psql -hlocalhost -Upostgres -p5432 -d postgres -f test.sql > validation_test.txt

校验脚本如下:

create function validation() returns text
    language plpgsql as $$
DECLARE
    rec   record;
    countTable bigint;
    sumRowHashTable bigint;
    sch   record;
    seqName record;
    seq record;
   
    results text;
BEGIN
    results = '';
      
    -- table hash
    FOR sch IN
        SELECT *
        FROM information_schema.schemata
        WHERE schema_name <> 'pg_catalog' and schema_name <> 'information_schema'
        ORDER BY schema_name
    LOOP
        FOR rec IN
            SELECT *
            FROM pg_tables
            WHERE schemaname = sch.schema_name
            ORDER BY tablename
        LOOP
            EXECUTE 'SELECT count(*) FROM '
                        || quote_ident(rec.schemaname) || '.'
                || quote_ident(rec.tablename)
                INTO countTable;
              
            -- adjust for precision of datatype for diffrent postgres version, this is for example
            IF rec.tablename = 'order' THEN
                EXECUTE 'SELECT sum(CAST(CAST((''x'' || md5(CAST((f.id, round(f.amount::numeric, 6), f.createTime) AS text))) AS bit(32)) AS int)) FROM '
                            || quote_ident(rec.schemaname) || '.'
                    || quote_ident(rec.tablename) || ' f'
                    INTO sumRowHashTable;
            ELSE
                EXECUTE 'SELECT sum(CAST(CAST((''x'' || md5(CAST((f.*)AS text))) AS bit(32)) AS int)) FROM '
                            || quote_ident(rec.schemaname) || '.'
                    || quote_ident(rec.tablename) || ' f'
                    INTO sumRowHashTable;
            END IF;
              
   
            IF results = '' THEN
                results = rec.schemaname || '.' || rec.tablename || ',' || countTable || ',' || sumRowHashTable;
            ELSE
                results = concat(results, CHR(10), rec.schemaname || '.' || rec.tablename || ',' || countTable || ',' || sumRowHashTable);
            END IF;
        END LOOP;
    END LOOP ;
      
    -- sequence
    results = concat(results, CHR(10), CHR(10), CHR(10), CHR(10), CHR(10), '-------------------------------------');
    FOR seqName IN
        SELECT c.relname
        FROM pg_class c
        WHERE c.relkind = 'S'
        ORDER BY c.relname
    LOOP
        -- change 'public' to your own database schema
        EXECUTE  'SELECT * FROM ' || 'public' || '.' || quote_ident(seqName.relname)
        INTO seq;
        results = concat(results, CHR(10), seqName.relname || ',' || seq.last_value || ',' || seq.log_cnt || ',' || seq.is_called);
    END LOOP ;
      
    RETURN results;
END;
$$;
   
select validation();
   
DROP FUNCTION validation();

接下来通过以下命令进行数据恢复:

pg_restore -Fc -v -h localhost -p 5432 -U postgres -d postgres test.dump 

恢复之后,同样用相同的脚本生成校验文件,比较校验文件是否相同。

你可能感兴趣的:(工具,数据库与sql,postgres)