MogDB企業應用 之 七種武器

如今江湖上最卷的門派,非國產數據庫莫屬。各位大俠們往往把精力放在拼內功(內核/架構)、拼身法(性能)、拼拳腳(功能/兼容性)、拼江湖地位(生態/社區)。然而好像并不怎么重視兵(武)器(接口/驅動/API),當然,可能我是搞C/C++出身,也許搞JAVA的兄弟并不會遇到這樣的困惑,因為一套JDBC可以打遍天下。雖然市場占有率的頭把交椅JAVA已經做了很多年,但隨著各種開發語言的大行其道,現代企業的信息化系統中不太可能只使用單一的開發語言。因此闖蕩江湖還是需要幾把趁手的兵器!
本文以古龍先生的《七種武器》和武器的寓意作為類比,簡單分析MogDB各種驅動的優勢與應用場景。
七種武器分別是:長生劍——寓意“笑”;孔雀翎——寓意“自信”;碧玉刀——寓意“誠實”;多情環——寓意“仇恨”;霸王槍——寓意“勇氣”;離別鉤——寓意“團聚”;箱子——寓意“道”;
當然,《七種武器》與MogDB驅動的類比并非那么貼切,甚至有些牽強。如果各位大俠有不同見解歡迎留言評論,一起切磋MogDB的“道”。
長生劍——psycopg

天上白玉京 五樓十二城 仙人撫我頂 結發授長生。
長生劍!江湖中最可怕的一把劍。他只有殺人,從沒有人能殺死他!長生劍的講的是“笑”——“無論多鋒利的劍,也比不上那動人的一笑。一個人只要懂得利用自己的長處,根本不必用武功也一樣能夠將人擊倒”。
“笑”對于每個人來說再簡單不過了,是每個人都能利用的一件武器。和笑一樣簡單的開發語言那當屬Python了。Python是一種代表簡單主義思想的語言,它編寫的程序讀起來就感覺像是在讀英語段落一樣流暢。它懂得利用自己的長處——化繁為簡,可以玩AI、大數據、做運維甚至非專業開發人員也可以熟練使用它,包括小朋友也可以拿它來進行邏輯思維的擴展。psycopg這把“長生劍”用最簡單的方式殺敵于無形。
功法
江湖上有一篇入門心法供各位參考使用Python-psycopg訪問postgres、openGauss、MogDB
- 安裝
獲取安裝介質,下載。
$ tar -zxvf openGauss-3.0.0-openEuler-x86_64-Python.tar.gz
# cp -r /home/postgres/psycopg2/ /usr/lib/python3.7/site-packages/
# chmod -R 775 psycopg2/
- 驗證
$ python3
Python 3.7.9 (default, Jan 25 2022, 15:12:36)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> conn=psycopg2.connect(database="postgres",user="frank",password="frank@123",host="localhost",port=5432)
>>> cur=conn.cursor()
>>> cur.execute("CREATE TABLE student(id integer,name varchar,sex varchar);")
>>> cur.execute("INSERT INTO student(id,name,sex) VALUES(%s,%s,%s)",(1,'Aspirin','M'))
>>> cur.execute("INSERT INTO student(id,name,sex) VALUES(%s,%s,%s)",(2,'Taxol','F'))
>>> cur.execute('SELECT * FROM student')
>>> results=cur.fetchall()
>>> print (results)
[(1, 'Aspirin', 'M'), (2, 'Taxol', 'F')]
>>> conn.commit()
>>> cur.close()
>>> conn.close()
>>>
秘籍
繼續修煉請參考官方文檔

江湖
能夠完美的發揮自己的特長,勝過手中鋒利的劍。有了psycopg,MogDB可以在很多領域大展拳腳,比如爬蟲系統、運維系統、AI、數據分析甚至是日常辦公。也可以讓MogDB在很多非核心的企業應用中發揮關鍵作用,讓MogDB更貼近普通人的舒適工作區。
孔雀翎——node-postgres

孔雀翎是早已不存在的暗器,高立向朋友秋鳳梧借來孔雀翎,信心十足地殺了強敵,這才發現孔雀翎已丟失。而秋鳳梧告訴他,孔雀翎早就沒有了,他借給高立的只是“信心”。“真正的勝利,并不是你用武器爭取的,一定要用你的信心。無論多可怕的武器,也比不上人的信心。”
前些年有這樣一個梗,PHP是“最好編程語言”,JavaScript將“一統天下”。不說PHP了,單講JavaScript的信心其實并非空穴來風,從前端開發中最能打的武器,到幾行代碼就可以寫出HTTP的服務“后端”,再到“全棧”、“大前端”。在江湖的各個門派中都有JS的一席之地。而node-postgres正是作為PostgreSQL體系數據庫的那把泰山之巔的“暗器”。
功法
- 安裝
$ npm install pg
- 范例
const { Client } = require('pg')
const client = new Client()
client.connect()
client.query('SELECT version()::text as version', (err, res) => {
console.log(err ? err.stack : res.rows[0].version)
client.end()
})
- 驗證
PGUSER=frank \ PGHOST=localhost \ PGPASSWORD=frank@123 \ PGDATABASE=postgres \ PGPORT=15432 \ node test.js
實測驗證最新的8.7.3版本node-postgres在MogDB 3.0.0上可正常使用,輸出如下:
(MogDB 3.0.0 build 62408a0f) compiled at 2022-06-30 14:21:11 commit 0 last mr on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit
秘籍
上面的例子只是簡單的范例,如果各位想繼續修煉可以參考官方文檔。

江湖
如果你用nodejs開發小型網站系統,爬蟲系統、或者微服務架構系統要是想使用一款數據庫,那么MogDB也將會出現在你的備選方案中。而node-postgres就是MogDB心中的“孔雀翎”。
碧玉刀——libpqxx

段家的碧玉刀非但價值連城,而且故老相傳,都說其中還藏著一個很大的秘密。無論誰只要能解開這秘密,他立刻就可能變成富可敵國的武林高手。
尺八長的碧玉刀看上去并不華麗,也談不上絕世神兵,氣質上看起來與libpqxx有幾分相似。說到libpqxx可能鮮有人知,甚至使用它的就更少了,但如果能夠解開它背后的秘密或許會變成“富可敵國的武林高手”。也許大家已經猜到它背后的秘密就是——libpq。其實libpqxx也是出自名門正派,它是PostgreSQL官方開源C++ 客戶單API。它華麗的C++外表下有著一顆C樸實的心,這也正符合了碧玉刀“誠實”的氣質。
功法
還是先推薦一篇江湖上的典籍libpqxx (PostgreSQL C++ API)——使用簡介
- 安裝
git clone https://github.com/jtv/libpqxx
git checkout 6.4
./configure --disable-documentation
make -j8
make check -j 8
make install
- 范例
test.sql
CREATE TABLE public.employee (
id int4 NULL,
"name" varchar(20) NULL,
gender bpchar(2) NULL,
birthday date NULL,
email bpchar(10) NULL,
remark varchar(50) NULL,
salary int8 NULL
);
insert into employee (id,name,gender,birthday,email,remark,salary) values(1,'frank','男','2014-02-23','f@123.com','',1000);
main.cpp
#include <iostream>
#include <pqxx/pqxx>
int main()
{
try
{
pqxx::connection C;
std::cout << "Connected to " << C.dbname() << std::endl;
pqxx::work W(C);
pqxx::result R = W.exec("SELECT name FROM employee");
std::cout << "Found " << R.size() << "employees:" << std::endl;
for (auto row: R)
std::cout << row[0].c_str() << std::endl;
std::cout << "Doubling all employees' salaries..." << std::endl;
W.exec("UPDATE employee SET salary = salary*2");
std::cout << "Making changes definite: ";
W.commit();
std::cout << "OK." << std::endl;
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}
run.sh
rm -rf a.out
g++ main.cpp -lpqxx -lpq -L/home/frank/pgsql/lib
export PGDATABASE=postgres
export PGHOST=localhost
export PGPORT=15432
export PGUSER=frank
export PGPASSWORD=frank@123
psql -h localhost -p 15432 -d postgres -U frank -W 'frank@123' -f test.sql
./a.out
- 編譯
g++ main.cpp -lpqxx -lpq -L/home/frank/pgsql/lib
- 驗證
frank@DESKTOP-6NF3B9K:~/test/libpqxx$ sh run.sh
psql: warning: extra command-line argument "frank@123" ignored
Password:
DROP TABLE
CREATE TABLE
INSERT 0 1
Connected to postgres
Found 1employees:
frank
Doubling all employees' salaries...
Making changes definite: OK.
秘籍
繼續修煉請參考官方文檔。

江湖
libpqxx并不是什么絕世神兵,他能做的事情libpq都可以做,但通過C++封裝后,它具備了更加友好的用戶接口,同時也大大提升了開發效率,如果您使用C++開發MogDB的應用,或者您公司使用比較高版本的C++標準,例如:C++17,那么libpqxx會大幅減少您公司的開發成本,并且保證了代碼風格的一致性。相信MogDB配上了libpqxx這把“碧玉刀”,在江湖路上必將一路坦途。
霸王槍——Golang pq

霸王槍長一丈三尺七寸三分,重七十三斤七兩三錢。霸王槍象征勇氣。“一個人只要有勇氣去冒險,天下就絕沒有不能解決的事。”
Golang是年輕充滿朝氣的開發語言,它誕生于2007年,發布與2009年,自發布以來,披荊斬棘,一時間攪得江湖上不得安寧。Golang以編譯型語言的姿態挑戰C的性能,以輕量級的攜程挑戰java和c++的并發,從日志處理、運維監控,到虛擬機、容器、區塊鏈等后端,再到代理、web應用、API應用,憑著這股“勇氣”,在各個領域Go都有上佳表現。
Golang pq對于PostgreSQL系的數據庫有著非常重要的作用,不僅僅是在企業應用中,在MogDB的周邊工具(如MTK等)開發中,這桿“霸王槍”也發發揮了重要作用,也許日后MogDB的監控和運維工具也會有Golang pq的一席之地。
對于Golang pq,恩墨也有自己的版本:openGauss-connector-go-pq
功法
- 獲取
go get gitee.com/opengauss/openGauss-connector-go-pq
- 注意:如果遇到golang.org/x/ 報錯相關問題可以使用下面方法
mkdir $GOPATH/src/golang.org/x/
cd $GOPATH/src/golang.org/x/
git clone https://github.com/golang/text.git text
git clone https://github.com/golang/crypto.git crypto
git clone https://github.com/golang/xerrors.git xerrors
go install text
go install crypto
go install xerrors
- 范例
package main
import (
"fmt"
"log"
"database/sql"
_ "gitee.com/opengauss/openGauss-connector-go-pq"
)
func main() {
connStr := "host=127.0.0.1 port=15432 user=frank password=frank@123 dbname=postgres sslmode=disable"
// db, err := sql.Open("opengauss", connStr)
db, err := sql.Open("mogdb", connStr)
if err != nil {
log.Fatal(err)
}
var version string
err = db.QueryRow("select version()").Scan(&version)
if err != nil {
log.Fatal(err)
}
fmt.Println(version)
}
- 驗證
frank@DESKTOP-6NF3B9K:~/test/go/src$ ll
total 7480
drwxr-xr-x 5 frank frank 4096 Aug 6 09:31 ./
drwxr-xr-x 4 frank frank 4096 Aug 5 21:54 ../
drwxr-xr-x 3 frank frank 4096 Aug 5 21:52 gitee.com/
drwxr-xr-x 3 frank frank 4096 Aug 5 21:52 github.com/
drwxr-xr-x 3 frank frank 4096 Aug 5 21:54 golang.org/
-rwxr-xr-x 1 frank frank 7631349 Aug 6 09:26 main*
-rw-r--r-- 1 frank frank 480 Aug 5 21:57 main.go
frank@DESKTOP-6NF3B9K:~/test/go/src$ ./main
(MogDB 3.0.0 build 62408a0f) compiled at 2022-06-30 14:21:11 commit 0 last mr on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit
frank@DESKTOP-6NF3B9K:~/test/go/src$
秘籍
Golang pq 源碼


江湖
Golang就像橫空出世的霸王槍,憑借著“勇氣”已經撼動了不少企業級的JAVA和C/C++應用,一些企業的核心系統已經逐漸的開始向Golang轉型。隨著應用架構的不斷演進,MogDB想在江湖上保持競爭力,一定要緊握Golang pq這桿搶。
多情環——JDBC

多情自古空余恨,好夢由來最易醒。豈是拈花難解脫,可憐飛絮太飄零。
想必大家還記得Oracle宣布JDK 8u202以上版本開始商用收費的消息,“好夢由來最易醒”,從SUN到Oracle再到商用收費,也許這是必然的過程,隨著商用收費的宣布,我們的夢也應該醒了。雖然可以選擇繼續使用低版本,或者openJDK,但一定會對企業應用和未來的技術路線有一定的沖擊。欣喜的是國內的華為、阿里也有基于openJDK的產品,但在我們龐大系統中分散著太多依賴JDK的組件,需要全面的兼容性評估——豈是拈花難解脫,可憐飛絮太飄零。
java無疑是目前市場占有率做大的一門企業級開發語言,沒有之一。可以說幾乎沒有企業的信息化系統不使用java作為主要的技術棧,從業務系統、大數據、信息系統幾乎java應用遍及大部分核心系統。作為應用與數據庫的橋梁——JDBC來說真是又愛又恨。
功法
- 安裝
官方軟件包

- 范例
import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JdbcDemo {
public static void main(String[] args) throws Exception {
System.out.println("System.out.println(rs.getString(1));");
Class.forName("org.opengauss.Driver");
Connection conn = DriverManager.getConnection("jdbc:opengauss://localhost:15432/postgres?user=frank&password=frank@123&ssl=false");
String sql = "select version()";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next())
{
System.out.print("Version : ");
System.out.println(rs.getString(1));
}
stmt.close();
conn.close();
}
}
- 驗證
$ export CLASSPATH=/home/frank/test/java/opengauss-jdbc-3.0.0.jar:$CLASSPATH
$ javac JdbcDemo.java
$ java JdbcDemo
System.out.println(rs.getString(1));
Aug 06, 2022 10:24:12 AM org.opengauss.core.v3.ConnectionFactoryImpl openConnectionImpl
INFO: [11a01b6b-3b51-4549-b552-6f836646ef36] Try to connect. IP: localhost:15432
Aug 06, 2022 10:24:12 AM org.opengauss.core.v3.ConnectionFactoryImpl openConnectionImpl
INFO: [127.0.0.1:39218/ocalhost/127.0.0.1:15432] Connection is established. ID: 11a01b6b-3b51-4549-b552-6f836646ef36
Aug 06, 2022 10:24:12 AM org.opengauss.core.v3.ConnectionFactoryImpl openConnectionImpl
INFO: Connect complete. ID: 11a01b6b-3b51-4549-b552-6f836646ef36
Version : (MogDB 3.0.0 build 62408a0f) compiled at 2022-06-30 14:21:11 commit 0 last mr on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit
秘籍


江湖
對java我們有著復雜的感情,國內有著最多的java程序員群體,甚至可以用“過剩”這個詞。對于JDK來說,雖然國內像阿里、華為這樣的大廠已經有了JDK的產品,但尚未成熟,需要社區繼續努力和生態的支撐。MogDB作為基于openGauss的企業級數據庫,嚴格說也屬于華為鯤鵬生態的一部分,華為有著完備的全棧生態體系,從Kunpeng 處理器、openEuler操作系統、openGauss/GaussDB數據庫到畢昇編譯器,畢昇JDK。在IT技術垂直領域幾乎面面俱到。MogDB是華為數據庫生態領域的水平拓展,既享受著生態的紅利,又是生態建設的主要力量——恩墨對openGauss社區的貢獻僅次于華為。
離別鉤——ODBC

“你為什么要用如此殘酷的武器?”“因為我不愿被人強迫與我所愛的人離別。”……“你用離別鉤,只不過為了要相聚。”
說起ODBC,一些早年的程序員會比較熟悉,但現在似乎漸漸的與我們“離別”,JDBC也是復用了ODBC的思想后大行其道,但由于原生的數據庫C/C++接口從性能到兼容性上表現的更為出色,而C/C++往往追求的恰恰是性能,所以ODBC在企業應用的用武之地變得越來越少。
功法
- 安裝
獲取unixODBC
tar -zxvf unixODBC-2.3.7pre.tar.gz
cd unixODBC-2.3.7pre
./configure
make -j6
sudo make install
tar -zxvf openGauss-3.0.0-ODBC.tar.gz
export ODBCSYSINI=/usr/local/etc
export ODBCINI=/usr/local/etc/odbc.ini
export LD_LIBRARY_PATH=/home/frank/test/odbc/lib:/home/frank/test/odbc/odbc/lib:$LD_LIBRARY_PATH
- 配置
/usr/local/etc/odbcinst.ini
# /usr/local/etc/odbcinst.ini
[GaussMPP]
Driver64=/home/frank/test/odbc/odbc/lib/psqlodbcw.so
setup=/home/frank/test/odbc/odbc/lib/psqlodbcw.so
/usr/local/etc/odbc.ini
# /usr/local/etc/odbc.ini
[MOGODBC]
Driver=GaussMPP
Servername=localhost
Database=postgres
Username=frank
Password=frank@123
Port=15432
Sslmode=disable
frank@DESKTOP-6NF3B9K:/usr/local/etc$ isql -v MOGODBC
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> select version();
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| version |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| (MogDB 3.0.0 build 62408a0f) compiled at 2022-06-30 14:21:11 commit 0 last mr on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
SQLRowCount returns 1
1 rows fetched
SQL>
- 范例
// 此示例演示如何通過ODBC方式獲取MogDB中的數據。
// DBtest.c (compile with: libodbc.so)
#include <stdlib.h>
#include <stdio.h>
#include <sqlext.h>
#ifdef WIN32
#include <windows.h>
#endif
SQLHENV V_OD_Env; // Handle ODBC environment
SQLHSTMT V_OD_hstmt; // Handle statement
SQLHDBC V_OD_hdbc; // Handle connection
char typename[100];
SQLINTEGER value = 100;
SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id;
int main(int argc,char *argv[])
{
// 1. 申請環境句柄
V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHandle\n");
exit(0);
}
// 2. 設置環境屬性(版本信息)
SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// 3. 申請連接句柄
V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
// 4. 設置連接屬性
SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
// 5. 連接數據源,這里的“userName”與“password”分別表示連接數據庫的用戶名和用戶密碼,請根據實際情況修改。
// 如果odbc.ini文件中已經配置了用戶名密碼,那么這里可以留空("");但是不建議這么做,因為一旦odbc.ini權限管理不善,將導致數據庫用戶密碼泄露。
V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "MOGODBC", SQL_NTS,
(SQLCHAR*) "frank", SQL_NTS, (SQLCHAR*) "frank@123", SQL_NTS);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLConnect %d\n",V_OD_erg);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Connected !\n");
// 6. 設置語句屬性
SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
// 7. 申請語句句柄
SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
// 8. 直接執行SQL語句。
SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS);
SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS);
SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS);
// 9. 準備執行
SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS);
// 10. 綁定參數
SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,
&value,0,NULL);
// 11. 執行準備好的語句
SQLExecute(V_OD_hstmt);
SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS);
// 12. 獲取結果集某一列的屬性
SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL);
printf("SQLColAtrribute %s\n",typename);
// 13. 綁定結果集
SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150,
(SQLLEN *)&V_OD_err);
// 14. 通過SQLFetch取結果集中數據
V_OD_erg=SQLFetch(V_OD_hstmt);
// 15. 通過SQLGetData獲取并返回數據。
while(V_OD_erg != SQL_NO_DATA)
{
SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL);
printf("SQLGetData ----ID = %d\n",V_OD_id);
V_OD_erg=SQLFetch(V_OD_hstmt);
};
printf("Done !\n");
// 16. 斷開數據源連接并釋放句柄資源
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
return(0);
}
- 驗證
frank@DESKTOP-6NF3B9K:~/test/odbc$ gcc main.c -lodbc -o main -w
frank@DESKTOP-6NF3B9K:~/test/odbc$ ./main
Connected !
SQLColAtrribute
Done !
秘籍
看了網上的一些文檔綜合比下來ODBC這塊還是參考MogDB官方文檔 (客觀的講,MogDB的文檔在對比其競品確實做的很好)

江湖
離別意味著再次相聚,隨著國產數據庫遷移的步伐加快,在選型或者過度階段可能會同時適配多種不同的數據庫,諸如:mysql體系、postgres體系或者完全自研的國產數據庫,如果適配每一種數據庫都使用期原生的C/C++驅動,那么無形中會增加很大的工作量,既是有系統有很好的架構設計(有SQL適配層或者使用ORM)也避免不了要做全面的測試。但據我目前的實踐經驗看,幾乎所有的國產關系型數據庫都提供了ODBC(就像JDBC一樣)標準的接口,這樣只要適配了ODBC接口就可以一勞永逸。
箱子——libpq

《英雄無淚》塑造出一個極為經典的兵器-箱子,這口箱子復雜玄妙,可任意變換成各種兵器,是武器的集大成者。箱子寓意武者的“道”。
任何武器都是身外之物,只有libpq是和內核代碼放在一起,所以說它并非武器,而是“道”是PostgreSQL的“道”也是openGauss/MogDB的“道”。
功法
- 安裝
獲取安裝介質
- 范例
/*
* testlibpq.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
static void
exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int
main(int argc, char **argv)
{
const char *conninfo;
PGconn *conn;
PGresult *res;
int nFields;
int i,j;
/*
* 用戶在命令行上提供了conninfo字符串的值時使用該值
* 否則環境變量或者所有其它連接參數
* 都使用缺省值。
*/
if (argc > 1)
conninfo = argv[1];
else
conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
/* 連接數據庫 */
conn = PQconnectdb(conninfo);
/* 檢查后端連接成功建立 */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
}
/*
* 測試實例涉及游標的使用時候必須使用事務塊
*把全部放在一個 "select * from pg_database"
* PQexec() 里,過于簡單,不推薦使用
*/
/* 開始一個事務塊 */
res = PQexec(conn, "BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/*
* 在結果不需要的時候PQclear PGresult,以避免內存泄漏
*/
PQclear(res);
/*
* 從系統表 pg_database(數據庫的系統目錄)里抓取數據
*/
res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
res = PQexec(conn, "FETCH ALL in myportal");
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/* 打印屬性名稱 */
nFields = PQnfields(res);
for (i = 0; i < nFields; i++)
printf("%-15s", PQfname(res, i));
printf("\n\n");
/* 打印行 */
for (i = 0; i < PQntuples(res); i++)
{
for (j = 0; j < nFields; j++)
printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
PQclear(res);
/* 關閉入口 ... 不用檢查錯誤 ... */
res = PQexec(conn, "CLOSE myportal");
PQclear(res);
/* 結束事務 */
res = PQexec(conn, "END");
PQclear(res);
/* 關閉數據庫連接并清理 */
PQfinish(conn);
return 0;
}
- 驗證
export LD_LIBRARY_PATH=/home/frank/test/libpq/lib/:$LD_LIBRARY_PATH
gcc testlibpq.c -I include -L lib -lpq -o testlibpq

秘籍
PostgreSQL官方文檔

MogDB官方文檔

江湖
沒有武器就是有武器,有武器就是沒有武器。一口箱子可以任意變換成各種兵器,libpqxx、ODBC、node posstgres、psycopg等等都可以找到他的影子。libpq是PostgreSQL系數據庫最強的武器,也是他們的道。
- 幻化ODBC

- 幻化libpqxx

- 幻化node-postgres

番外篇
洋槍——OCI/OCCI

與上面的冷兵器不同,洋槍的出現改變了人類了的戰爭史。而“洋槍”這個詞,在國人的心中有著意味深長的寓意,可能是“落后”、“屈辱”亦或是“臥薪嘗膽的意志”。
這東西用著很順手,或許是用慣了。當然如果找一件趁手的兵器替代它也并非難事,但是需要付出一定的學習成本和時間。那么不妨在過度期間我們可以先模仿它的用法,哪怕扣響扳機后打出來的不是“子彈”,而是“袖箭”。
很多大俠已經開始這么干了,相信MogDB也已經在路上。
尾聲

MogDB可用的武器遠不止七種,這里只是列出來企業級應用最常用的幾種。就像開頭說的,各位大俠們并不是那么地重視驅動,而豐富的數據庫驅動接口是滿足企業復雜的應該系統的必要條件。對于MogDB來說繼承了祖上(PostgreSQL、openGauss)豐富的驅動接口,這是MogDB是優勢。可能現在缺的就是一把“洋槍”。
這里還要特別提一下除了武器之外MogDB的一些拳腳功夫,像server端的過程語言:PL/pgSQl、PL/Tcl、PL/Perl、PL/Python、PL/Java;可以擴展內部函數:C FUNCTION、Embedded SQL in C;可以熱插拔的插件:contrib下面C開發的插件、使用rust pgx開發的rust語言插件等等,就擴展性來說,我認為PostgreSQL/openGauss/MogDB是最強大的,沒有之一,這也是MogDB吸引我的最重要原因。由于篇幅有限,后續有機會再和大家一起討論 MogDB的拳腳功夫 。





