Phoenix使用场景
第一种:单单的访问hbase中的数据,视图映射(只读的,删除视图对hbase中的表无影响)和表映射(通过phoenix的表查hbase中表的数据,删除phoenix表,hbase中的表也会被删除)
第二种场景:Phoenix建库建表插入数据,把hbase当存储系统
连接客户端
配置phoenix需要把phoenix的一个jar包放到hbase的lib目录下并且分发到每一个节点:
cp /opt/module/phoenix/phoenix-5.0.0-HBase-2.0-server.jar /opt/module/hbase/lib/
复制完之后重启,否则不会起作用。
连接 thick 客户端
thick客户端连接的是zookeeper
sqlline.py hadoop102,hadoop103,hadoop104:2181
phoenix中没有database,有的是schema,相当于mysql中的数据库
create schema bigdata
会出现以下错误
原因是需要在hbase的conf目录中的hbase-site.xml配置一个参数:
此参数是phoenix的schema和hbase的nameSpace命名空间做映射。
phoenix.schema.isNamespaceMappingEnabled将它设置成true
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
同时在phoenix/binhbase-site.xml文件中添加参数设置:
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
再次创建schema:
注意:schema “test” 加双引号映射到hbase会是小写的,不加双引号默认都是大写的
create schema "test"
或者:
create schema IF NOT EXIST "test"
在hbase的shell客户端询数据数据库:
list_namespace
创建成功:
表的操作
1.显示所有的表:
phoenix客户端:
! table 或者 ! tables
2.创建表:必须指定单个列作为主键,映射到hbsase中的rowkey
2.1主键:
CREATE TABLE IF NOT EXISTS student(
id VARCHAR primary key,
name VARCHAR,
addr VARCHAR);
插入一条数据:
upsert into STUDENT values('1001','lisi','beijing')
hbase客户端查看结果:
这里的value=x是涉及到phoenix的null值问题
如果name和addr是null ,那么存在hbase中就只有rowkey,如果没有第一行数据,在hbase中就没有任何信息,是为了把phoenix中的null值和hbase中统一
phoenix查看:
2.2联合主键
指定多个列的联合作为rowkey
CREATE TABLE IF NOT EXISTS "test3"(name varchar,age varchar,address varchar CONSTRAINT my_lk PRIMARY KEY (name,age));
upsert into "test1" values('zhangsan','20','beijing');
结果:蓝色字体表示主键
hbase端:从插入数据的结果来看,联合主键只有一条数据,是把两个作为主键的列拼接到了一起,形成rowkey
关于数据类型
用phoenix
CREATE TABLE "test5" (name varchar PRIMARY KEY,addr varchar,age UNSIGNED_LONG);
插入数据:
upsert into "test5" values('zhangsan','beijing',26);
结果:
hbase端:
hbase底层字符串类型存储的是字节数组,对于数字类型存储的是补码,但是存的也不是标准的 补码。那就说一下phoenix关于数据类型的一些坑:
Phoenix插入数据都要序列化,因为hbase中底层存放的是字节数组,对于表映射,如果数据不是phoenix写的,就不是phoenix 进行的序列化,那phoenix要读已经存在的数据时,需要反序列化,可能反序列化不是用的Bytes工具类,最终反序列化的结果可能不对。主要集中体现在数字类型的数据上(比如:int long )
问题演示:
在hbase中创建表添加数据,phoenix创建映射表,查看数据
这里默认的是long类型的:
Create ‘popu’,’info’
Put ‘popu’,’1001’,’info:cnt’,Bytes.toBytes(12345)里边的参数是Long类型的
Scan ‘popu’
数字类型底层存放入是数据的补码
在phoenix中建表关联一下:
Create table “popu”(id varchar primary key,”info”.”cnt” INTEGER) column_encode_bytes=0
Hbase存数字存的是补码。Phoenix存的不是标准的补码,而是将标准的补码的符号位给置换了一下,如果是0,就给置换成了1.phoenix为了保证所有的正数在表的前边就做了反转。
解决办法:
方法一:
如果hbase中所有数据都是正数,没有负数,在phoenix建表的时候声明成UNSIGNED_INT(无符号的对应类型,反序列化用的就是Bytes.toBytes)
Create table “popu”(id varchar primary key,”info”.”cnt” UNSIGNED_LONG) column_encode_bytes=0
第二种方法:
如果有负数,只能通过phoenix的自定义函数,拿到hbases的字节数组,手动的把符号位转变一下。
列的编码
使用列名编码:
CREATE TABLE "test5" (addr varchar,age varchar,score Long);
0就是列族的名,\x80\x0B两位十六进制,是为了减少hbase列名对磁盘空间的占用,column_encode_bytes=1这个参数就会把列名映射成数字,1代表最多可创建255个列,0或者none表示不使用列名编码,不同的数字表示最多创建的列的个数不同,实际选择要考虑自己表中的列数有几个,按需选择在这里插入图片描述](https://img-blog.csdnimg.cn/20200624203847563.png)
不使用列名编码:
create table "qq2"(addr varchar primary key,age varchar,score varchar) column_encode_bytes=0;
视图映射&表映射
phoenix的视图映射对hbase中的表是只读的,删除视图不会删除hbase中的表。而表映射在phoenix中删除,hbase中的表也会被删除。
视图映射:
create view "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar);
表映射:
create table "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar);