Doris数据模型

2021-09-08 15:55:11 浏览数 (1)

列可以分为两大类:Key 和 Value。从业务角度看,Key 和 Value 可以分别对应维度列和指标列。

Apache Doris主要有3种数据模型:

  • 明细模型:Duplicate(重复,复制)模型,表中的Key值(类似关系模型中的主键)可以重复,和插入数据行一一对应。
  • 聚合模型:Aggregate(聚合,合计)模型,表中key值不重复,对于插入的数据数据按照key值对value值进行聚合函数合并。
  • 更新模型:UNIQUE 模型,聚合类型的特殊情况,key满足唯一性,最新插入的数据替换掉对应key的数据行。

1、明细模型(Duplicate)

1.1 说明
  • 明细模型是 DORIS 默认使用的数据模型
  • 该数据模型不会对导入的数据进行任何处理,保留导入的原始数据
  • 明细模型中, 可以指定部分的维度列为排序键; 而聚合模型和更新模型中, 排序键只能是全体维度列
  • 事实表中一类事务事实表,用于存储随业务不断产生的数据,一旦产生不再变化。例如交易流水、操作日志、出库入口记录等。这类需求,推荐使用明细模型。
1.2 样例测试

(1)表结构

ColumnName

Type

SortKey

Comment

visitor_id

INT

Y

访问者ID

session_id

INT

Y

会话ID

client_ip

CHAR(32)

客户端IP

city

CHAR(32)

城市

(2)建表语句

代码语言:javascript复制
CREATE TABLE IF NOT EXISTS test.session_log
(
	visitor_id INT NOT NULL COMMENT "访问者ID",
    session_id INT NOT NULL COMMENT "SessionID",
	client_ip CHAR(32) NOT NULL COMMENT "客户端IP",
    city CHAR(32) NOT NULL COMMENT "城市"
)
DUPLICATE  KEY(visitor_id,session_id)
DISTRIBUTED BY HASH(visitor_id) BUCKETS 8
PROPERTIES ("replication_num"="1");

说明:建表语句中指定的 DUPLICATE KEY,只是用来指明底层数据按照那些列进行排序。

代码语言:javascript复制
mysql> CREATE TABLE IF NOT EXISTS test.session_log
    -> (
    ->     visitor_id INT NOT NULL COMMENT "访问者ID",
    ->     session_id INT NOT NULL COMMENT "SessionID",
    ->     client_ip CHAR(32) NOT NULL COMMENT "客户端IP",
    ->     city CHAR(32) NOT NULL COMMENT "城市"
    -> )
    -> DUPLICATE  KEY(visitor_id,session_id)
    -> DISTRIBUTED BY HASH(visitor_id) BUCKETS 8
    -> PROPERTIES ("replication_num"="1");
Query OK, 0 rows affected (0.01 sec)

(3)插入测试数据

代码语言:javascript复制
mysql> insert into test.session_log values(1,1,'192.163.9.101','shanghai');
Query OK, 1 row affected (0.05 sec)
{'label':'insert_c36ae31ecb8549ef-923daa82fda8dc78', 'status':'VISIBLE', 'txnId':'235'}

mysql> insert into test.session_log values(1,1,'192.163.9.101','shanghai');
Query OK, 1 row affected (0.06 sec)
{'label':'insert_fcad117e62e84ee7-908fc1e118b13368', 'status':'VISIBLE', 'txnId':'236'}

mysql> select * from test.session_log;
 ------------ ------------ --------------- ---------- 
| visitor_id | session_id | client_ip     | city     |
 ------------ ------------ --------------- ---------- 
|          1 |          1 | 192.163.9.101 | shanghai |
|          1 |          1 | 192.163.9.101 | shanghai |
 ------------ ------------ --------------- ---------- 
2 rows in set (0.03 sec)

mysql> insert into test.session_log values(1,2,'192.163.100.10','beijing');
Query OK, 1 row affected (0.04 sec)
{'label':'insert_fde1a90815f64a1d-a3e48a02ebce7bc6', 'status':'VISIBLE', 'txnId':'237'}

mysql> select * from test.session_log;
 ------------ ------------ ---------------- ---------- 
| visitor_id | session_id | client_ip      | city     |
 ------------ ------------ ---------------- ---------- 
|          1 |          1 | 192.163.9.101  | shanghai |
|          1 |          1 | 192.163.9.101  | shanghai |
|          1 |          2 | 192.163.100.10 | beijing  |
 ------------ ------------ ---------------- ---------- 
3 rows in set (0.01 sec)

mysql> 

2、聚合模型(Aggregate)

2.1 说明
  • 聚合模型需要用户在建表时显式的将列分为 Key 列和 Value 列。
  • 该模型会自动的对Aggregate Key 相同的行,在 Value 列上进行聚合操作。
  • 目前支持SUM/MIN/MAX/REPLACE聚合操作。
    • SUM:求和,多行的 Value 进行累加。
    • REPLACE:替代,下一批数据中的 Value 会替换之前导入过的行中的 Value。
    • MAX:保留最大值。
    • MIN:保留最小值。
  • Aggregate模型可以提前聚合数据,适合报表和多维业务。
2.2 样例测试

(1)表结构

ColumnName

Type

AggregationType

Comment

user_id

INT

用户id

user_name

VARCHAR(32)

用户名

last_visit

DATETIME

REPLACE

用户最后一次访问时间

max_dwell_time

INT

MAX

用户最大停留时间

min_dwell_time

INT

MIN

用户最小停留时间

pv

BIGINT

SUM

点击量

dt

DATE

数据灌入日期时间

(2)建表语句

代码语言:javascript复制
CREATE TABLE IF NOT EXISTS test.user_visit
(
    dt DATE NOT NULL COMMENT "数据灌入日期时间"
	user_id INT NOT NULL COMMENT "用户id",
    last_visit DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "最近访问时间",
    max_dwell_time INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
    min_dwell_time INT MIN DEFAULT "99999" COMMENT "用户最小停留时间",
	pv BIGINT SUM DEFAULT "0" COMMENT "点击量"
)
AGGREGATE KEY(dt,user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 8
PROPERTIES ("replication_num"="1");
代码语言:javascript复制
mysql> CREATE TABLE IF NOT EXISTS test.user_visit
    -> (
    ->     dt DATE NOT NULL COMMENT "数据灌入日期时间",
    ->     user_id INT NOT NULL COMMENT "用户id",
    ->     last_visit DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "最近访问时间",
    ->     max_dwell_time INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
    ->     min_dwell_time INT MIN DEFAULT "99999" COMMENT "用户最小停留时间",
    ->     pv BIGINT SUM DEFAULT "0" COMMENT "点击量"
    -> )
    -> AGGREGATE KEY(dt,user_id)
    -> DISTRIBUTED BY HASH(user_id) BUCKETS 8
    -> PROPERTIES ("replication_num"="1");                                                                                                                     Query OK, 0 rows affected (0.03 sec)

mysql> 

(3)插入数据

代码语言:javascript复制
mysql> insert into test.user_visit values("2021-08-31",1,"2021-08-30 10:20:22",2,1,1);
Query OK, 1 row affected (0.11 sec)
{'label':'insert_d275799ba2b842c5-aa89f42c97d28e12', 'status':'VISIBLE', 'txnId':'152'}

mysql> select * from test.user_visit;
 ------------ --------- --------------------- ---------------- ---------------- ------ 
| dt         | user_id | last_visit          | max_dwell_time | min_dwell_time | pv   |
 ------------ --------- --------------------- ---------------- ---------------- ------ 
| 2021-08-31 |       1 | 2021-08-30 10:20:22 |              2 |              1 |    1 |
 ------------ --------- --------------------- ---------------- ---------------- ------ 
1 row in set (0.02 sec)

mysql>
代码语言:javascript复制
mysql> insert into test.user_visit values("2021-08-31",1,"2021-08-30 11:30:22",10,0,2);
Query OK, 1 row affected (0.05 sec)
{'label':'insert_546f947cc80b4832-849e85afc78be4fc', 'status':'VISIBLE', 'txnId':'154'}

mysql> select * from test.user_visit;
 ------------ --------- --------------------- ---------------- ---------------- ------ 
| dt         | user_id | last_visit          | max_dwell_time | min_dwell_time | pv   |
 ------------ --------- --------------------- ---------------- ---------------- ------ 
| 2021-08-31 |       1 | 2021-08-30 11:30:22 |             10 |              0 |    3 |
 ------------ --------- --------------------- ---------------- ---------------- ------ 
1 row in set (0.03 sec)

mysql>

3、更新模型(UNIQUE)

3.1 说明
  • 数据仓库中有一类累计快照事实表,覆盖一个完整的事务或产品的生命周期(无固定周期),通常有多个日期字段,记录生命周期的关键时间点,比如订单记录快照事实表有付款日期,发货日期和收货日期时间点。
  • 针对这种数据更新更新场景,传统处理方式是业务结束时间进行分区,未结束的业务结束日期统一定义为9999-12-31。Doris采用更新模型来满足这种需求。
  • 排序键满足唯一性约束, 成为主键
3.2 样例测试

(1)表结构

ColumnName

Type

IsKey

Comment

order_id

BIGINT

Y

订单id

order_status

TINYINT

订单状态

user_id

varchar(32)

用户ID

order_amount

DOUBLE

订单金额

(2)建表语句

代码语言:javascript复制
CREATE TABLE IF NOT EXISTS test.user_order
(
	order_id BIGINT NOT NULL COMMENT "订单ID",
    order_status TINYINT COMMENT "订单状态",
	user_id varchar(32) NOT NULL COMMENT "用户ID",
    order_amount DOUBLE COMMENT "订单金额"
)
UNIQUE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 8
PROPERTIES ("replication_num"="1");

(3)插入数据

代码语言:javascript复制
mysql> CREATE TABLE IF NOT EXISTS test.user_order                                                                                                                  -> (
    ->     order_id BIGINT NOT NULL COMMENT "订单ID",
    ->     order_status TINYINT COMMENT "订单状态",
    ->     user_id varchar(32) NOT NULL COMMENT "用户ID",
    ->     order_amount DOUBLE COMMENT "订单金额"
    -> )
    -> UNIQUE KEY(order_id)
    -> DISTRIBUTED BY HASH(order_id) BUCKETS 8
    -> PROPERTIES ("replication_num"="1");
Query OK, 0 rows affected (0.02 sec)

mysql> insert into  test.user_order values(1001,1,'hadron',98.5);
Query OK, 1 row affected (0.06 sec)
{'label':'insert_5fabf4aca7074801-b5156a1523160ec9', 'status':'VISIBLE', 'txnId':'238'}

mysql> insert into  test.user_order values(1001,2,'hadron',98.5);
Query OK, 1 row affected (0.04 sec)
{'label':'insert_58b051467da94422-b49c606b6f54f1f3', 'status':'VISIBLE', 'txnId':'239'}

mysql> select * from test.user_order;
 ---------- -------------- --------- -------------- 
| order_id | order_status | user_id | order_amount |
 ---------- -------------- --------- -------------- 
|     1001 |            2 | hadron  |         98.5 |
 ---------- -------------- --------- -------------- 
1 row in set (0.03 sec)

mysql> 

0 人点赞