Skip to content

Commit

Permalink
Add time-window and sample docs (#862)
Browse files Browse the repository at this point in the history
Co-authored-by: dengn <[email protected]>
  • Loading branch information
dengn and helgarock authored Dec 4, 2023
1 parent 3492e5b commit 682ffd2
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 10 deletions.
2 changes: 1 addition & 1 deletion docs/MatrixOne/Develop/import-data/stream-load.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ INTO TABLE tbl_name;
```

!!! note
上述代码段中的登录账号为初始账号,请在登录 MatrixOne 后及时修改初始密码,参见[密码管理](../../../Security/password-mgmt.md)。
上述代码段中的登录账号为初始账号,请在登录 MatrixOne 后及时修改初始密码,参见[密码管理](../../Security/password-mgmt.md)。

2. 在 MatrixOne 中执行 `LOAD DATA INLINE` 之前,需要提前在 MatrixOne 中创建完成数据表 `user`:

Expand Down
122 changes: 122 additions & 0 deletions docs/MatrixOne/Develop/read-data/window-function/time-window.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# 时间窗口

在时序场景中,数据通常是流式的,流数据通常是无穷无尽的,我们无法知道什么时候数据源会继续/停止发送数据,所以在流上处理聚合事件(count、sum 等)的处理方式与批处理中的处理方式会有所差异。在时序数据流上一般用时间窗口(Windows)来限定聚合的范围,例如“过去 2 分钟网站点击量的计数”。时间窗口的概念相当于帮我们根据采集时间收集了一张有限数据的动态表,我们可以对表中的数据进行聚合计算。随着时间的推移,这个窗口会向前滑动,持续捕捉新的数据进行计算。

时间窗口分为 Tumble Window(翻滚窗口)和 Sliding Window(滑动窗口)。Tumble Window 的时间窗口长度固定,每个窗口时间不重叠。而 Sliding Window 的时间窗口长度也固定,但是窗口之间有重叠部分,可以更频繁地捕捉数据变化。

用户使用时间窗口功能时,可以在每个时间窗口内做计算,窗口随着时间的流动向前滑动。在定义连续查询的时候需要指定时间窗口的大小和下个窗口向前的增量时间。

## 降采样 (Downsampling)

降采样是指从大量数据中提取较小、管理性更强的数据子集的过程。这在处理大规模时间序列数据时尤为重要,可以减少存储需求,提高查询效率,并在数据可视化中提供更清晰的趋势图。时间窗口功能是数据库实现降采样功能的核心能力,通过定义时间窗口,我们可以在每个窗口内对数据进行聚合,从而实现降采样。时间窗口的大小和滑动距离决定了降采样的粒度。

## 时序表与时间窗口语法

在 MatrixOne 中,时间窗口需要结合时序表来使用,时序表是指建表时必须以 `ts` 列为主键的表,且类型为 `timestamp`.

```sql
DDL Clause:
CREATE TABLE TS_TBL (ts timestamp(6) primary key, SIGNAL1 FLOAT, SIGNAL2 DOUBLE, ...);

time_window_clause:
INTERVAL(timestamp_col, interval_val, time_unit) [SLIDING (sliding_val)] [fill_clause]

time_unit:
SECOND | MINUTE | HOUR | DAY

fill_clause:
FILL(NONE | PREV | NEXT | NULL | VALUE, val | LINEAR)
```

创建时序表的时候 `ts` 列可以指定 `timestamp` 的精度,最大为 `timestamp(6)`(微秒级别)。

INTERVAL 语句中的参数含义:

* timestamp_col:时间戳列。
* interval_val:时间窗口的长度。
* time_unit:时间单位(秒、分钟、小时、天)。
* SLIDING (sliding_val):可选,指定窗口滑动的时间距离。
* FILL(fill_method):可选,指定如何填充窗口内的数据。

INTERVAL (timestamp_col, interval_val) 作用于数据产生相当时间周期 interval_val 窗口,SLIDING 用以指定窗口向前滑动的 sliding_val 时间距离。

- 当 interval_val 等于 sliding_val 时为 Tumble window。

- 当 interval_val 大于 sliding_val 时为 Sliding window。

其他使用说明:

- INTERVAL 和 SLIDING 子句需要配合聚合或选择函数来使用,目前时间窗口中会支持:max, min, sum, avg, count 聚合函数。
- 聚合时间段的窗口宽度由关键词 INTERVAL 指定,最短时间间隔 1 秒。
- 时间窗口返回的结果中时间序列严格单调递增。
- interval_val 必须为正整数。
- 用 INTERVAL 查询时,_wstart(ts),_wend(ts) 是根据窗口生成出来的伪列,分别是窗口的开始时间和结束时间。

使用示例:

这个示例演示如何在 10 分钟的时间窗口内,每 5 分钟滑动一次,给出每 5 分钟的温度最大最小值。

```sql
mysql> drop table if exists sensor_data;
CREATE TABLE sensor_data (ts timestamp(3) primary key, temperature FLOAT);
INSERT INTO sensor_data VALUES('2023-08-01 00:00:00', 25.0);
INSERT INTO sensor_data VALUES('2023-08-01 00:05:00', 26.0);
INSERT INTO sensor_data VALUES('2023-08-01 00:15:00', 28.0);
INSERT INTO sensor_data VALUES('2023-08-01 00:20:00', 30.0);
INSERT INTO sensor_data VALUES('2023-08-01 00:25:00', 27.0);
INSERT INTO sensor_data VALUES('2023-08-01 00:30:00', null);
INSERT INTO sensor_data VALUES('2023-08-01 00:35:00', null);
INSERT INTO sensor_data VALUES('2023-08-01 00:40:00', 28);
INSERT INTO sensor_data VALUES('2023-08-01 00:45:00', 38);
INSERT INTO sensor_data VALUES('2023-08-01 00:50:00', 31);
insert into sensor_data values('2023-07-31 23:55:00', 22);
mysql> select _wstart, _wend, max(temperature), min(temperature) from sensor_data where ts > "2023-08-01 00:00:00.000" and ts < "2023-08-01 00:50:00" interval(ts, 10, minute) sliding(5, minute);
+-------------------------+-------------------------+------------------+------------------+
| _wstart | _wend | max(temperature) | min(temperature) |
+-------------------------+-------------------------+------------------+------------------+
| 2023-08-01 00:00:00.000 | 2023-08-01 00:10:00.000 | 26 | 26 |
| 2023-08-01 00:05:00.000 | 2023-08-01 00:15:00.000 | 26 | 26 |
| 2023-08-01 00:10:00.000 | 2023-08-01 00:20:00.000 | 28 | 28 |
| 2023-08-01 00:15:00.000 | 2023-08-01 00:25:00.000 | 30 | 28 |
| 2023-08-01 00:20:00.000 | 2023-08-01 00:30:00.000 | 30 | 27 |
| 2023-08-01 00:25:00.000 | 2023-08-01 00:35:00.000 | 27 | 27 |
| 2023-08-01 00:30:00.000 | 2023-08-01 00:40:00.000 | NULL | NULL |
| 2023-08-01 00:35:00.000 | 2023-08-01 00:45:00.000 | 28 | 28 |
| 2023-08-01 00:40:00.000 | 2023-08-01 00:50:00.000 | 38 | 28 |
| 2023-08-01 00:45:00.000 | 2023-08-01 00:55:00.000 | 38 | 38 |
+-------------------------+-------------------------+------------------+------------------+
10 rows in set (0.04 sec)

```

## 插值

在处理时序数据时,经常会遇到缺失值的情况。插值(FILL)功能允许我们以多种方式填充这些缺失值,确保数据的连续性和完整性,这对于数据分析和降采样过程至关重要。时间窗口的 `FIll` 子句作用于填充聚合结果。

MatrixOne 提供多种插值方法,以适应不同的数据处理需求:

- FILL(NONE): 不进行填充,即列不变
- FILL(VALUE, expr): 填充 expr 结果
- FILL(PREV): 使用前一个非 NULL 值填充数据
- FILL(NEXT): 使用下一个非 NULL 值填充数据
- FILL(LINEAR): 根据前后距离最近的非 NULL 值做线性插值填充

使用示例:

这个示例在之前那张表的基础上增加了插值逻辑,会将 NULL 值填充。

```sql
select _wstart(ts), _wend(ts), max(temperature), min(temperature) from sensor_data where ts > "2023-08-01 00:00:00.000" and ts < "2023-08-01 00:50:00.000" interval(ts, 10, minute) sliding(5, minute) fill(prev);
_wstart | _wend | max(temperature) | min(temperature) |
==================================================================================================
2023-08-01 00:00:00.000 | 2023-08-01 00:10:00.000 | 26.0000000 | 26.0000000 |
2023-08-01 00:05:00.000 | 2023-08-01 00:15:00.000 | 26.0000000 | 26.0000000 |
2023-08-01 00:10:00.000 | 2023-08-01 00:20:00.000 | 28.0000000 | 28.0000000 |
2023-08-01 00:15:00.000 | 2023-08-01 00:25:00.000 | 30.0000000 | 28.0000000 |
2023-08-01 00:20:00.000 | 2023-08-01 00:30:00.000 | 30.0000000 | 27.0000000 |
2023-08-01 00:25:00.000 | 2023-08-01 00:35:00.000 | 27.0000000 | 27.0000000 |
2023-08-01 00:30:00.000 | 2023-08-01 00:40:00.000 | 27.0000000 | 27.0000000 |
2023-08-01 00:35:00.000 | 2023-08-01 00:45:00.000 | 28.0000000 | 28.0000000 |
2023-08-01 00:40:00.000 | 2023-08-01 00:50:00.000 | 38.0000000 | 28.0000000 |
2023-08-01 00:45:00.000 | 2023-08-01 00:55:00.000 | 38.0000000 | 38.0000000 |
```
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ SQL 窗口函数在多种业务场景中都有其广泛的应用:

- 大多数聚合函数也可以用作窗口函数,例如,`SUM()``AVG()``COUNT()` 这些聚合函数可以与窗口函数一起使用,以在窗口内计算某个列的总和、平均值或计数。MatrixOne 支持的可做窗口函数的聚合函数和参考文档参见:

* [AVG](../../Reference/Functions-and-Operators/Aggregate-Functions/avg.md)
* [COUNT](../../Reference/Functions-and-Operators/Aggregate-Functions/count.md)
* [MAX](../../Reference/Functions-and-Operators/Aggregate-Functions/max.md)
* [SUM](../../Reference/Functions-and-Operators/Aggregate-Functions/sum.md)
* [MIN](../../Reference/Functions-and-Operators/Aggregate-Functions/min.md)
* [AVG] (../../../Reference/Functions-and-Operators/Aggregate-Functions/avg.md)
* [COUNT](../../../Reference/Functions-and-Operators/Aggregate-Functions/count.md)
* [MAX](../../../Reference/Functions-and-Operators/Aggregate-Functions/max.md)
* [SUM](../../../Reference/Functions-and-Operators/Aggregate-Functions/sum.md)
* [MIN](../../../Reference/Functions-and-Operators/Aggregate-Functions/min.md)

- 其他窗口函数参见下表:

|函数名称 | 说明|
|---|---|
|[DENSE_RANK()](../../Reference/Functions-and-Operators/Window-Functions/dense_rank.md)|用于为数据集中的行分配排名,始终为下一个值分配连续的排名,即使前面的值有相同的排名。|
|[RANK()](../../Reference/Functions-and-Operators/Window-Functions/rank.md)|为查询结果集中的每一行分配一个排名值,相同值的行将具有相同的排名,而下一个排名值将会跳过相同数量的行。|
|[ROW_NUMBER()](../../Reference/Functions-and-Operators/Window-Functions/row_number.md)|为查询结果集中的每一行分配一个唯一的整数值,根据指定的排序规则确定顺序。|
|[DENSE_RANK()](../../../Reference/Functions-and-Operators/Window-Functions/dense_rank.md)|用于为数据集中的行分配排名,始终为下一个值分配连续的排名,即使前面的值有相同的排名。|
|[RANK()](../../../Reference/Functions-and-Operators/Window-Functions/rank.md)|为查询结果集中的每一行分配一个排名值,相同值的行将具有相同的排名,而下一个排名值将会跳过相同数量的行。|
|[ROW_NUMBER()](../../../Reference/Functions-and-Operators/Window-Functions/row_number.md)|为查询结果集中的每一行分配一个唯一的整数值,根据指定的排序规则确定顺序。|

## 如何使用窗口函数

Expand Down
33 changes: 33 additions & 0 deletions docs/MatrixOne/Overview/feature/time-series.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 时序能力

## 时序数据的特点

随着物联网的发展,时序数据库的需求越来越多,比如智能汽车产生的数据,工厂的设备监控、金融行业的交易行情指标数据等。常见的业务场景包括:

监控软件系统:虚拟机、容器、服务、应用;
监控物理系统:水文监控、制造业工厂中的设备监控、国家安全相关的数据监控、通讯监控、传感器数据、血糖仪、血压变化、心率等;
资产跟踪应用:汽车、卡车、物理容器、运货托盘;
金融交易系统:传统证券、新兴的加密数字货币;
事件应用程序:跟踪用户、客户的交互数据;
商业智能工具:跟踪关键指标和业务的总体健康情况;
互联网行业:也有着非常多的时序数据,例如用户访问网站的行为轨迹,应用程序产生的日志数据等。

一方面由于时序数据库的时间属性,即随着时间的推移不断地产生新的数据;另一方面,时序的数据量巨大,每秒钟可能要写入千万、上亿条数据。这两方面的特性使得时序数据库在一些业务需求中会出现,常见的业务需求有:

1)获取最新状态,查询最近的数据(例如传感器最新的状态);
2)展示区间统计,指定时间范围,查询统计信息,例如平均值、最大值、最小值、计数等;
3)获取异常数据,根据指定条件,筛选异常数据。

## MatrixOne 的时序能力

目前行业中已经有一些专用的 NoSQL 时序数据库,如 InfluxDB, OpenTSDB, TDEngine 等,而 MatrixOne 与它们不一样的地方在于 MatrixOne 仍然是一个通用数据库,以满足应用开发的增删改查及数据分析的 HTAP 为核心,同时也仍然是一个关系型数据的建模形式,使用的查询语言也仍然是经典的 SQL 语言,MatrixOne 是在通用数据库能力的基础增加了一些时序相关的能力,定位上来说有点类似于 TimeScaleDB。MatrixOne 在功能上支持时间窗口,降采样,插值,分区等时序常见的能力,性能上可以满足时序场景中对高吞吐,高压缩,实时分析,同时整体架构上的强扩展性,冷热分离,读写分离等特点也非常适合时序相关的场景使用,同时保持了传统数据库中对更新,事务的支持。因此,MatrixOne 更适合需要用普通的关系型数据库进行业务开发,但是同时有需要有一定时序处理能力的混合场景。

MatrixOne 的时序能力体现在以下方面:

- 支持传统数据库中常见的字符串,数字,日期等数据类型,也同时支持新型负载的 JSON,向量等类型,详细可参见[数据类型](../../Reference/Data-Types/data-types.md).
- 支持建立按时间戳作为主键的专用时序表,并支持任意的维度/指标列,详细可参见[时间窗口](../../Develop/read-data/window-function/time-window.md).
- 提供常用的时间窗口能力,可以按不同的时间进行降采样查询,详细可参见[时间窗口](../../Develop/read-data/window-function/time-window.md).
- 支持针对空值的插值能力,并提供不同策略的插值方法,详细可参见[时间窗口](../../Develop/read-data/window-function/time-window.md).
- 支持各类传统数据库中的简单及复杂查询能力,详细可参见[单表查询](../../Develop/read-data/query-data-single-table.md), [多表查询](../../Develop/read-data/multitable-join-query.md), [子查询](../../Develop/read-data/subquery.md), [视图](../../Develop/read-data/subquery.md), [CTE](../../Develop/read-data/cte.md).
- 支持高速的[离线导入](../../Develop/import-data/bulk-load/bulk-load-overview.md), [流式数据写入](../../Develop/import-data/stream-load.md), [Insert into 写入](../../Develop/import-data/insert-data.md)等方式。
- 支持各类[聚合函数](../../Reference/Functions-and-Operators/Aggregate-Functions/count.md), 以满足时序数据类型的计算。
30 changes: 30 additions & 0 deletions docs/MatrixOne/Reference/Functions-and-Operators/Other/sample.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SAMPLE 采样函数

SAMPLE 采样函数功能是处理大量数据分析的关键工具,主要用于快速缩减查询范围。

1. 语法结构

```sql
SELECT SAMPLE(<column_list>, <N ROWS>/<K PERCENT>) FROM <table> [WHERE ...] [GROUP BY ...] [ORDER BY ...] [LIMIT ...] [OFFSET ...]
```

* `<column_list>`: 选择的列名列表。
* `<N ROWS>/<K PERCENT>`: 指定返回的样本数量(N 行)或百分比(K%)。

2. 功能特点

* SAMPLE 函数会在表过滤再执行采样。
* 返回表中 N 个随机样本,或 K%的随机样本。
* 当指定 N 行时,N 为 1-1000 的正整数。
* 当指定 K%时,K 的取值范围为 0.01-99.99 的,代表每行被选中的概率,结果每次可能不同,且行数不固定。比如表有 10000 行,执行 SAMPLE(a, 50 PERCENT); 由于每行都是有 50% 的概率被选中,类似于掷了 1 万次硬币,正反面的概率每次都是 50%,但是最终的结果可能是 350 次正面,650 次反面。
* 支持多列采样,如 SELECT SAMPLE(a,b,c, 100 ROWS) FROM t1;。
* 可与 WHERE 子句、GROUP BY 子句等结合使用。

3. 应用示例

```sql
SELECT SAMPLE(a, 100 ROWS) FROM t1; -- 返回 100 个随机样本
SELECT SAMPLE(a, 0.2 PERCENT) FROM t1; -- 返回约 0.2% 的样本
SELECT SAMPLE(a, 100 ROWS) FROM t1 WHERE a > 1; -- 先过滤后采样
SELECT a, SAMPLE(b, 100 ROWS) FROM t1 GROUP BY a; -- 分组后采样
```
6 changes: 5 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ nav:
- 极致扩展性: MatrixOne/Overview/feature/scalability.md
- 高性价比: MatrixOne/Overview/feature/cost-effective.md
- 高可用: MatrixOne/Overview/feature/high-availability.md
- 时序: MatrixOne/Overview/feature/time-series.md
- MySQL 兼容性: MatrixOne/Overview/feature/mysql-compatibility.md
- MatrixOne 技术架构:
- 整体架构概述: MatrixOne/Overview/architecture/matrixone-architecture-design.md
Expand Down Expand Up @@ -124,7 +125,9 @@ nav:
- 子查询: MatrixOne/Develop/read-data/subquery.md
- 视图: MatrixOne/Develop/read-data/views.md
- 公共表表达式: MatrixOne/Develop/read-data/cte.md
- 窗口函数: MatrixOne/Develop/read-data/window-function.md
- 窗口函数:
- 标准窗口: MatrixOne/Develop/read-data/window-function/window-function.md
- 时间窗口: MatrixOne/Develop/read-data/window-function/time-window.md
- 租户设计:
- 多租户概述: MatrixOne/Develop/Publish-Subscribe/multi-account-overview.md
- 发布订阅: MatrixOne/Develop/Publish-Subscribe/pub-sub-overview.md
Expand Down Expand Up @@ -535,6 +538,7 @@ nav:
- ROW_NUMBER(): MatrixOne/Reference/Functions-and-Operators/Window-Functions/row_number.md
- JSON 函数: MatrixOne/Reference/Functions-and-Operators/Json/json-functions.md
- 其他函数:
- SAMPLE: MatrixOne/Reference/Functions-and-Operators/Other/samples.md
- SLEEP: MatrixOne/Reference/Functions-and-Operators/Other/sleep.md
- UUID(): MatrixOne/Reference/Functions-and-Operators/Other/uuid.md
- 系统运维函数:
Expand Down

0 comments on commit 682ffd2

Please sign in to comment.