Apache Phoenix 4.7中Upsert带Row Timestamp行的语法示例及错误解决
解决Phoenix带ROW_TIMESTAMP的Upsert语法问题
首先,你遇到的TypeMismatchException是因为ROW_TIMESTAMP对应的列类型必须是BIGINT(或可隐式转换为BIGINT的类型),但你把CREATED_DATE定义成了DATE类型。Phoenix自动填充的行时间戳是毫秒级的BIGINT值,无法直接转换为DATE类型,所以触发了类型不匹配错误。
下面给你两种可行的解决方案,对应不同的需求场景:
方案1:将ROW_TIMESTAMP列设为BIGINT类型(推荐,贴合HBase时间戳本质)
首先调整表结构,把CREATED_DATE改为BIGINT类型,同时标记为ROW_TIMESTAMP:
CREATE TABLE DESTINATION_METRICS_TABLE ( CREATED_DATE BIGINT NOT NULL, METRIC_ID CHAR(15) NOT NULL, METRIC_VALUE LONG, CONSTRAINT PK PRIMARY KEY(CREATED_DATE ROW_TIMESTAMP, METRIC_ID) ) SALT_BUCKETS = 8;
此时Upsert有两种写法:
- 写法1:不指定
CREATED_DATE,让Phoenix自动填充当前服务器的毫秒时间戳作为行时间戳:
UPSERT INTO DESTINATION_METRICS_TABLE (METRIC_ID, METRIC_VALUE) VALUES (?, ?);
这种写法下,CREATED_DATE会自动被设置为Phoenix服务器当前的时间戳(BIGINT类型),同时作为HBase行的时间戳。
- 写法2:显式指定自定义的时间戳(比如你自己生成的毫秒时间):
UPSERT INTO DESTINATION_METRICS_TABLE (CREATED_DATE, METRIC_ID, METRIC_VALUE) VALUES (1620000000000, ?, ?);
方案2:保留DATE类型列,同时使用ROW_TIMESTAMP
如果你确实需要CREATED_DATE为DATE类型,可以额外加一个BIGINT类型的列作为ROW_TIMESTAMP,然后用默认值同步时间:
CREATE TABLE DESTINATION_METRICS_TABLE ( TS BIGINT NOT NULL ROW_TIMESTAMP, CREATED_DATE DATE NOT NULL DEFAULT CURRENT_DATE, METRIC_ID CHAR(15) NOT NULL, METRIC_VALUE LONG, CONSTRAINT PK PRIMARY KEY(TS, METRIC_ID) ) SALT_BUCKETS = 8;
此时Upsert时可以只指定业务列,TS会自动填充当前服务器时间戳,CREATED_DATE会自动填充当前日期:
UPSERT INTO DESTINATION_METRICS_TABLE (METRIC_ID, METRIC_VALUE) VALUES (?, ?);
补充说明
- ROW_TIMESTAMP标记的列会直接映射到HBase的行时间戳,这个列的值必须是BIGINT(因为HBase时间戳是64位整数)。
- 如果需要DATE类型的时间展示,建议在查询时将BIGINT时间戳转换为DATE,比如:
SELECT TO_DATE(CREATED_DATE), METRIC_ID, METRIC_VALUE FROM DESTINATION_METRICS_TABLE;
内容的提问来源于stack exchange,提问作者Amateur
相关产品推荐
相关产品推荐

