在ApsaraDB获取到一个GP实例后,会得到以下信息:
-
连接地址
分为公网和私网,暂时不考虑VPC。私网地址只能通过阿里云ECS访问,公网地址则可以通过互联网上任一主机访问。例如:
公网地址:mygpdbpub.gpdb.rds.aliyuncs.com:3568 私网地址:mygpdb.gpdb.rds.aliyuncs.com:3432
-
账号密码
账号:mygpdb 密码:mygpdb
有了这些信息后,就可以连接到GP实例上进行相关的操作。
连接
GP目前基于的是PostgreSQL 8.3,完整支持PG 8.3的消息协议。因此,在各种操作下,与PG几无二致。
得益于PG 9.4消息协议的良好向后兼容性,所有基于PG 8.3以及之后的连接工具,大部分可以直接用于连接到GP,包括libpq、JDBC、ODBC、psycopg2、pgadmin III等。
GP官网提供了一个安装包,包含了JDBC、ODBC和libpq,方便安装和使用。请参考官方文档
psql && pgAdmin III
连接PG和GP,最为常用的莫过于psql和pgAdmin III了。psql是PG、GP安装后自带的类shell终端,可以执行所提供的诸多命令和SQL。以psql为例如:
$ ~/workspace/pgsql/bin/psql -h mygpdbpub.gpdb.rds.aliyuncs.com -p 3568 -d postgres -U mygpdb
Password for user mygpdb:
psql (9.4.4, server 8.3devel)
Type "help" for help.
postgres=> select version();
version
-----------------------------------------------------------------------------------------------
PostgreSQL 8.3devel (Greenplum Database 4.3.99.00 build dev) compiled on May 10 2016 01:19:10
(1 row)
postgres=>
其中,“-h”指定主机地址,“-p”指定端口号,“-d“指定数据库(默认的数据库是postgres),“-U”指定连接的用户。更多选项,通过“psql --help”可以看到。
在psql中,可以执行"?"查看更多psql中支持的命令。
pgAdmin III是图形客户端,相对简单,请参考或中文版。
JDBC
PostgreSQL的官方JDBC可以在这里下载到,下载之后加入到环境变量中即可。
代码案例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class gp_conn {
public static void main(String[] args) {
try {
Class.forName("org.postgresql.Driver");
Connection db = DriverManager.getConnection("jdbc:postgresql://mygpdbpub.gpdb.rds.aliyuncs.com:3568/postgres","mygpdb","mygpdb");
Statement st = db.createStatement();
ResultSet rs = st.executeQuery("select * from gp_segment_configuration;");
while (rs.next()) {
System.out.print(rs.getString(1));
System.out.print(" | ");
System.out.print(rs.getString(2));
System.out.print(" | ");
System.out.print(rs.getString(3));
System.out.print(" | ");
System.out.print(rs.getString(4));
System.out.print(" | ");
System.out.print(rs.getString(5));
System.out.print(" | ");
System.out.print(rs.getString(6));
System.out.print(" | ");
System.out.print(rs.getString(7));
System.out.print(" | ");
System.out.print(rs.getString(8));
System.out.print(" | ");
System.out.print(rs.getString(9));
System.out.print(" | ");
System.out.print(rs.getString(10));
System.out.print(" | ");
System.out.println(rs.getString(11));
}
rs.close();
st.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
详细文档请参考。
ODBC
PostgreSQL的ODBC是以LGPL协议开源的版本,可以在这里下载到。
也可以参考德哥的博客,里面有更详细的方法和案例。
Python
Python连接GP和PG用的库是psycopg2。安装方法很简单:
yum -y install python-psycopg2
或者
pip install psycopg2
或者从源码安装
yum install -y postgresql-devel*
wget http://initd.org/psycopg/tarballs/PSYCOPG-2-6/psycopg2-2.6.tar.gz
tar xf psycopg2-2.6.tar.gz
cd psycopg2-2.6
python setup.py build
sudo python setup.py install
安装后,设置PYTHONPATH,之后就可以引用,如:
import psycopg2
sql = 'select * from gp_segment_configuration;'
conn = psycopg2.connect(database='gpdb', user='mygpdb', password='mygpdb', host='mygpdbpub.gpdb.rds.aliyuncs.com', port=3568)
conn.autocommit = True
cursor = conn.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print row
conn.commit()
conn.close()
会得到类似以下的结果:
(1, -1, 'p', 'p', 's', 'u', 3022, '192.168.2.158', '192.168.2.158', None, None)
(6, -1, 'm', 'm', 's', 'u', 3019, '192.168.2.47', '192.168.2.47', None, None)
(2, 0, 'p', 'p', 's', 'u', 3025, '192.168.2.148', '192.168.2.148', 3525, None)
(4, 0, 'm', 'm', 's', 'u', 3024, '192.168.2.158', '192.168.2.158', 3524, None)
(3, 1, 'p', 'p', 's', 'u', 3023, '192.168.2.158', '192.168.2.158', 3523, None)
(5, 1, 'm', 'm', 's', 'u', 3026, '192.168.2.148', '192.168.2.148', 3526, None)
libpq
libpq是PostgreSQL原生支持用于连接PG的C库。在安装了GP或者PG之后,在其lib目录下可以找到其的静态库和动态库。这里有很多例子,此处不再列举。
常规操作
对GP的操作,整体与PG相较为一致,包括schema、类型支持、用户权限等。除了GP自身的一些特有的操作,如分布表、AO表等,其他操作皆可参考PG。
当前ApsaraDB For Greenplum对并没有开放DB实例的superuser权限,对应的则是rds_superuser,这一点与ApsaraDB For RDS(PostgreSQL)中的权限体系一致。
创建DB
Greenplum中创建DB的操作与PG相同,可以通过SQL来执行,如psql连接到GP后执行:
=> create database mygpdb;
CREATE DATABASE
=> \c mygpdb
psql (9.4.4, server 8.3devel)
You are now connected to database "mygpdb" as user "mygpdb".
mygpdb=> create extension postgis;
CREATE EXTENSION
创建分布表
在GP中,表是分布在所有的Segment上的,其分布规则是HASH或者随机。在建表的时候,指定分布键;当导入数据的时候,会根据分布键计算得到的HASH值分配到特定的Segment上。
=> create table vtbl(id serial, key integer, value text, comment text) distributed by (key);
CREATE TABLE
当不指定分布键的时候(即不带后面的"distributed by (key)"),GP会默认对id字段以round-robin的方式进行随机分配。
分布键
分布键对于查询性能至关重要。均匀为分布键选择的第一大原则,选取更有业务意义的字段,并非必须选择原库的主键。参考中,《Greenplum 数据库最佳实践》做了很好的说明。
查询
构造数据:
- 创建随机字符串生成函数和类型
CREATE OR REPLACE FUNCTION random_string(integer) RETURNS text AS $body$
SELECT array_to_string(array
(SELECT substring('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
FROM (ceil(random()*62))::int
FOR 1)
FROM generate_series(1, $1)), ''); $body$ LANGUAGE SQL VOLATILE;
CREATE TYPE cuboid AS (LENGTH integer, width integer, height integer);
- 创建分布表和构造数据
CREATE TABLE tbl(id serial, KEY integer, value text, shape cuboid, locate geometry, COMMENT text) distributed by (key);
INSERT INTO tbl(KEY, COMMENT, shape, locate, value) SELECT KEY, COMMENT, shape, ST_GeomFromText(locate) AS locate, value FROM (SELECT (a.t + 1) AS KEY, random_string(ceil(random() * 24)::integer) AS COMMENT, row(ceil(random() * 36 + 49), ceil(random() * 6 + 99), ceil(random() * 12 + 199))::cuboid AS shape, 'POINT(' || ceil(random() * 36 + 99) || ' ' || ceil(random() * 24 + 50) || ')' AS locate, (CASE WHEN a.b = 1 THEN 'red' WHEN a.b = 2 THEN 'green' WHEN a.b = 3 THEN 'yellow' WHEN a.b = 4 THEN 'blue' END) AS value FROM (SELECT ceil(random() * 4) b, t FROM generate_series(0, 99999) AS t) AS a) AS t;
- 查询
=> select * from vtbl where key = 13944;
id | key | value | shape | locate | comment
--------+-------+-------+--------------+--------------------------------------------+----------------
113944 | 13944 | red | (84,102,206) | 01010000000000000000405D400000000000C05140 | 22EaPlVqvfSgpq
(1 row)
Time: 513.101 ms
- PG上的查询
=> select * from tbl where key = 13944;
id | key | value | shape | locate | comment
-------+-------+-------+--------------+--------------------------------------------+--------------
13944 | 13944 | green | (55,105,207) | 01010000000000000000C05C400000000000004C40 | 3wQrCJqnHPds
(1 row)
Time: 1162.243 ms
在同样的表结构、记录数和没有添加任何索引的情况下,GP的查询要比PG的快一些。这个GP的实例是两个Segments,当记录数更多、Segments更多的时候,理论上差距会更明显。