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,現在需要拿到每個類目的樹,比如"母嬰產品=>奶粉=>愛他美",在展示第三級類目"愛他美"的時候,對應的類目樹應該是"(母嬰用品)(奶粉)(愛他美)",如下圖

建表語句

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行數據,如下圖

上面遞歸查詢結果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

使用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;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優秀的...
    笨鳥慢飛閱讀 5,633評論 0 4
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,166評論 6 13
  • 1. 《上班的地鐵上》 一個孕婦,快生了 她笨重,卻很漂亮 像大地孕育出的這個美好清晨 她會生一個像她那樣美麗聰慧...
    陳玲00閱讀 232評論 0 4
  • 孩子有沒有音樂細胞?其實我們可以換個角度來回答,一個正常的孩子基本上都是有著接近的天賦和潛力的,能不能把音樂弄好,...
    屁桃爸閱讀 198評論 0 0