数据类型
序号 | 类型名 | 对应的java类型 | 取值范围 | 说明 |
---|---|---|---|---|
1 | INTEGER | INTEGER | [-2147483648, 2147483647] | binary表示是4个byte的整数, 符号位被翻转(为了让负数排在正数前面) |
2 | UNSIGNED_INT | Integer | [ 0,2147483647] | binary表示是4个byte的整型。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(int)方法。 |
3 | BIGINT | Long | [-9223372036854775808 ,9223372036854775807] | binary表示是8位byte的Long类型, 符号位被翻转(为了让负数排在正数前面) |
4 | UNSIGNED_LONG | Long | [0 ,9223372036854775807] | binary表示是8位byte的Long类型。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(long)方法。 |
5 | TINYINT | Byte | [-128,127] | binary表示是单个byte,为了排序符号位被翻转。 |
6 | UNSIGNED_TINYINT | Byte | [0,127] | binary表示是单个byte。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配 HBase Bytes.toBytes(byte)方法。 |
7 | SMALLINT | Short | [-32768,32767] | binary表示是两个byte,为了排序符号位被翻转。 |
8 | UNSIGNED_SMALLINT | Short | [0,32767] | binary表示是两个byte。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(short)方法。 |
9 | FLOAT | Float | [-3.402823466 E + 38,3.402823466 E + 38] | binary表示是四个byte, 为了排序符号位被翻转。 |
10 | UNSIGNED_FLOAT | Float | [0,3.402823466 E + 38] | binary表示是四个byte。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(float)方法。 |
11 | DOUBLE | DOUBLE | [-1.7976931348623158 E + 308,1.7976931348623158 E + 308] | binary表示是8个byte,为了排序符号位被翻转。 |
12 | UNSIGNED_DOUBLE | DOUBLE | [0,1.7976931348623158 E + 308] | binary表示是8个byte。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(double)方法。 |
13 | DECIMAL(precision,scale) | BigDecimal | 最大精度38位 | binary是可比较的边长格式。如果用于rowkey。 当它不是最后一列时,比较终结符号是null byte |
14 | BOOLEAN | BOOLEAN | 0或1 | binary表示0是flase, 1是true |
15 | TIME | java.sql.Time | 格式: yyyy-MM-dd hh:mm:ss | 二进制表示是8位byte的long类型数据, 数据内容是客户端时区自1970-01-01 00:00:00 UTC到现在的毫秒大小(GMT)。此类型与 SQL 92中的Time类型不兼容 |
16 | DATE | java.sql.Date | 格式: yyyy-MM-dd hh:mm:ss | 二进制表示是8位byte的long类型数据, 数据内容是客户端时区自1970-01-01 00:00:00 UTC到现在的毫秒大小(GMT)。此类型与 SQL 92中的DATE类型不兼容。 |
17 | TIMESTAMP | java.sql.Timestamp | 格式:yyyy-MM-dd hh:mm:ss[.nnnnnnnnn] | 二进制表示是8位byte的long类型和4位整型纳秒。8位byte的long类型数据是客户端时区自1970-01-01 00:00:00 UTC到现在的毫秒大小(GMT)。 |
18 | UNSIGNED_TIME | java.sql.Time | 格式: yyyy-MM-dd hh:mm:ss | 二进制表示是8位byte的long类型数据, 数据内容是客户端时区自1970-01-01 00:00:00 UTC到现在的毫秒大小(GMT)。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(long)方法。 |
19 | UNSIGNED_DATE | java.sql.Date | 格式: yyyy-MM-dd hh:mm:ss | 二进制表示是8位byte的long类型数据, 数据内容是客户端时区自1970-01-01 00:00:00 UTC到现在的毫秒大小(GMT)。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(long)方法。 |
20 | UNSIGNED_TIMESTAMP | java.sql.Timestamp | 格式:yyyy-MM-dd hh:mm:ss[.nnnnnnnnn] | 二进制表示是8位byte的long类型和4位整型纳秒。8位byte的long类型数据是客户端时区自1970-01-01 00:00:00 UTC到现在的毫秒大小(GMT)。这个类型主要用作序列化映射到已经存在Hbase表的数据,适配HBase Bytes.toBytes(long)方法。 |
21 | VARCHAR(precisionInt) | java.lang.String | 变长,可选最大长度 | 对应UTF-8字符通过HBase Bytes.toBytes(String)转换的二进制。如果用于rowkey。 当它不是最后一列时,比较终结符号是null byte |
22 | CHAR ( precisionInt ) | java.lang.String | 定长 | 对应UTF-8字符通过HBase Bytes.toBytes(String)转换的二进制。 |
23 | BINARY ( precisionInt ) | byte[] | 定长 | 定长byte数组 |
24 | VARBINARY | byte[] | 变长 | 变长byte数组 |
25 | ARRAY [dimension] | java.sql.Array | - | Java原始类型数组,只支持一维数组。例如:VARCHAR ARRAY, CHAR(10) ARRAY [5],INTEGER [],INTEGER [100] |
连接的两种方式
Phoenix Shell
启动 Zookeeper => HDFS => Yarn => HBase
1 | sqlline.py hadoop01,hadoop02,hadoop03:2181 |
第一次启动比较慢,请耐心等待。
查询
1 | !tables |
Phoenix Query Server
在 4.4-4.14 和5.0 releases 中 query server 及其 JDBC client 是内置的.
4.15以后 及5.1 release版本,Phoenix Query Server 需要单独下载, 版本号为 6.0.
下载及安装
下载地址:Download page
1 | tar -zxvf phoenix-queryserver-6.0.0-bin.tar.gz -C /root/ |
启动query server
1 | queryserver.py start |
测试
1 | sqlline-thin.py http://hadoop01:8765 |
停止
1 | queryserver.py stop |
SQL操作
Schema的操作
1)创建schema
查看所有schema
1 | !schema |
创建schema
1 | create schema "zdb"; |
注意:在phoenix中,schema名,表名,字段名等会自动转换为大写,若要小写,使用双引号,如
"zdb"
。
执行如下命令使用这个新建的 schema:
1 | use "zdb"; |
执行如下命令则使用默认的 schema:
1 | USE DEFAULT; |
执行如下命令可以删除 zdb 这个 schema:
注意:确保该 schema 下的表都已删除,否则该 schema 会删除失败。
1 | DROP SCHEMA "zdb"; |
表操作
显示所有表
1 | !table |
创建表
创建表的时候一定要设置主键,这个会作为RowKey使用。
直接指定单个列作为RowKey
1 | CREATE TABLE IF NOT EXISTS "tuser"( |
指定多个列的联合作为RowKey
1 | CREATE TABLE IF NOT EXISTS us_population ( |
插入数据
1 | upsert into "tuser" values('1001','zhangsan','beijing'); |
查询记录
1 | select * from "tuser"; |
分页查询
1 | select * from "tuser" order by id desc limit 1 offset 0; |
其中
limit
取多少条offset
从多少条开始
在Hbase中查看
1 | hbase shell |
索引
查看是否用到索引
1 | explain select * from "tuser"; |
只要出现FULL SCAN
就证明没用用到索引
创建索引
1 | CREATE INDEX "index_tuser_name" ON "zdb"."tuser"(name); |
删除索引
1 | DROP INDEX "index_tuser_name" ON "zdb"."tuser"; |
如果创建二级索引报错
Mutable secondary indexes must have the hbase.regionserver.wal.codec property
停止hbase
1 | $HBASE_HOME/bin/stop-hbase.sh |
在每个regionServer的hbase-site.xml添加以下语句:
1 | <property> |
分发配置
1 | ha-call.sh "rm -rf $HBASE_HOME/logs/*" |
重启hbase即可
1 | $HBASE_HOME/bin/start-hbase.sh |
也要重启queryserver
1 | queryserver.py stop |
删除记录
1 | delete from "tuser" where id='1001'; |
删除表
1 | drop table "tuser"; |
7)退出命令行
1 | !quit |
表的映射
默认情况下:
Phoenix中创建的表在HBase中是可以看到的。
直接在HBase中创建的表,通过Phoenix是查看不到的。
1)表的关系
如果要在Phoenix中操作直接在HBase中创建的表,则需要在Phoenix中进行表的映射。
映射方式有两种:
- 视图映射
- 表映射。
2)命令行中创建表test
HBase 中test的表结构如下,两个列族info1、info2。
Rowkey | info1 | info2 |
---|---|---|
id | name | address |
启动HBase Shell
1 | hbase shell |
创建HBase表test
1 | create 'test','info1','info2' |
3)视图映射
Phoenix创建的视图是只读的,所以只能用来做查询,无法通过视图对源数据进行修改等操作。
在phoenix中创建关联test表的视图
1 | create view "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar); |
删除视图
1 | drop view "test"; |
4)表映射
使用Apache Phoenix创建对HBase的表映射,有两种方法:
- HBase中不存在表时,可以直接使用create table指令创建需要的表,系统将会自动在Phoenix和HBase中创建同名的表,并会根据指令内的参数对表结构进行初始化。
- 当HBase中已经存在表时,可以以类似创建视图的方式创建关联表,只需要将create table改为create view即可。
1 | create table "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar) column_encoded_bytes=0; |
表映射中数值类型的问题
Hbase中存储数值类型的值(如int,long等)会按照正常数字的补码进行存储. 而phoenix对数字的存储做了特殊的处理. phoenix 为了解决遇到正负数同时存在时,导致负数排到了正数的后面(负数高位为1,正数高位为0,字典序0 < 1)的问题。
phoenix在存储数字时会对高位进行转换.原来为1,转换为0, 原来为0,转换为1.
因此,如果hbase表中的数据的写是由phoenix写入的,不会出现问题,因为对数字的编解码都是phoenix来负责。
如果hbase表中的数据不是由phoenix写入的,数字的编码由hbase负责. 而phoenix读数据时要对数字进行解码。 因为编解码方式不一致。导致数字出错。
1) 在hbase中创建表,并插入数值类型的数据
1 | create 'person','info' |
注意: 如果要插入数字类型,需要通过Bytes.toBytes(123456)来实现。
2)在phoenix中创建映射表并查询数据
1 | create table "person"(id varchar primary key,"info"."salary" integer) column_encoded_bytes=0; |
会发现数字显示有问题
3) 解决办法:
在phoenix中创建表时使用无符号的数值类型unsigned_long
1 | create table "person"(id varchar primary key,"info"."salary" unsigned_long) column_encoded_bytes=0; |
DBeaver连接
DBeaver中搜索phoenix
修改DBeaver配置
修改dbeaver.ini
文件,增加如下内容
1 | -vm |
连接配置
连接属性
驱动属性中也添加
属性
1 | phoenix.schema.isNamespaceMappingEnabled |
值
1 | true |
自动下载的Jar版本较老
我们要引用对应版本的Jar
1 | phoenix-client-hbase-2.1-5.1.2.jar |
服务配置
如果报错
CATALOG is found but client does not have phoenix.schema.isNamespaceMappingEnabled enabled
查询
1 | select * from SYSTEM."CATALOG"; |
查看表的 TABLE_SCHEM 发现有些表这个属性为空。 那么如果你没有指定自动映射命名空间,就会报错。
在 hbase 的 conf 目录下 hbase-site.xml
文件加入下面的属性:
1 | <property> |
然后,重启 hbase。