phoenix 01 (概述,安装,连接方式,增删改查,schema操作,映射)

phoenix是什么?

  1. phoenix目前是apache旗下的一款开源工具
  2. phoenix是构建在hbase层之上的一个sql层,使用标准的sql语言对hbase进行操作
  3. sql会被翻译成hbase的API,比如扫描对象Scan,过滤器Filter等
  4. phoenix适合做OLAP的工作(不适合做OLTP)

为什么要学?(特点)

phoenix虽然是构建在hbase层之上,但是由于以下特点,不会影响查询性能,反而会提高性能

  • 编译SQL查询为原生HBase的scan语句
  • 检测scan语句最佳的开始和结束的key
  • 精心编排你的scan语句让他们并行执行
  • 让计算去接近数据
  • 推送你的WHERE子句的谓词到服务端过滤器处理
  • 执行聚合查询通过服务端钩子(称为协同处理器)

phoenix还提供了一些增强优化性能

  • 实现了二级索引来提升非主键字段查询的性能
  • 统计相关数据来提高并行化水平,并帮助选择最佳优化方案
  • 跳过扫描过滤器来优化IN,LIKE,OR查询
  • 优化主键来均匀分布写压力

phoenix不能做的事情

  • 不支持事务处理
  • 不支持复杂的条件

phoenix安装

1、上传、解压、更名、环境变量
2、将phoenix目录下的phoenix-4.13.1-HBase-1.2-client.jar 和phoenix-core-4.13.1-HBase-1.2.jar两个jar包拷贝到hbase下的lib目录下,要分发到集群其他机器上
3、配置hbase-site.xml
添加以下内容:

<property> 
    <name>phoenix.schema.isNamespaceMappingEnabled</name> 
    <value>true</value> 
</property> 
<property> 
    <name>phoenix.schema.mapSystemTablesToNamespace</name> 
    <value>true</value> 
</property>
<property>
    <name>hbase.table.sanity.checks</name>
    <value>false</value>
</property>

hbase-site.xml也要分发到集群其他机器上
4、配置phoenix的bin下的hdfs-site.xml(可以用hbase下的hbase-site.xml覆盖,也可自己配置,将上面的配置添加进去即可)
5、启动即可(sqlline.py)

出现的错误:

启动phoenix时提示以下错误,(phoenix可以正常进去,但不能使用。不能查看表等等)

Error: ERROR 726 (43M10):  Inconsistent namespace mapping properties.. Ensure that config phoenix.schema.isNamespaceMappingEnabled is consitent on client and server. (state=43M10,code=726)

解决办法:
将配置完毕的hbase-site.xml分发到其他节点上。

phoenix的四种操作方式

命令行方式

使用 sqlline.py脚本登录到phoenix的客户端
在此界面使用hlep命令就可以看到phoenix所有的操作命令

批处理方式

指的是在linux命令行使用 psql.py [zookeeper host:port] filename 方式将文件中的命令以phoenix执行

例如:

1)创建表

首先创建createtable.sql文件,里面添加l两个建表语句,表名分别是us_population和ak_population

[root@qianfeng01 phoenix]# vi ./sql/createtable.sql

CREATE TABLE IF NOT EXISTS us_population (
state CHAR(2) NOT NULL,
city VARCHAR NOT NULL,
population BIGINT
CONSTRAINT my_pk PRIMARY KEY (state, city)
);


CREATE TABLE IF NOT EXISTS ak_population (
state CHAR(2) NOT NULL,
city VARCHAR NOT NULL,
population BIGINT
CONSTRAINT my_pk PRIMARY KEY (state, city)
);
2)创建表对应的数据文件

接下来新建一个数据文件us_population.csv

要加载的所有CSV文件都必须具有".csv"文件扩展名,同样phoenix也支持mr做一个批量数据导入,主键就是hbase对应的rowkey,为了保证hbase主键的唯一性,可以设置多个字段为主键。

注意: 根据文件名称来找对应的表名

[root@qianfeng01 phoenix]# vi ./sql/us_population.csv

NY,New York,8143197
CA,Los Angeles,3844829
IL,Chicago,2842518
TX,Houston,2016582
PA,Philadelphia,1463281
AZ,Phoenix,1461575
TX,San Antonio,1256509
CA,San Diego,1255540
TX,Dallas,1213825
CA,San Jose,912332

创建一个ak.csv
通过-t参数指定表名

[root@qianfeng01 phoenix]# vi ./sql/ak.csv

AK,kenai,450283
AK,haines,370283
AK,fairbanks,390283
3)执行批处理

执行命令为:psql.py [zkserver:port] filepath……

-- 可以使用批处理命令,来执行多个文件
[root@qianfeng01 phoenix]# psql.py  ./sql/createtable.sql ./sql/us_population.csv 


-- 会出现异常,因为在导入数据时,文件名必须要和表名一致。
[root@qianfeng01 phoenix]# psql.py ./sql/ak.csv
java.lang.IllegalArgumentException: Table AK not found
   
-- 更名后,再次导入   
[root@qianfeng01 phoenix]# mv ./sql/ak.csv  ./sql/ak_population.csv
[root@qianfeng01 phoenix]# psql.py ./sql/ak_population.csv

--在phoenix命令行上检查表的数据
select * from us_population;
select * from ak_population;

4)创建查询语句

创建一个查询sql文件queries.sql

[root@qianfeng01 phoenix]# vi ./sql/queries.sql

SELECT state as "State",count(city) as "City Count",sum(population) as "Population Sum"
FROM us_population
GROUP BY state
ORDER BY sum(population) DESC;

执行命令为:psql.py [zkserver:port] filepath……

[root@qianfeng01 phoenix]# psql.py ./sql/queries.sql

ST CITY                                                                   POPULATION
-- ---------------------------------------- ----------------------------------------
AK fairbanks                                                                  390283
AK haines                                                                     370283
AK kenai                                                                      450283
Time: 0.067 sec(s)

ST CITY                                                                   POPULATION
-- ---------------------------------------- ----------------------------------------
AZ Phoenix                                                                   1461575
CA Los Angeles                                                               3844829
CA San Diego                                                                 1255540
CA San Jose                                                                   912332
IL Chicago                                                                   2842518
NY New York                                                                  8143197
PA Philadelphia                                                              1463281
TX Dallas                                                                    1213825
TX Houston                                                                   2016582
TX San Antonio                                                               1256509
Time: 0.036 sec(s)

注意:

1、通过Phoenix建的表都会自动转成大写,如果需要使用小写的表,请使用create table “tablename”

2、安装了Phoenix之后,系统会自动生成四张系统表

3、在Phoenix中创建的表同时会在HBase中创建一张表与之对应,并且需要使用psql.py脚本加载数据

jdbc连接方式

通过IDEA连接
phoenix能支持sql语句,同样我们也可以使用jdbc来连接phoenix发送sql语句操作hbase。

引入phoenix的依赖


    <!--加入phoenix的相关依赖-->
    <dependencies>
		<dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>4.13.1-HBase-1.2</version>
        </dependency>
    </dependencies>
</project>

查询代码

package edu.qf;

import java.sql.*;
import java.util.Properties;

/**
 * 使用phoenix的api操作
 */
public class PhoenixJDBC {
    //定义驱动类
    private static final String phoenix_driver = "org.apache.phoenix.jdbc.PhoenixDriver";
    public static void main(String[] args) {
        //定义conn、语句、结果集
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //加载驱动
            Class.forName(phoenix_driver);
            //client端配置Namespace属性,否则会报错,因为服务端配置咯的
            Properties pro = new Properties();
            pro.setProperty("phoenix.schema.isNamespaceMappingEnabled","true");
            //获取连接
            conn = DriverManager.getConnection("jdbc:phoenix:qianfeng01,qianfeng02,qianfeng03:2181",
                    pro);
            //定义sql
            String sql = "select * from US_POPULATION";
            ps = conn.prepareStatement(sql);
            //执行
            rs = ps.executeQuery();
            //取值
            while (rs.next()){
                System.out.println(rs.getString(1)+"\t"+rs.getString(2)
                +"\t"+rs.getString(3));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            try {
                conn.close();
                ps.close();
                rs.close();
            } catch (SQLException e) {
                //do nothing
            }
        }
    }
}

查询结果

在这里插入图片描述

GUI方式

不好用,不说了

phoenix的数据操作

支持的数据类型

数据类型Java Map占用大小范围 (byte)
INTEGERjava.lang.Integer4-2147483648 to 2147483647
UNSIGNED_INTjava.lang.Integer40 to 2147483647
BIGINTjava.lang.Long8-9223372036854775807 to 9223372036854775807
UNSIGNED_LONGjava.lang.Long80 to 9223372036854775807
TINYINTjava.lang.Byte1-128 to 127
UNSIGNED_TINYINTjava.lang.Byte10 to 127
SMALLINTjava.lang.Short2-32768 to 32767
UNSIGNED_SMALLINTjava.lang.Short20 to 32767
FLOATjava.lang.Float4-3.402823466 E + 38 to 3.402823466 E + 38
UNSIGNED_FLOATjava.lang.Float40 to 3.402823466 E + 38
DOUBLEjava.lang.Double8-1.7976931348623158 E + 308 to 1.7976931348623158 E + 308
UNSIGNED_DOUBLEjava.lang.Double80 to 1.7976931348623158 E + 308
DECIMALjava.math.BigDecimalDECIMAL(p,s)
BOOLEANjava.lang.Boolean1TRUE and FALSE
TIMEjava.sql.Time8yyyy-MM-dd hh:mm:ss
DATEjava.sql.Date8yyyy-MM-dd hh:mm:ss,
TIMESTAMPjava.sql.Timestamp12yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]
UNSIGNED_TIMEjava.sql.Time8yyyy-MM-dd hh:mm:ss
UNSIGNED_DATEjava.sql.Date8yyyy-MM-dd hh:mm:ss
UNSIGNED_TIMESTAMPjava.sql.Timestamp12
VARCHARjava.lang.StringVARCHAR(n)
CHARjava.lang.StringCHAR (n)
BINARYbyte[]BINARY(n)
VARBINARYbyte[]VARBINARY
ARRAYjava.sql.ArrayVARCHAR ARRAY

请移步http://phoenix.apache.org/language/datatypes.html 测试
但是实际使用中,建议如果要关联已有的HBase表,最好直接使用VARCHAR类型

表的DDL

--建表语句案例:
create table student(
id integer primary key,
name varchar(20),
age integer,
salary double
);
create table teacher(
id integer not null,
name varchar(20) not null,
age integer,
salary double,
constraint pk_id_name primary key(id,name)
)

--删除表
drop table [if exists] student1;

--自己测试是否支持修改表结构 已经验证:支持
语法:alter table tableName add colName type;


注意事项: 
	(1)建表语句必须有主键约束,hbase会将带有主键约束的字段映射成rowkey字段
	(2)如果是联合主键,那么字段后面要有非空约束。
    (3)如果不指定schame,会将表映射到hbase的default命名空间下

表的插入

phoenix的插入关键语句是 upsert into 或者upsert into……. select ………….

案例演示:
upsert into student values(1001,'zhangsan',23,1000.0);
upsert into student (id,name,age)values(1002,'lisi',24);
upsert into student (id,name,age,salary)values(1003,'wangwu',25,1100.0);
upsert into student (id,name,age,salary)values(1004,'zhaoliu',25,1100.0);

案例演示:要插入的数据来源于另外一张表
create table student1(
id integer primary key,
name varchar(20),
age integer,
salary double
);
upsert into student1 select * from student;
upsert into student1(id,name,age) select id,name,age from student where id>1002;

注意事项:
	主键约束的字段一定要有值。
	多次插入操作,如果主键字段的值相同,其实是hbase的覆盖操作。

表的数据修改

因为phoenix是在建立hbase之上的,所有phoenix的修改就是upsert into  对应hbase的插入和修改都是put.

案例演示:修改id为1003的姓名为wangwu1,年龄为20
upsert into student1 (id,name,age) values(1003,'wangwu1',20);

表的查询操作

1. 基本查询语法与mysql一致。
2. 支持where子句
3. 支持group by 子句
4. 支持having 子句
5. 支持order by子句
6. 支持limit子句,但是只能有一个参数,表示从第一条查询n条。
7. 支持[not]in、like
8. 支持union all,不支持去重。
9. 支持子查询(可以在from中,where中)  在hiving中使用比较符号语法没有错误,但是条件不起作用。

表的数据删除

使用delete关键字,和mysql语法一致。

Phoenix的Schema

说明

在phoenix4.8版本以后,引入了Schema概念,映射的是Hbase的namespace. 当然如果想要生效,那么必须在hbase框架和phoenix框架中的hbase-site.xml中配置以下两个属性:
phoenix.schema.isNamespaceMappingEnabled = true
hoenix.schema.mapSystemTablesToNamespace = true

schema的应用

-- 创建一个schema
create schema  schemaName     <--- schemaName,要么加双引号,要么不加,不加会自动转为大写。

create schema "ns2"
create schema ns2     ns2和“ns2”是两个schema,在hbase中对应两个namespace


-- 在schema下创建表:   在ns2下创建表名为小写的s1的表。
create table ns2."s1"(
id integer primary key,
name varchar(20)
);
create table ns2.s1(
id integer primary key,
name varchar(20)
);
create table "ns2".S1(
id integer primary key,
name varchar(20)
);
create table "ns2"."s1"(
id integer primary key,
name varchar(20)
);

注意:如果没有指定列族名,那么在hbase中对应的列族名为0.  建表时可以指定列族名

--在schema下创建表,同时指定列族名
create table "ns2"."s2"(
id integer primary key,
"base".name varchar(20)
);
upsert into "ns2"."s2" values(1001,'zhangsan');



create table "ns2"."s3"(
id integer primary key,
"base".name varchar(20),
"base"."age" INTEGER,
"f1"."province" varchar(20),
"f1"."city" varchar(20)
)
column_encoded_bytes=0;

upsert into "ns2"."s3" values(1001,'zhangsan',23,'guangdong','深圳');

注意:建表时带上column_encoded_bytes=0,在hbase中可以将key解析成字符串。

表的映射

指先在hbase中创建的表,Phoenix中是看不到的,如果想要在phoenix看到,那么必须做映射关系操作。

如何映射表???????????
在phoenix中创建一张表
(1)表名必须相同,如果有命名空间,那么在phoenix中必须要有schema与之映射
(2)表中必须要有主键,rowkey会自动与主键字段进行映射,主键字段名可以是row,也可以是其他名称
(3)表的列名前必须要有列族名与hbase的列族名一致。
(4)字段的类型一定要一致。
(5)高版本虽然可以不加此属性column_encoded_bytes=0,但是建议在做映射时,要加上。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值