PostgreSQL對接SequoiaDB

PostgreSQL是一款開源的SQL數據庫,支持標準SQL,用戶能夠經過JDBC驅動鏈接PostgreSQL進行應用程序開發。用戶經過擴展PostgreSQL功能,讓開發者可使用SQL語句訪問SequoiaDB數據庫,完成SequoiaDB數據庫的增、刪、查、改操做。本文就針對如何擴展PostgreSQL功能,實現PostgreSQL對接SequoiaDB進行介紹。java

1. 部署PostgreSQL

1.1 安裝PostgreSQL

本教程爲PostgreSQL與SequoiaDB的對接教程,因此做者建議使用者在sdbadmin用戶下(SequoiaDB數據庫默認用戶)安裝並使用PostgreSQL(本教程使用的PostgreSQL版本爲9.3.4)。linux

  1. 源碼編譯PostgreSQLsql

    下載連接:http://www.postgresql.org/ftp/source/
    解壓後編譯安裝(須要root權限)shell

    $> tar -zxvf postgresql-9.3.4.tar.gz
    $> cd postgresql-9.3.4/
    $> ./configure && make && make install
  2. 切換用戶數據庫

    $>su - sdbadmin
  3. 拷貝PostgreSQL文件數組

    $>cp -rf /usr/local/pgsql ~/
  4. 進入PostgreSQL目錄bash

    $>cd pgsql
  5. 環境變量添加PostgreSQL的lib庫app

    $>export LD_LIBRARY_PATH=$(pwd)/lib:${LD_LIBRARY_PATH}

    建議用戶將PostgreSQL的lib加到sdbadmin用戶的環境變量中,不然每次登錄sdbadmin使用PostgreSQL,都須要手工添加PostgreSQL的lib 到 LD_LIBRARY_PATH中tcp

    $> echo "export LD_LIBRARY_PATH=$(pwd)/lib:${LD_LIBRARY_PATH}" >> ~/.bash_profile
  6. 建立PostgreSQL的數據目錄post

    $>mkdir pg_data
  7. 初始化數據目錄(該操做只能操做一次)

    $>bin/initdb -D pg_data/

1.2 安裝SequoiaDB-PostgreSQL插件

  1. 建立PostgreSQL的lib 目錄

    獲取PostgreSQL的libdir路徑

    $> PGLIBDIR=$(bin/pg_config --libdir)

    若是顯示的libdir目錄不存在,則須要用戶本身手工建立目錄

    $> mkdir -p ${PGLIBDIR}
  2. 建立PostgreSQL的extension目錄

    獲取PostgreSQL的sharedir路徑

    $> PGSHAREDIR=$(bin/pg_config --sharedir)

    在shardir目錄上再建立extemsion目錄

    $> mkdir -p ${PGSHAREDIR}/extension
  3. 從SequoiaDB的安裝包中,拷貝PostgreSQL的擴展文件

    從SequoiaDB安裝後的postgresql目錄中拷貝sdb_fdw.so文件到PostgreSQL的lib目錄,SequoiaDB默認安裝目錄爲/opt/sequoiadb

    $> cp -f /opt/sequoiadb/postgresql/sdb_fdw.so ${PGLIBDIR}
  4. 將sdb_fdw.control和sdb_fdw--1.0.sql腳本拷貝到extension目錄中,兩個腳本須要用戶手工編輯

    $> cp -f sdb_fdw.control ${PGSHAREDIR}/extension/ ;
    $> cp -f sdb_fdw--1.0.sql ${PGSHAREDIR}/extension/ ;

    sdb_fdw.control 腳本內容

    # sdb_fdw extension
        comment = 'foreign data wrapper for SequoiaDB access'
        default_version = '1.0'
        module_pathname = '$libdir/sdb_fdw'
        relocatable = true

    sdb_fdw--1.0.sql 腳本內容

    /* contrib/mongo_fdw/sdb_fdw--1.0.sql */
    -- complain if script is sourced in psql, rather than via CREATE EXTENSION
    \echo Use "CREATE EXTENSION sdb_fdw" to load this file. \quit
    CREATE FUNCTION sdb_fdw_handler()
    RETURNS fdw_handler
    AS 'MODULE_PATHNAME'
    LANGUAGE C STRICT;
    CREATE FUNCTION sdb_fdw_validator(text[], oid)
    RETURNS void
    AS 'MODULE_PATHNAME'
    LANGUAGE C STRICT;
    CREATE FOREIGN DATA WRAPPER sdb_fdw
    HANDLER sdb_fdw_handler
    VALIDATOR sdb_fdw_validator;

1.3 部署PostgreSQL

  1. 檢查端口是否被佔用

    PostgreSQL默認啓動端口爲」5432」,檢查端口是否被佔用(檢查操做建議使用root用戶操做,只有檢查端口須要root權限,其他操做仍是須要在sdbadmin用戶下操做)

    $>netstat -nap | grep 5432

    若是5432端口被佔用或者但願修改PostgreSQL的啓動端口,則執行:

    $> sed -i "s/#port = 5432/port = 11780/g" pg_data/postgresql.conf
  2. 啓動Postgresql服務進程(須要使用sdbadmin用戶執行如下命令)

    $> bin/postgres -D pg_data/ >> logfile 2>&1 &
  3. 檢查PostgreSQL是否啓動成功

    執行命令:

    $> netstat -nap | grep 5432

    結果爲:

    tcp   0   0 127.0.0.1:5432     0.0.0.0:*         LISTEN     20502/postgres
    unix  2   [ ACC ]   STREAM    LISTENING   40776754 20502/postgres     /tmp/.s.PGSQL.5432
  4. 建立PostgreSQL的database

    $> bin/createdb -p 5432 foo

  5. 進入PostgreSQL shell 環境

    $> bin/psql -p 5432 foo

2. PostgreSQL鏈接SequoiaDB

如下操做均在PostgreSQL shell 環境下執行

2.1 PostgreSQL與SequoiaDB創建關聯

  1. 加載SequoiaDB鏈接驅動

    foo=# create extension sdb_fdw;
  2. 配置與SequoiaDB鏈接參數

    foo=# create server sdb_server foreign data wrapper sdb_fdw options(address '192.168.30.182', service '11810', user 'sdbadmin', password 'cmbc123');
  3. 關聯SequoiaDB的集合空間與集合

    注:集合空間與集合必須已經存在於SequoiaDB,不然查詢出錯。
    默認狀況下,表的字段映射到SequoiaDB中爲小寫字符,若是強制指定字段爲大寫字符,建立方式參考注意事項1
    映射SequoiaDB 的數組類型,建立方式參考注意事項2

    foo=# create foreign table test (name text, id numeric) server sdb_server options ( collectionspace 'chen', collection 'test' ) ;
  4. 查詢

    foo=# select * from test;
  5. 寫入數據

    foo=# insert into test values('one',3);
  6. 更改數據

    foo=# update test set id=9 where name='one';
  7. 查看全部的表(show tables;)

    foo=# \d
  8. 查看錶的描述信息

    foo=# \d test
  9. 刪除表

    foo=# drop foreign table test;
  10. 退出PostgreSQL shell環境

    foo=# \q

2.2 使用須知

2.2.1 數據類型的對應關係

圖片描述

2.2.2 注意事項

  1. 注意字符的大小寫

    SequoiaDB 中的集合空間、集合和字段名均對字母的大小寫敏感

    集合空間、集合名大寫

    假設SequoiaDB 中存在名爲TEST的集合空間,CHEN的集合,在PostgreSQL中創建相應的映射表

    foo=# create foreign table sdb_upcase_cs_cl (name text) server sdb_server options ( collectionspace 'TEST', collection 'CHEN' ) ;

    字段名大寫

    假設SequoiaDB 中存在名爲foo的集合空間,bar的集合,並且保存的數據爲:

    {
     "_id": {
       "$oid":"53a2a0e100e75e2c53000006"
     },
     "NAME": "test"
    }

    在PostgreSQL中創建相應的映射表

    foo=# create foreign table sdb_upcase_field (「NAME」 text) server sdb_server options ( collectionspace 'foo', collection 'bar' ) ;

    執行查詢命令:

    foo=# select * from sdb_upcase_field;

    查詢結果爲:

    NAME
    ------
     test
    (1 rows)
  2. 映射SequoiaDB中的數據類型

    假設SequoiaDB中存在foo集合空間,bar集合,保存記錄爲:

    {
     "_id": {
        "$oid":"53a2de926b4715450a000001"
     },
     "name": [
       1,
       2,
       3
     ],
     "id": 123
    }

    在PostgreSQL 中創建相應的映射表

    foo=# create foreign table bartest (name numeric[], id numeric) server sdb_server options ( collectionspace 'foo', collection 'bar' ) ;

    執行查詢命令:

    foo=# select * from bartest;

    查詢結果:

    name  | id
    ---------+-----
    {1,2,3} | 123
  3. 鏈接SequoiaDB 協調節點錯誤

    若是PostgreSQL鏈接的SequoiaDB 協調節點重啓,在查詢時報錯

    ERROR: Unable to get collection "chen.test", rc = -15
    HINT: Make sure the collectionspace and collection exist on the remote database

    解決方法:

    退出PostgreSQL shell

    foo=# \q

    從新進入PostgreSQL shell

    $> bin/psql -p 5432 foo

2.2.3 調整PostgreSQL配置文件

  1. 查看pg_shell中默認的配置

    執行命令:

    foo=#\set

    結果爲:

    AUTOCOMMIT = 'on'
    PROMPT1 = '%/%R%# '
    PROMPT2 = '%/%R%# '
    PROMPT3 = '>> '
    VERBOSITY = 'default'
    VERSION = 'PostgreSQL 9.3.4 on x86_64-unknown-linux-gnu, compiled by gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973], 64-bit'
    DBNAME = 'foo'
    USER = 'sdbadmin'
    PORT = '5432'
    ENCODING = 'UTF8'
  2. 調整pg_shell查詢時,每次獲取記錄數

    foo=#\set FETCH_COUNT 100

    調整爲每次ps_shell每次獲取100 條記錄當即返回記錄,而後再繼續獲取。

    直接在pg_shell中修改配置文件,只能在當前pg_shell中生效,從新登陸pg_shell須要從新設置。

  3. 修改配置文件,調整pg_shell查詢時,每次獲取記錄數

    執行命令:

    $> ${PG_HOME}/bin/pg_config -sysconfdir

    結果爲:

    /opt/sequoiadb/pgsql/etc

    若是顯示目錄不存在,本身手動建立便可

    $> mkdir -p /opt/sequoiadb/pgsql/etc

    將須要修改的參數寫入配置文件中

    $>echo "\\set FETCH_COUNT 100" >> /opt/sequoiadb/pgsql/etc/psqlrc
  4. 調整pg_shell的日誌級別

    $>sed -i 's/#client_min_messages = notice/client_min_messages = debug1/g' pg_data/postgresql.conf
  5. 調整pg引擎的日誌級別

    $>sed -i 's/#log_min_messages = warning/log_min_messages = debug1/g' pg_data/postgresql.conf

3. 使用java客戶端鏈接PostgreSQL

3.1 修改PostgreSQL的鏈接配置

  1. 修改PostgreSQL的監聽地址

    $>sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '0.0.0.0'/g" pg_data/postgresql.conf
  2. 修改信任的機器列表

    $>linenum=$(cat -n pg_data/pg_hba.conf | grep "# IPv4 local connections:" | awk '{print $1}'); \
    let "linenum=linenum+1";varStr="host   all            all            0.0.0.0/0              trust"; \
    sed -i "${linenum} a${varStr}" pg_data/pg_hba.conf;
  3. 重啓PostgreSQL

    $>bin/pg_ctl stop -s -D pg_data/ -m fast; bin/postgres -D pg_data/ >> logfile 2>&1 &

3.2 JDBC鏈接程序

```
package com.sequoiadb.sample;
import java.sql.*;
public class postgresql_sample {
   static{
       try {
           Class.forName"org.postgresql.Driver");
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
   }
   public static void main( String[] args ) throws SQLException{
      String pghost = "192.168.30.182";
      String port = "5432";
      String databaseName = "foo";
      // postgresql process is running in which user
      String pgUser = "sdbadmin";
      String url = "jdbc:postgresql://"+pghost+":"+port+"/" + databaseName;
      Connection conn = DriverManager.getConnection(url, pgUser, null);
      Statement stmt = conn.createStatement();
      String sql = "select * from sdb_upcase_field ";
      ResultSet rs = stmt.executeQuery(sql);
      boolean isHeaderPrint = false;
      while (rs.next()) {
           ResultSetMetaData md = rs.getMetaData();
           int col_num = md.getColumnCount();
           if (isHeaderPrint){
               for (int i = 1; i <= col_num; i++) {
                   System.out.print(md.getColumnName(i) + "|");
                   isHeaderPrint = true;
               }
           }
           for (i = 1; i <= col_num; i++) {
               System.out.print(rs.getString(i) + "|");
           }
           System.out.println();
       }
       stmt.close();
       conn.close();
   }
}
```
相關文章
相關標籤/搜索