Postgresql使用记录

创建扩展

root用户,使用"su postgres"切换到postgres

postgres=# create extension xx; 

例如创建一个新的fdw(foreign-data-wrapper):

postgres=#create extension postgres_fdw;

查看安装的扩展

postgres=# select * from pg_extension;

或者

postgres=# \dx

postgres_fdw实例

:> psql product
product=# create extension postgres_fdw;

1,创建外部服务器对象

product=# create server inventory_foreign_server foreign data wrapper postgres_fdw options(host '192.168.223.14', dbname 'b2b_inventory',port '5432');
2,创建用户映射
product=# create user mapping for tomtop server inventory_foreign_server options(user 'tomtop', password 'tomtop');

3,建立外部表

product=# create foreign table cloud_inventory(id bigint, sku varchar(255), stock integer, warehouse_id integer, warehouse_name varchar(255), residue_num integer) server inventory_foreign_server options(table_name 't_product_inventory_total');
product=# create foreign table cloud_inventory_lock(sku varchar(255), stock_locked integer, warehouse_id integer, warehouse_name varchar(255), is_effective smallint) server inventory_foreign_server options(table_name 't_product_inventory_order_lock');
product=# create foreign table micro_inventory(sku varchar(255), warehouse_id integer, warehouse_name varchar(255), stock integer, account varchar(255)) server inventory_foreign_server options(table_name 't_product_micro_inventory_total');
product=# create foreign table micro_inventory_lock(sku varchar(255), stock_locked integer, warehouse_id integer, warehouse_name varchar(255), is_effective smallint, account varchar(255)) server inventory_foreign_server options(table_name 't_product_micro_inventory_order_lock');

建立后的表和本地表看起来是一样的;
使用tomtop用户:select * from cloud_inventory;

递归查询实例

数据表中,商品类目(t_category_base)是按父子级存的,类目的名称在t_category_name,现在需要拿到每个类目的树,比如"母婴产品=>奶粉=>爱他美",在展示第三级类目"爱他美"的时候,对应的类目树应该是"(母婴用品)(奶粉)(爱他美)",如下图

Postgresql使用记录_第1张图片

建表语句

CREATE TABLE "public"."t_category_base" (
"iid" SERIAL NOT NULL,
"iparentid" int4,
"cpath" varchar(255) COLLATE "default",
"ilevel" int4,
"iposition" int4,
"ichildrencount" int4
);

CREATE TABLE "public"."t_category_name" (
"iid" SERIAL NOT NULL,
"icategoryid" int4,
"ilanguageid" int4,
"cname" varchar(300) COLLATE "default",
"ctitle" varchar(300) COLLATE "default",
"cdescription" varchar(2000) COLLATE "default",
"ckeywords" varchar(2000) COLLATE "default",
"cmetatitle" varchar(500) COLLATE "default",
"cmetakeyword" varchar(2000) COLLATE "default",
"cmetadescription" varchar(2000) COLLATE "default",
"ccontent" varchar(8000) COLLATE "default",
"cnickname" varchar(32) COLLATE "default"
);

需要用到的是递归的关键字WITH RECURSIVE,下面是真实代码:

WITH RECURSIVE T 
            (id, 
                parentid, 
                categoryIdTree, 
                categoryNameTree, 
                level
            )  
        AS (
                SELECT 
                    t_category_base.iid, 
                    iparentid, 
                    ARRAY[t_category_base.iid] AS categoryIdTree, 
                    '(' || cname || ')' AS categoryNameTree,
                    1 AS level 
                FROM t_category_base, t_category_name
                WHERE 
                    iparentid = -1
                AND t_category_base.iid = t_category_name.icategoryid
                AND t_category_name.ilanguageid = 1
        
                UNION ALL
        
                SELECT 
                    cb.iid, 
                    cb.iparentid, 
                    T.categoryIdTree ||cb.iid, 
                    T.categoryNameTree || '(' || cb.cname || ')',
                    T.level + 1 AS level 
                FROM (
                    SELECT  cb.iid, cb.iparentid, cn.cname
                    FROM t_category_base cb, t_category_name cn
                    WHERE cb.iid = cn.icategoryid
                    AND cn.ilanguageid = 1
                ) cb
                JOIN T ON cb.iparentid = T.id
        ) select * from T;

pgsql的递归查询效率很高。

更复杂的递归实例

有一个更麻烦的业务场景,要展示商品和类目树的关系;

麻烦的是,商品和类目映射表中存数据的时候,sku会存所有级别的映射,而且某个商品可能属于两个三级类目,那这个sku在这个映射表中就会存在3+3行数据,如下图

Postgresql使用记录_第2张图片

上面递归查询结果T是平铺了所有的类目的父子级关系,所以映射表需要先过滤自己,只取关联的最后一级类目的id,这时候需要关联T来做操作.
t_product_category_mapper的建标语句:

WITH RECURSIVE T 
    (id, 
        parentid, 
        categoryIdTree, 
        categoryNameTree, 
        level
    )  
AS (
        SELECT 
            t_category_base.iid, 
            iparentid, 
            ARRAY[t_category_base.iid] AS categoryIdTree, 
            '(' || cname || ')' AS categoryNameTree,
            1 AS level 
        FROM t_category_base, t_category_name
        WHERE 
            iparentid = -1
        AND t_category_base.iid = t_category_name.icategoryid
        AND t_category_name.ilanguageid = 1

        UNION ALL

        SELECT 
            cb.iid, 
            cb.iparentid, 
            T.categoryIdTree ||cb.iid, 
            T.categoryNameTree || '(' || cb.cname || ')',
            T.level + 1 AS level 
        FROM (
            SELECT  cb.iid, cb.iparentid, cn.cname
            FROM t_category_base cb, t_category_name cn
            WHERE cb.iid = cn.icategoryid
            AND cn.ilanguageid = 1
        ) cb
        JOIN T ON cb.iparentid = T.id
) SELECT 
    pcm.csku, 
    T.categoryIdTree categoryIdTree, 
    T.categoryNameTree categoryNameTree 
FROM T,
    t_product_category_mapper pcm
WHERE 
    T.ID  NOT IN (select iparentid from t_category_base)
AND pcm.icategory = T.ID
Postgresql使用记录_第3张图片

使用db_link

首选在对应的库要创建'db_link'扩展,create extension db_link,创建的方法在顶部第一部分

注意,根据 官方文档,db_link在使用之前,需要用SELECT dblink_connect语句建立连接,使用完要用SELECT dblink_disconnect关闭连接;

select dblink_connect('product_dblink','dbname=product host=127.0.0.1 port=5432 user=tomtop password=tomtop');

实例:

INSERT INTO t_product_base_mapper (
    iid,
    istatus,
    distributorid,
    preferdate,
    orderby,
    retailprice,
    iwebsiteid,
    ctitle,
    csku,
    masterimgurl,
    warehouseno,
    warehousename,
    totalsales
) select 
        nextval('t_product_base_mapper_iid_seq'),
        1,
        1,
        now(),
        1,
        T.price,
        1,
        T.title,
        T.sku, 
        T.masterimgurl, 
        T.warehouseno, 
        T.warehousename, 
        0 
        from (
            SELECT
                *
            FROM dblink('product_dblink',
                    'SELECT
                        DISTINCT pb.csku,
                        pb.fprice,
                        pt.ctitle,
                        gi.warehouse_id,
                        gi.warehouse_name,
                        pi.cimageurl
                    FROM
                        t_product_base pb
                    LEFT JOIN t_product_translate pt ON pb.csku = pt.csku
                    LEFT JOIN t_goods_inventory gi ON pb.csku = gi.sku
                    LEFT JOIN t_product_image pi ON pb.csku = pi.csku
                        AND pi.bbaseimage=true 
                        AND pi.bsmallimage=true 
                        AND iorder=(select MAX(iorder) from t_product_image where csku=pb.csku and bbaseimage=true)'
                ) AS t (
                                sku VARCHAR(20), 
                                price float8, 
                                title VARCHAR(200), 
                                warehouseno VARCHAR(20), 
                                warehousename VARCHAR(20), 
                                masterimgurl VARCHAR(200))
                    where t.sku not in (select csku from t_product_base_mapper where iwebsiteid=1)
        ) T where T.warehouseno is not null;

你可能感兴趣的:(Postgresql使用记录)