Skip to content

HydraQL is a SQL queryer designed based on HBase's client API, designed to simplify the use of HBase's client API. Its name "Hydra" references the Hydra, which symbolizes flexibility, versatility when dealing with HBase data. HydraQL aims to provide an intuitive and easy to use way to query and manipulate HBase databases. By using SQL syntax, user

License

Notifications You must be signed in to change notification settings

CCweixiao/HydraQL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

4cc377b · Dec 15, 2024
Aug 17, 2024
Aug 17, 2024
Aug 4, 2024
Aug 17, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Dec 15, 2024
Apr 21, 2024
Jul 15, 2024
Aug 4, 2023
Aug 17, 2024
Dec 15, 2024

Repository files navigation

🍬 HydraQL [ˈhaɪdrəQL],是基于HBase原生客户端API设计的一款SQL查询器,专为简化HBase的使用而打造。

👉 https://hydraql.com/ 👈


🌎English Documentation


📚简介

HydraQL 是基于 hbase-clinet API设计的一款SQL查询器,专为简化HBase的使用而打造。

HydraQL旨在提供一种更直观和易用的方式来查询和操作HBase数据库。通过使用SQL语法或更精简的API, 用户就可以轻松读写HBase表中的数据,而无需深入了解和编写复杂的方法调用。

与Phoenix相比,HydraQL中的SQL语法更轻量,无需引入额外的组件和配置即可使用,但目前还不支持二级索引。

🎁HydraQL的名称由来

HydraQL由Hydra + SQL 拼接而来,其名称Hydra引用了“九头蛇”,象征着在处理HBase数据时的灵活性和多功能性。 hql 是其简称,一种类SQL的语言,其在执行时,会被翻译成hbase-client的原生API来读写HBase表中的数据。

🍺HydraQL的理念

HydraQL 是HBase的衍生工具集,它融合了hql、HBatis、hbase-shell、hbase-thrift等API的功能,你可以按需引用,也可以拷贝和修改源码使用, 这并不会有什么限制,只希望能及时反馈bug,或提供更好的建议。


⚙️模块信息

项目结构:

├── LICENSE
├── README.md
├── antlr
├── bin
├── build
├── hydraql-adapter
│   ├── hydraql-adapter-core
│   ├── hydraql-adapter_1.2
│   ├── hydraql-adapter_1.4
│   ├── hydraql-adapter_2.2
├── hydraql-core
├── hydraql-console
├── hydraql-dsl
├── hydraql-examples
├── hydraql-tests
│   ├── hydraql-example
│   ├── hydraql-shell-example
│   └── spring-boot-starter-hydraql-example
├── hydraql-shell
│   ├── hydraql-shell-core
│   ├── hydraql-shell_1.2
│   ├── hydraql-shell_1.4
│   ├── hydraql-shell_2.2
├── hydraql-template
├── hydraql-thrift
└── spring-boot-starter-hydraql

核心模块介绍:

模块 介绍
hydraql-core 对一些公共方法的封装
hydraql-dsl hql的定义,以及使用antr4解析hql,并转换hbase-client的调用
hydraql-adapter 统一HBase数据读写的接口,并针对不同版本的hbase-client api进行适配和增强,屏蔽了多版本下hbase-client api不兼容
hydraql-template 依赖hydraql-adapter,对外统一暴露为模版类和模版方法
hydraql-tests 利用HBaseMiniCluster来做单元测试
spring-boot-starter-hydraql 可以利用spring-boot-starter-hydraql与Spring Boot轻松集成
hydraql-thrift 对HBase thrift API的池化和封装
hydraql-shell 对HBase Shell的封装,支持直接在java进程中执行hbase-shell的JRuby环境,可以利用该模块,封装web-hbase-shell
hydraql-console hql的命令行交互程序

🛠️功能特性

hbase-client原生API进行了统一的接口定义,屏蔽了底层API的复杂调用方式,消除了跨版本升级过程中API不兼容的问题。 在保障原有功能的同时,额外扩展了其他优秀特性,列举如下:

  • 定义了统一的接口规范,消除了不同版本hbase-clientAPI之间的差异
  • HQL,以类SQL的形式读写HBase的表中数据
  • HBatis, 类似MyBatis,提供ORM的特性,支持以注解的方式快速定义表、列簇、字段的数据模型,在保存和查询数据时,底层自动做数据类型转换
  • 对HBase的原生thrift API进行池化封装,提供了HBaseThriftPool的功能
  • 利用spring-boot-starter-hydraql可与SpringBoot无缝集成
  • 支持kerberos认证,支持kerberos认证的超级用户代理普通用户
  • 支持类似hdfs的hbase.client.hedged.read功能,在读主集群达到超时阈值或异常时,自动降级读备集群数据,此功能要求HBase主备集群互相Replication
  • hydraql-shell,把hbase-shell封装到一个jar包中,可被其他项目通过maven等方式依赖,这在你想开发hbase-web-shell的功能时非常有用
  • hydraql-console,命令行交互工具,可以同时执行hql和hbase-shell的指令,可完全替代hbase-shell来使用
  • HBatis,类似于myBatis,提供配置文件管理HQL的功能(规划中)
  • thrift 连接池中连接数的动态扩所容能力(规划中)

📝文档

📘中文文档

📙参考API

🎬视频介绍


🪙支持HydraQL

💳捐赠

如果你觉得HydraQL不错,可以请维护者吃包辣条~,在此表示感谢^_^。

赞助


📦使用指南

🍊Maven

在普通maven项目中使用,在项目的pom.xml的dependencies中加入以下内容:

<properties>
    <hydraql.hbase.adapter.version>1.2</hydraql.hbase.adapter.version>
    <!--    <hydraql.hbase.adapter.version>1.4</hydraql.hbase.adapter.version>-->
    <!--    <hydraql.hbase.adapter.version>2.2</hydraql.hbase.adapter.version>-->
</properties>

<dependency>
    <groupId>com.hydraql</groupId>
    <artifactId>hydraql-template_${hydraql.hbase.adapter.version}</artifactId>
    <version>1.0.0</version>
</dependency>

在Spring Boot项目中使用,在项目的pom.xml的dependencies中加入以下内容:

<properties>
    <hydraql.hbase.adapter.version>1.2</hydraql.hbase.adapter.version>
    <!--    <hydraql.hbase.adapter.version>1.4</hydraql.hbase.adapter.version>-->
    <!--    <hydraql.hbase.adapter.version>2.2</hydraql.hbase.adapter.version>-->
</properties>

<dependency>
    <groupId>com.hydraql</groupId>
    <artifactId>spring-boot-starter-hydraql_${hydraql.hbase.adapter.version}</artifactId>
    <version>1.0.0</version>
</dependency>

根据所需hbase的版本来指定不同的hydraql.hbase.adapter.version,目前支持的hbase版本有:1.2.x,1.4.x,2.0.x ~ 2.2.x,

更多HBase版本的支持还在持续构建中 ~

🔔️注意 最新版本的发行包可能更新不及时,同时,hydraql在构建发行包时,默认把hbase--shaded-client的依赖一起打包。 如果对hbase的版本要求强一致,可以选择修改hbase-client的版本后,自行编译安装,再在项目中引入

🍐Gradle

implementation 'com.hydraql:hydraql-template_1.2:1.0.0'
implementation 'com.hydraql:hydraql-template_1.4:1.0.0'
implementation 'com.hydraql:hydraql-template_2.2:1.0.0'

🚽编译安装

访问HydraQL的GItHub主页:https://github.com/CCweixiao/HydraQL 下载整个项目源码(master分支)然后进入HydraQL项目的根目录下执行:

sh bin/build.sh 1.2/1.4/2.2

# 默认1.2
mvn clean install -Dmaven.test.skip=true

# 1.4
mvn clean install -Dmaven.test.skip=true -Dhbase.profile=1.4

# 2.2 
mvn clean install -Dmaven.test.skip=true -Dhbase.profile=2.2

如果你想在本地进行开发,扩展额外的功能,请确保已经安装了Java8和maven3.6+,同时建议在本地部署一个可连通的HBase开发环境。 建议使用docker来快速搭建一个HBase的单机环境,可以参考博客:https://blog.csdn.net/feinifi/article/details/121174846

快速入门

@Test
public void testSaveAndGet(){
    Configuration conf = HBaseConfiguration.create();
    HBaseTableTemplate tableTemplate = HBaseTableTemplate.of(conf);

    Map<String, Object> data = new HashMap<>(2);
    data.put("f1:name", "leo");
    data.put("f1:age", 18);
    tableTemplate.save("test_table", "1001", data);
    HBaseRowData rowData = tableTemplate.getRow("test_table", GetRowParam.of("1001").build());
}

更多测试用例请参考:更多测试用例

使用手册

连接配置

普通Java项目

普通认证

// 普通认证
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "myhbase");
conf.set("hbase.zookeeper.property.clientPort", "2181");
// 请按需引入一些额外所需的客户端配置
conf.set("hbase.client.retries.number", "3");
HBaseTableTemplate tableTemplate = HBaseTableTemplate.of(conf);

或者在项目的src/main/resources目录下放入hbase-site.xml配置文件

Kerberos认证

Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "zk1,zk2,zk3");
conf.set("hbase.zookeeper.property.clientPort", "2181");
conf.set("hbase.security.authentication", "kerberos");

// 下面配置是kerberos认证方式所需
conf.set("kerberos.principal", "hbase@HADOOP.LEO.COM");
conf.set("keytab.file", "/etc/hbase/conf/hbase.keytab");
// 设置kerberos代理用户,默认为空即不进行设置,需保证hbase有代理其他用户的权限
conf.set("kerberos.proxy.user", "leojie");
conf.set("hbase.regionserver.kerberos.principal", "hbase/_HOST@HADOOP.LEO.COM");
conf.set("hbase.master.kerberos.principal", "hbase/_HOST@HADOOP.LEO.COM");
// 指定kdc服务相关的配置方式有如下两种:
// 方式一:指定krb5.conf路径
conf.set("java.security.krb5.conf", "/etc/krb5.conf");
// 方式二:指定java.security.krb5.realm和java.security.krb5.kdc
// conf.set("java.security.krb5.realm", "HADOOP.LEO.COM");
// conf.set("java.security.krb5.kdc", "你自己的kdc服务地址");
// 一些额外的客户端参数
conf.set("hbase.client.retries.number", "3");
HBaseTableTemplate tableTemplate = HBaseTableTemplate.of(conf);

Spring Boot项目

普通认证

application.yaml

spring:
  datasource:
    hbase:
      zk-quorum: zk_host1,zk_host2,zk_host3
      zk-client-port: 2181 # (可选,默认2181)
      dfs-root-dir: /hbase # (可选,默认/hbase)
      zk-node-parent: /hbase  # (可选,默认/hbase)
      security-auth-way: simple # (可选,默认simple)
      client-properties: hbase.client.retries.number=3;key1=value2
server:
  port: 8088

Kerberos认证

spring:
  datasource:
    hbase:
      zk-quorum: myhbase
      zk-client-port: 2181
      dfs-root-dir: /hbase
      zk-node-parent: /hbase
      security-auth-way: kerberos
      kerberos-principal: hbase@HADOOP.LEO.COM
      keytab-file-path: /etc/hbase/conf/hbase.keytab
      kerberos-proxy-user: test
      rs-kerberos-principal: hbase/_HOST@HADOOP.LEO.COM
      master-kerberos-principal: hbase/_HOST@HADOOP.LEO.COM
      krb5-conf-path: /etc/krb5.conf
      krb5-realm:
      krb5-kdc-server-addr:
      client-properties: hbase.client.retries.number=3
server:
  port: 8088
@Service
public class HBaseAdminService {
    @Autowired
    private BaseHBaseAdminTemplate adminTemplate;

    public List<String> allTables() {
        return adminTemplate.listTableNames();
    }
}

hydraql-template模块介绍

hydraql-template模块中封装了三类模版操作类,分别是:

  • HBaseAdminTemplate: 对Admin中方法的封装,比如:创建表,创建namespace,list表等
  • HBaseTableTemplate: 对Table中方法的封装,比如:put,get,scan,delete等
  • HBaseSqlTemplate: 提供hql的功能

UML

普通项目

// 数据读写API的操作模版类
Configuration conf = HBaseConfiguration.create();
BaseHBaseTableTemplate tableTemplate = HBaseTableTemplate.of(conf);

// Admin操作模版类
BaseHBaseAdminTemplate adminTemplate = HBaseAdminTemplate.of(conf);

// HQL操作模版类
BaseHBaseSqlTemplate sqlTemplate = HBaseSqlTemplate.of(conf);

SpringBoot项目

@Autowired 依赖注入

@Service
public class UserService {
    @Autowired
    private BaseHBaseTableTemplate tableTemplate;
    @Autowired
    private BaseHBaseAdminTemplate adminTemplate;
    @Autowired
    private BaseHBaseSqlTemplate sqlTemplate;
}

BaseHBaseAdminTemplate使用

BaseHBaseAdminTemplate封装了hbase-client中Admin的常用操作,比如namespace的创建和删除、表的创建和删除、以及快照管理等等,后续这些API将会更加完整。

admin-api

创建namespace

@Test
public void createNameSpace() {
    NamespaceDesc namespaceDesc = new NamespaceDesc();
    namespaceDesc.setNamespaceName("test_nn");
    namespaceDesc.addNamespaceProp("createdBy", "leojie");
    adminTemplate.createNamespaceAsync(namespaceDesc);
}

创建表

@Test
public void testCreateTable() {
    ColumnFamilyDesc f1 = ColumnFamilyDesc.newBuilder()
            .name("f1")
            .build();
    ColumnFamilyDesc f2 = ColumnFamilyDesc.newBuilder()
            .name("f2")
            .timeToLive(3600)
            .maxVersions(3)
            .build();
    HTableDesc tableDesc = HTableDesc.newBuilder()
            .name("leo_test_22222")
            .addFamilyDesc(f1)
            .addFamilyDesc(f2)
            .build();
    adminTemplate.createTable(tableDesc);
}

更多测试用例请参考 hydraql-tests模块

BaseHBaseTableTemplate使用

BaseHBaseTableTemplate中封装了对HBase表数据的读、写、删除等操作。

普通方式读写

@Test
public void testSaveMap() {
    Map<String, Object> data = new HashMap<>(2);
    data.put("f1:name", "leo");
    data.put("f1:age", 18);
    tableTemplate.save(TEST_TABLE, "1001", data);
    HBaseRowData rowData = tableTemplate.getRow(TEST_TABLE, GetRowParam.of("1001").build());
    Assert.assertEquals(2, rowData.getColDataContainer().size());
}

ORM特性

  1. 创建数据模型类
public class CityTag {
    private String tagName;

    public CityTag(String tagName) {
        this.tagName = tagName;
    }
		// 省略Getter/Setter/toString
}
@HBaseTable(namespaceName = "default", tableName = "test_table", defaultFamilyName = "f1")
public class CityModel {
    @HBaseRowKey
    private String cityId;
    private String cityName;
    private String cityAddress;
    @HBaseColumn(familyName = "detail")
    private Integer cityArea;
    @HBaseColumn(familyName = "detail", toUpperCase = true)
    private Integer totalPopulation;
    @HBaseColumn(familyName = "detail", columnName = "cityTagList")
    private List<CityTag> cityTagList;
  	// 省略Getter/Setter/toString
}

@HBaseTable注解用于定义HBase的表信息

@HBaseTable(namespaceName = "default", tableName = "t2", defaultFamilyName = "info")

1)namespaceName:用于指定该表的命名空间,默认:default 2)tableName:用于指定该表的表名,如果不指定,表名则为类名的组合单词拆分转小写加'_'拼接,如:CityModel对应的表名为:city_model。 3)defaultFamilyName:用于定义如果有字段不特配置(@HBaseRowKey注解中的familyName)列簇名,则使用此处配置的列簇名。

@HBaseRowKey注解用于定义某一个属性字段是用作存储rowKey数据的,是必须要设置的,如:

@HBaseRowKey
private String cityId;

该注解表示cityId字段为rowKey,每一个模型类必须,也只能有一个字段被标识为rowKey。

@HBaseColumn注解用于定义HBase的列簇和列名信息,如:

@HBaseColumn(familyName = "detail", columnName = "TOTAL_POPULATION",  toUpperCase = true)
private Integer totalPopulation;

1)familyName:指定列簇名,不指定,则使用defaultFamilyName配置的列簇名。 2)columnName:指定列名,不指定则默认使用字段名的组合单词拆分转小写加'_'拼接,如:isVip,对应的字段名是:is_vip 3)toUpperCase:定义字段名是否转大写,如:isVip -> IS_VIP,默认值:false,不做转换。

  1. 存取数据
@Test
public void testSave() {
    CityModel cityModel = CityModelUtil.createDefaultCityModel();
    tableTemplate.save(cityModel);
    GetRowParam getRowParam = GetRowParam.of(cityModel.getCityId()).build();
    Optional<CityModel> cityModelRes = tableTemplate.getRow(getRowParam, CityModel.class);
    Assert.assertNotNull(cityModelRes);
}
  1. 批量存取数据
@Test
public void testSaveBatch() {
    List<CityModel> cityModelList = CityModelUtil.createDefaultCityModelList();
    tableTemplate.saveBatch(cityModelList);
    List<String> rowKeys = cityModelList.stream().map(CityModel::getCityId).collect(Collectors.toList());
    GetRowsParam getRowsParam = GetRowsParam.of().rowKeyList(rowKeys).build();
    List<CityModel> rows = tableTemplate.getRows(getRowsParam, CityModel.class);
    Assert.assertEquals(rowKeys.size(), rows.size());
}
  1. 查询数据使用自定义的RowMapper解析字段
@Test
public void testGetByRowMapper() {
    GetRowParam getRowParam = GetRowParam.of("a10001").build();
    Map<String, String> data = tableTemplate.getRow(TEST_TABLE, getRowParam, new RowMapper<Map<String, String>>() {
        @Override
        public <R> Map<String, String> mapRow(R r, int rowNum) throws Exception {
            Result result = (Result) r;
            if (result == null) {
                return new HashMap<>(0);
            }
            Map<String, String> data = new HashMap<>(2);
            for (Cell cell : result.listCells()) {
                data.put(Bytes.toString(CellUtil.cloneFamily(cell)) + ":" +Bytes.toString(CellUtil.cloneQualifier(cell)),
                        Bytes.toString(CellUtil.cloneValue(cell)));
            }
            return data;
        }
    }).orElse(new HashMap<>(0));
    Assert.assertEquals(5, data.size());
}
  1. scan查询,自定义Filter
@Test
public void testScanWithCustomFilter() {
    testSaveBatch();
    ScanParams scanParams = ScanParams.of()
            .filter(new IHBaseFilter<Filter>() {
                @Override
                public Filter customFilter() {
                    List<Filter> filters = new ArrayList<>(2);
                    // 筛选row key 大于b20001的数据
                    Filter rowFilter = new RowFilter(CompareFilter.CompareOp.GREATER,
                            new BinaryComparator("b20001".getBytes()));
                    // 筛选列前缀city_address的数据
                    ColumnPrefixFilter columnPrefixFilter = new ColumnPrefixFilter(Bytes.toBytes("city_address"));
                    // 筛选列值与深圳市相等的数据
                    ValueFilter valueFilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("深圳市")));
                    // 多过滤器,注意顺序
                    filters.add(rowFilter);
                    filters.add(columnPrefixFilter);
                    filters.add(valueFilter);
                    // 需所有条件全部通过
                    FilterList andFilterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, filters);
                    // 满足其中一个条件即可
                    FilterList orFilterList = new FilterList(FilterList.Operator.MUST_PASS_ONE, filters);
                    return andFilterList;
                }
            })
            .build();
    List<CityModel> cityModels = tableTemplate.scan(scanParams, CityModel.class);
    Assert.assertEquals(1, cityModels.size());
}
  1. 多版本查询

使用HBaseRowDataWithMultiVersions结构来接收多版本数据

@Test
public void testGetMultiVersions() throws InterruptedException {
    Map<String, Object> data1 = new HashMap<>(3);
    tableTemplate.save(TEST_TABLE, "b1", data1);
    Map<String, Object> data2 = new HashMap<>(3);
    tableTemplate.save(TEST_TABLE, "b1", data2);
    Map<String, Object> data3 = new HashMap<>(3);
    tableTemplate.save(TEST_TABLE, "b1", data3);
    Map<String, Object> data4 = new HashMap<>(3);
    tableTemplate.save(TEST_TABLE, "b1", data4);
    Map<String, Object> data5 = new HashMap<>(3);
    tableTemplate.save(TEST_TABLE, "b1", data5);
    // 省略数据构造过程
    GetRowParam getRowParam = GetRowParam.of("b1").versions(5).build();
    HBaseRowDataWithMultiVersions rowData = tableTemplate.getWithMultiVersions(TEST_TABLE, getRowParam);
    Assert.assertEquals(3, rowData.getColDataWithMultiVersions().size());
    Assert.assertEquals(4, rowData.getColDataWithMultiVersions().get("info:name").size());
}

HQL

使用前首先构造BaseHBaseSqlTemplate

Configuration conf = HBaseConfiguration.create();
BaseHBaseSqlTemplate sqlTemplate = HBaseSqlTemplate.of(conf);

1. 创建表schema

使用create virtual table语句来创建表的schema,如果HBase集群中没有表HQL.META_DATA,会先创建,然后把表解析出来的 表模型HBaseTableSchema对象,以json的格式存储在这张元数据表中,之后每次select或insert时,加载出表schema的元数据。

@Test
public void testCreateVirtualTable) {
    String hql = "create virtual table test:test_sql (\n" +
            " row_key string isrowkey,\n" +
            " f1:id string nullable,\n" +
            " f1:name string nullable,\n" +
            " f1:age int nullable,\n" +
            " f1:job string nullable,\n" +
            " f1:pay double nullable,\n" +
            " f2:address string nullable,\n" +
            " f2:commuter string nullable\n" +
            " );";
    sqlTemplate.createVirtualTable(hql1);`
}

virtualTable的名称要与hbase的实际表名一致,且只能存在一个。 也可以选择在执行HQL前调用sqlTemplate.registerTableSchema方法来手动注册某张表的Schema,只有注册成功表的Schema之后,才能使用hql。

打印schema

printSchema

2. 删除表的schema

String hql = "drop virtual table test:test_sql;";
sqlTemplate.dropVirtualTable(hql2);

删除虚拟表的操作,不会对HBase的原表产生任何影响。

3. Insert

插入一条数据

insert into test:test_sql (row_key, f1:id , f1:name , f1:age ) values ('r1', 'id1_v1' , 'leo1_v1' , 11 )

插入多条数据

insert into test:test_sql (row_key, f1:id , f1:name , f1:age )
values ('r1', 'id1_v1' , 'leo1_v1' , 11 ),
('r2', 'id2_v1' , 'leo2_v1' , 21 ),
('r3', 'id3_v1' , 'leo3_v1' , 31 )

插入数据时,使用内置的rowKey自定义函数

insert into test:table ( f:id , f:name,
                 f:age, f2:pay, f3:detail) VALUES(md5('1001'),'张三', 23.32,null )

4. Select

select * from test:test_sql where rowKey = 'a10001'

select_by_row

select * from test:test_sql where rowKey in ( 'a10001' , 'a10002' , 'a10003' )

in_row_keys

4. Delete

delete * from test:test_sql where rowKey = 'b20004';
delete f1:age from test:test_sql where rowKey = 'b20004'

🏗️添砖加瓦

🎋分支说明

HydraQL的源码分为两个分支,功能如下:

分支 作用
master 主分支,release版本使用的分支,与中央库提交的jar一致,不接收任何pr或修改
dev 开发分支,默认为下个版本的SNAPSHOT版本,接受修改或pr

🐞提供bug反馈或建议

提交问题反馈时请说明正在使用的JDK版本、HydraQL版本和相关依赖库的版本。

🧬贡献代码的步骤

  1. 在Gitee或者Github上fork项目到自己的repo
  2. 把fork过去的项目也就是你的项目clone到你的本地
  3. 修改代码(记得一定要修改dev分支)
  4. commit后push到自己的库(dev分支)
  5. 登录Gitee或Github在你首页可以看到一个 pull request 按钮,点击它,填写一些说明信息,然后提交即可。
  6. 等待维护者合并

📐PR遵照的原则


⭐Star HydraQL

📌 知识星球

About

HydraQL is a SQL queryer designed based on HBase's client API, designed to simplify the use of HBase's client API. Its name "Hydra" references the Hydra, which symbolizes flexibility, versatility when dealing with HBase data. HydraQL aims to provide an intuitive and easy to use way to query and manipulate HBase databases. By using SQL syntax, user

Resources

License

Stars

Watchers

Forks

Packages

No packages published