yagagagaga commented on code in PR #1295: URL: https://github.com/apache/doris-website/pull/1295#discussion_r1830733474
########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/auto-partitioning.md: ########## @@ -0,0 +1,280 @@ +--- +{ + "title": "自动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 使用场景 + +自动分区功能主要解决了用户预期基于某列对表进行分区操作,但该列的数据分布比较零散或者难以预测,在建表或调整表结构时难以准确创建所需分区,或者分区数量过多以至于手动创建过于繁琐的问题。 + +以时间类型分区列为例,在动态分区功能中,我们支持了按特定时间周期自动创建新分区以容纳实时数据。对于实时的用户行为日志等场景该功能基本能够满足需求。但在一些更复杂的场景下,例如处理非实时数据时,分区列与当前系统时间无关,且包含大量离散值。此时为提高效率我们希望依据此列对数据进行分区,但数据实际可能涉及的分区无法预先掌握,或者预期所需分区数量过大。这种情况下动态分区或者手动创建分区无法满足我们的需求,自动分区功能很好地覆盖了此类需求。 + +假设我们的表 DDL 如下: + +```sql +CREATE TABLE `DAILY_TRADE_VALUE` +( + `TRADE_DATE` datev2 NOT NULL COMMENT '交易日期', + `TRADE_ID` varchar(40) NOT NULL COMMENT '交易编号', + ...... +) +UNIQUE KEY(`TRADE_DATE`, `TRADE_ID`) +PARTITION BY RANGE(`TRADE_DATE`) +( + PARTITION p_2000 VALUES [('2000-01-01'), ('2001-01-01')), + PARTITION p_2001 VALUES [('2001-01-01'), ('2002-01-01')), + PARTITION p_2002 VALUES [('2002-01-01'), ('2003-01-01')), + PARTITION p_2003 VALUES [('2003-01-01'), ('2004-01-01')), + PARTITION p_2004 VALUES [('2004-01-01'), ('2005-01-01')), + PARTITION p_2005 VALUES [('2005-01-01'), ('2006-01-01')), + PARTITION p_2006 VALUES [('2006-01-01'), ('2007-01-01')), + PARTITION p_2007 VALUES [('2007-01-01'), ('2008-01-01')), + PARTITION p_2008 VALUES [('2008-01-01'), ('2009-01-01')), + PARTITION p_2009 VALUES [('2009-01-01'), ('2010-01-01')), + PARTITION p_2010 VALUES [('2010-01-01'), ('2011-01-01')), + PARTITION p_2011 VALUES [('2011-01-01'), ('2012-01-01')), + PARTITION p_2012 VALUES [('2012-01-01'), ('2013-01-01')), + PARTITION p_2013 VALUES [('2013-01-01'), ('2014-01-01')), + PARTITION p_2014 VALUES [('2014-01-01'), ('2015-01-01')), + PARTITION p_2015 VALUES [('2015-01-01'), ('2016-01-01')), + PARTITION p_2016 VALUES [('2016-01-01'), ('2017-01-01')), + PARTITION p_2017 VALUES [('2017-01-01'), ('2018-01-01')), + PARTITION p_2018 VALUES [('2018-01-01'), ('2019-01-01')), + PARTITION p_2019 VALUES [('2019-01-01'), ('2020-01-01')), + PARTITION p_2020 VALUES [('2020-01-01'), ('2021-01-01')), + PARTITION p_2021 VALUES [('2021-01-01'), ('2022-01-01')) +) +DISTRIBUTED BY HASH(`TRADE_DATE`) BUCKETS 10 +PROPERTIES ( + "replication_num" = "1" +); +``` + + + +该表内存储了大量业务历史数据,依据交易发生的日期进行分区。可以看到在建表时,我们需要预先手动创建分区。如果分区列的数据范围发生变化,例如上表中增加了 2022 年的数据,则我们需要通过[ALTER-TABLE-PARTITION](../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-TABLE-PARTITION)对表的分区进行更改。如果这种分区需要变更,或者进行更细粒度的细分,修改起来非常繁琐。此时我们就可以使用 AUTO PARTITION 改写该表 DDL。 + +## 语法 + +建表时,使用以下语法填充[CREATE-TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE)时的`partition_info`部分: + +1. AUTO RANGE PARTITION: + + ```sql + AUTO PARTITION BY RANGE (FUNC_CALL_EXPR) + ( + ) + ``` + + + + 其中 + + ```sql + FUNC_CALL_EXPR ::= date_trunc ( <partition_column>, '<interval>' ) + ``` + + + + 注意:在 2.1.0 版本,`FUNC_CALL_EXPR` 外围不需要被括号包围。 + +2. AUTO LIST PARTITION: + +```sql +AUTO PARTITION BY LIST(`partition_col`) +( +) +``` + + + +### 用法示例 + +1. AUTO RANGE PARTITION + + ```sql + CREATE TABLE `date_table` ( + `TIME_STAMP` datev2 NOT NULL COMMENT '采集日期' + ) ENGINE=OLAP + DUPLICATE KEY(`TIME_STAMP`) + AUTO PARTITION BY RANGE (date_trunc(`TIME_STAMP`, 'month')) + ( + ) + DISTRIBUTED BY HASH(`TIME_STAMP`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" Review Comment: ```suggestion "replication_allocation" = "tag.location.default: 3" ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/auto-partitioning.md: ########## @@ -0,0 +1,280 @@ +--- +{ + "title": "自动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 使用场景 + +自动分区功能主要解决了用户预期基于某列对表进行分区操作,但该列的数据分布比较零散或者难以预测,在建表或调整表结构时难以准确创建所需分区,或者分区数量过多以至于手动创建过于繁琐的问题。 + +以时间类型分区列为例,在动态分区功能中,我们支持了按特定时间周期自动创建新分区以容纳实时数据。对于实时的用户行为日志等场景该功能基本能够满足需求。但在一些更复杂的场景下,例如处理非实时数据时,分区列与当前系统时间无关,且包含大量离散值。此时为提高效率我们希望依据此列对数据进行分区,但数据实际可能涉及的分区无法预先掌握,或者预期所需分区数量过大。这种情况下动态分区或者手动创建分区无法满足我们的需求,自动分区功能很好地覆盖了此类需求。 + +假设我们的表 DDL 如下: + +```sql +CREATE TABLE `DAILY_TRADE_VALUE` +( + `TRADE_DATE` datev2 NOT NULL COMMENT '交易日期', + `TRADE_ID` varchar(40) NOT NULL COMMENT '交易编号', + ...... +) +UNIQUE KEY(`TRADE_DATE`, `TRADE_ID`) +PARTITION BY RANGE(`TRADE_DATE`) +( + PARTITION p_2000 VALUES [('2000-01-01'), ('2001-01-01')), + PARTITION p_2001 VALUES [('2001-01-01'), ('2002-01-01')), + PARTITION p_2002 VALUES [('2002-01-01'), ('2003-01-01')), + PARTITION p_2003 VALUES [('2003-01-01'), ('2004-01-01')), + PARTITION p_2004 VALUES [('2004-01-01'), ('2005-01-01')), + PARTITION p_2005 VALUES [('2005-01-01'), ('2006-01-01')), + PARTITION p_2006 VALUES [('2006-01-01'), ('2007-01-01')), + PARTITION p_2007 VALUES [('2007-01-01'), ('2008-01-01')), + PARTITION p_2008 VALUES [('2008-01-01'), ('2009-01-01')), + PARTITION p_2009 VALUES [('2009-01-01'), ('2010-01-01')), + PARTITION p_2010 VALUES [('2010-01-01'), ('2011-01-01')), + PARTITION p_2011 VALUES [('2011-01-01'), ('2012-01-01')), + PARTITION p_2012 VALUES [('2012-01-01'), ('2013-01-01')), + PARTITION p_2013 VALUES [('2013-01-01'), ('2014-01-01')), + PARTITION p_2014 VALUES [('2014-01-01'), ('2015-01-01')), + PARTITION p_2015 VALUES [('2015-01-01'), ('2016-01-01')), + PARTITION p_2016 VALUES [('2016-01-01'), ('2017-01-01')), + PARTITION p_2017 VALUES [('2017-01-01'), ('2018-01-01')), + PARTITION p_2018 VALUES [('2018-01-01'), ('2019-01-01')), + PARTITION p_2019 VALUES [('2019-01-01'), ('2020-01-01')), + PARTITION p_2020 VALUES [('2020-01-01'), ('2021-01-01')), + PARTITION p_2021 VALUES [('2021-01-01'), ('2022-01-01')) +) +DISTRIBUTED BY HASH(`TRADE_DATE`) BUCKETS 10 +PROPERTIES ( + "replication_num" = "1" +); +``` + + + +该表内存储了大量业务历史数据,依据交易发生的日期进行分区。可以看到在建表时,我们需要预先手动创建分区。如果分区列的数据范围发生变化,例如上表中增加了 2022 年的数据,则我们需要通过[ALTER-TABLE-PARTITION](../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-TABLE-PARTITION)对表的分区进行更改。如果这种分区需要变更,或者进行更细粒度的细分,修改起来非常繁琐。此时我们就可以使用 AUTO PARTITION 改写该表 DDL。 + +## 语法 + +建表时,使用以下语法填充[CREATE-TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE)时的`partition_info`部分: + +1. AUTO RANGE PARTITION: + + ```sql + AUTO PARTITION BY RANGE (FUNC_CALL_EXPR) + ( + ) + ``` + + + + 其中 + + ```sql + FUNC_CALL_EXPR ::= date_trunc ( <partition_column>, '<interval>' ) + ``` + + + + 注意:在 2.1.0 版本,`FUNC_CALL_EXPR` 外围不需要被括号包围。 Review Comment: ```suggestion 注意:在 2.1.0 版本,`FUNC_CALL_EXPR` 外围不需要被括号包围。 ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/auto-partitioning.md: ########## @@ -0,0 +1,280 @@ +--- +{ + "title": "自动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 使用场景 + +自动分区功能主要解决了用户预期基于某列对表进行分区操作,但该列的数据分布比较零散或者难以预测,在建表或调整表结构时难以准确创建所需分区,或者分区数量过多以至于手动创建过于繁琐的问题。 + +以时间类型分区列为例,在动态分区功能中,我们支持了按特定时间周期自动创建新分区以容纳实时数据。对于实时的用户行为日志等场景该功能基本能够满足需求。但在一些更复杂的场景下,例如处理非实时数据时,分区列与当前系统时间无关,且包含大量离散值。此时为提高效率我们希望依据此列对数据进行分区,但数据实际可能涉及的分区无法预先掌握,或者预期所需分区数量过大。这种情况下动态分区或者手动创建分区无法满足我们的需求,自动分区功能很好地覆盖了此类需求。 + +假设我们的表 DDL 如下: + +```sql +CREATE TABLE `DAILY_TRADE_VALUE` +( + `TRADE_DATE` datev2 NOT NULL COMMENT '交易日期', + `TRADE_ID` varchar(40) NOT NULL COMMENT '交易编号', + ...... +) +UNIQUE KEY(`TRADE_DATE`, `TRADE_ID`) +PARTITION BY RANGE(`TRADE_DATE`) +( + PARTITION p_2000 VALUES [('2000-01-01'), ('2001-01-01')), + PARTITION p_2001 VALUES [('2001-01-01'), ('2002-01-01')), + PARTITION p_2002 VALUES [('2002-01-01'), ('2003-01-01')), + PARTITION p_2003 VALUES [('2003-01-01'), ('2004-01-01')), + PARTITION p_2004 VALUES [('2004-01-01'), ('2005-01-01')), + PARTITION p_2005 VALUES [('2005-01-01'), ('2006-01-01')), + PARTITION p_2006 VALUES [('2006-01-01'), ('2007-01-01')), + PARTITION p_2007 VALUES [('2007-01-01'), ('2008-01-01')), + PARTITION p_2008 VALUES [('2008-01-01'), ('2009-01-01')), + PARTITION p_2009 VALUES [('2009-01-01'), ('2010-01-01')), + PARTITION p_2010 VALUES [('2010-01-01'), ('2011-01-01')), + PARTITION p_2011 VALUES [('2011-01-01'), ('2012-01-01')), + PARTITION p_2012 VALUES [('2012-01-01'), ('2013-01-01')), + PARTITION p_2013 VALUES [('2013-01-01'), ('2014-01-01')), + PARTITION p_2014 VALUES [('2014-01-01'), ('2015-01-01')), + PARTITION p_2015 VALUES [('2015-01-01'), ('2016-01-01')), + PARTITION p_2016 VALUES [('2016-01-01'), ('2017-01-01')), + PARTITION p_2017 VALUES [('2017-01-01'), ('2018-01-01')), + PARTITION p_2018 VALUES [('2018-01-01'), ('2019-01-01')), + PARTITION p_2019 VALUES [('2019-01-01'), ('2020-01-01')), + PARTITION p_2020 VALUES [('2020-01-01'), ('2021-01-01')), + PARTITION p_2021 VALUES [('2021-01-01'), ('2022-01-01')) +) +DISTRIBUTED BY HASH(`TRADE_DATE`) BUCKETS 10 +PROPERTIES ( + "replication_num" = "1" +); +``` + + + +该表内存储了大量业务历史数据,依据交易发生的日期进行分区。可以看到在建表时,我们需要预先手动创建分区。如果分区列的数据范围发生变化,例如上表中增加了 2022 年的数据,则我们需要通过[ALTER-TABLE-PARTITION](../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-TABLE-PARTITION)对表的分区进行更改。如果这种分区需要变更,或者进行更细粒度的细分,修改起来非常繁琐。此时我们就可以使用 AUTO PARTITION 改写该表 DDL。 + +## 语法 + +建表时,使用以下语法填充[CREATE-TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE)时的`partition_info`部分: + +1. AUTO RANGE PARTITION: + + ```sql + AUTO PARTITION BY RANGE (FUNC_CALL_EXPR) + ( + ) + ``` + + + + 其中 + + ```sql + FUNC_CALL_EXPR ::= date_trunc ( <partition_column>, '<interval>' ) + ``` + + + + 注意:在 2.1.0 版本,`FUNC_CALL_EXPR` 外围不需要被括号包围。 + +2. AUTO LIST PARTITION: + +```sql +AUTO PARTITION BY LIST(`partition_col`) +( +) +``` + + + +### 用法示例 + +1. AUTO RANGE PARTITION + + ```sql + CREATE TABLE `date_table` ( + `TIME_STAMP` datev2 NOT NULL COMMENT '采集日期' + ) ENGINE=OLAP + DUPLICATE KEY(`TIME_STAMP`) + AUTO PARTITION BY RANGE (date_trunc(`TIME_STAMP`, 'month')) + ( + ) + DISTRIBUTED BY HASH(`TIME_STAMP`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + ``` + + + +2. AUTO LIST PARTITION + + ```sql + CREATE TABLE `str_table` ( + `str` varchar not null + ) ENGINE=OLAP + DUPLICATE KEY(`str`) + AUTO PARTITION BY LIST (`str`) + ( + ) + DISTRIBUTED BY HASH(`str`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + ``` + +### 约束 + +1. 在 AUTO LIST PARTITION 中,**分区名长度不得超过 50**. 该长度来自于对应数据行上各分区列内容的拼接与转义,因此实际容许长度可能更短。 +2. 在 AUTO RANGE PARTITION 中,分区函数仅支持 `date_trunc`,分区列仅支持 `DATE` 或者 `DATETIME` 格式; Review Comment: ```suggestion 2. 在 AUTO RANGE PARTITION 中,分区函数仅支持 `date_trunc`,分区列仅支持 `DATE` 或者 `DATETIME` 类型; ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/manual-partitioning.md: ########## @@ -0,0 +1,230 @@ +--- +{ + "title": "手动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 分区列 + +- 分区列可以指定一列或多列,分区列必须为 KEY 列。多列分区的使用方式在后面多列分区小结介绍。 +- PARTITION 列默认必须为 NOT NULL 列,如果需要使用 NULL 列,应设置 session variable `allow_partition_column_nullable = true`。对于 LIST PARTITION,支持真正的 NULL 分区。对于 RANGE PARTITION,NULL 值会被划归**最小的 LESS THAN 分区**。 +- 不论分区列是什么类型,在写分区值时,都需要加双引号。 +- 分区数量理论上没有上限。 +- 当不使用分区建表时,系统会自动生成一个和表名同名的,全值范围的分区。该分区对用户不可见,并且不可删改。 +- 创建分区时不可添加范围重叠的分区。 + +## Range 分区 + +分区列通常为时间列,以方便的管理新旧数据。Range 分区支持的列类型 DATE, DATETIME, TINYINT, SMALLINT, INT, BIGINT, LARGEINT。 + +**分区信息,支持四种写法:** + +1. FIXED RANGE:定义分区的左闭右开区间。 + +```Plain Review Comment: ```suggestion ```sql ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/manual-partitioning.md: ########## @@ -0,0 +1,230 @@ +--- +{ + "title": "手动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 分区列 + +- 分区列可以指定一列或多列,分区列必须为 KEY 列。多列分区的使用方式在后面多列分区小结介绍。 +- PARTITION 列默认必须为 NOT NULL 列,如果需要使用 NULL 列,应设置 session variable `allow_partition_column_nullable = true`。对于 LIST PARTITION,支持真正的 NULL 分区。对于 RANGE PARTITION,NULL 值会被划归**最小的 LESS THAN 分区**。 +- 不论分区列是什么类型,在写分区值时,都需要加双引号。 +- 分区数量理论上没有上限。 +- 当不使用分区建表时,系统会自动生成一个和表名同名的,全值范围的分区。该分区对用户不可见,并且不可删改。 +- 创建分区时不可添加范围重叠的分区。 + +## Range 分区 + +分区列通常为时间列,以方便的管理新旧数据。Range 分区支持的列类型 DATE, DATETIME, TINYINT, SMALLINT, INT, BIGINT, LARGEINT。 + +**分区信息,支持四种写法:** + +1. FIXED RANGE:定义分区的左闭右开区间。 + +```Plain +PARTITION BY RANGE(col1[, col2, ...]) +( + PARTITION partition_name1 VALUES [("k1-lower1", "k2-lower1", "k3-lower1",...), ("k1-upper1", "k2-upper1", "k3-upper1", ...)), + PARTITION partition_name2 VALUES [("k1-lower1-2", "k2-lower1-2", ...), ("k1-upper1-2", MAXVALUE, )) +) +``` + +示例如下: + +```shell +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES [("2017-01-01"), ("2017-02-01")), + PARTITION `p201702` VALUES [("2017-02-01"), ("2017-03-01")), + PARTITION `p201703` VALUES [("2017-03-01"), ("2017-04-01")) +) +``` + +2. LESS THAN:仅定义分区上界。下界由上一个分区的上界决定。 + +```Plain +PARTITION BY RANGE(col1[, col2, ...]) +( + PARTITION partition_name1 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...), + PARTITION partition_name2 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...) +) +``` + +示例如下: + +```sql +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES LESS THAN ("2017-02-01"), + PARTITION `p201702` VALUES LESS THAN ("2017-03-01"), + PARTITION `p201703` VALUES LESS THAN ("2017-04-01"), + PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01")), + PARTITION `other` VALUES LESS THAN (MAXVALUE) +) +``` + +3. BATCH RANGE:批量创建数字类型和时间类型的 RANGE 分区,定义分区的左闭右开区间,设定步长。 + +```Plain +PARTITION BY RANGE(int_col) +( + FROM (start_num) TO (end_num) INTERVAL interval_value +) + +PARTITION BY RANGE(date_col) +( + FROM ("start_date") TO ("end_date") INTERVAL num YEAR | num MONTH | num WEEK | num DAY | 1 HOUR +) +``` + +示例如下: + +```shell +PARTITION BY RANGE(age) +( + FROM (1) TO (100) INTERVAL 10 +) + +PARTITION BY RANGE(`date`) +( + FROM ("2000-11-14") TO ("2021-11-14") INTERVAL 2 YEAR +) +``` + +4.MULTI RANGE:批量创建 RANGE 分区,定义分区的左闭右开区间。示例如下: + +```shell +PARTITION BY RANGE(col) +( + FROM ("2000-11-14") TO ("2021-11-14") INTERVAL 1 YEAR, + FROM ("2021-11-14") TO ("2022-11-14") INTERVAL 1 MONTH, + FROM ("2022-11-14") TO ("2023-01-03") INTERVAL 1 WEEK, + FROM ("2023-01-03") TO ("2023-01-14") INTERVAL 1 DAY, + PARTITION p_20230114 VALUES [('2023-01-14'), ('2023-01-15')) +) +``` + +## List 分区 + +分区列支持 `BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE, DATETIME, CHAR, VARCHAR` 数据类型,分区值为枚举值。只有当数据为目标分区枚举值其中之一时,才可以命中分区。 + +Partition 支持通过 `VALUES IN (...)` 来指定每个分区包含的枚举值。 + +举例如下: + +```shell +PARTITION BY LIST(city) +( + PARTITION `p_cn` VALUES IN ("Beijing", "Shanghai", "Hong Kong"), + PARTITION `p_usa` VALUES IN ("New York", "San Francisco"), + PARTITION `p_jp` VALUES IN ("Tokyo") +) +``` + +List 分区也支持多列分区,示例如下: + +```Plain Review Comment: ```suggestion ```sql ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/basic-concepts.md: ########## @@ -0,0 +1,182 @@ +--- +{ + "title": "基本概念", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +本文档主要介绍 Doris 的建表和数据划分,以及建表操作中可能遇到的问题和解决方法。 + +## 基本概念 + +在 Doris 中,数据都以表(Table)的形式进行逻辑上的描述。 + +### Row & Column + +一张表包括行(Row)和列(Column): + +- Row:即用户的一行数据; + +- Column:用于描述一行数据中不同的字段; + +- Column 可以分为两大类:Key 和 Value。从业务角度看,Key 和 Value 可以分别对应维度列和指标列。Doris 的 key 列是建表语句中指定的列,建表语句中的关键字'unique key'或'aggregate key'或'duplicate key'后面的列就是 key 列,除了 key 列剩下的就是 value 列。从聚合模型的角度来说,Key 列相同的行,会聚合成一行。其中 Value 列的聚合方式由用户在建表时指定。关于更多聚合模型的介绍,可以参阅 [Doris 数据模型](../table-design/data-model/overview.md)。 + +### 分区和分桶(Partition & Bucket) + +Doris 使用分区和分桶的两层划分方式来组织和管理数据。 + +**分区** + +分区是指根据表中特定列的值进行分段,将表中的数据划分为更小,更易于管理的不相交的子集,每一个数据子集称为一个分区。分区可以视为最小的逻辑管理单元。合理地选择分区列有助于优化器根据查询谓词在查询计划中裁剪不相关的分区,从而减少需要扫描的数据量,提升查询性能。 + +目前 Doris 支持 Range 和 List 的分区划分方式。建表时如果不建立分区,此时 Doris 会生成一个默认的分区包含表中的所有数据,这个分区对用户是透明的。 + +**分桶** + +分桶是指将一个分区中的数据进一步按照某种规则被划分更小的不相交的数据单元。与根据特定列值对数据进行分段的分区不同,分桶不考虑实际的数据值,而是将数据均匀分布在预定义的桶中,从而减少数据倾斜的问题。分桶通过确保数据分布均匀并提高数据局部性以提升查询执行的性能。 + +目前 Doris 支持 Hash 和 Random 的分桶划分方式。 + +一个分桶在物理上对应一个数据分片(Tablet),数据分片在物理上是独立存储的,它是数据移动、复制等操作的最小物理存储单元。 + +**采用两层数据划分的好处** + +- 有时间维度或类似带有有序值的维度,可以以这类维度列作为分区列。分区粒度可以根据导入频次、分区数据量等进行评估。 + +- 历史数据删除需求:如有删除历史数据的需求(比如仅保留最近 N 天的数据)。使用复合分区,可以通过删除历史分区来达到目的。也可以通过在指定分区内发送 DELETE 语句进行数据删除。 + +- 解决数据倾斜问题:每个分区可以单独指定分桶数量。如按天分区,当每天的数据量差异很大时,可以通过指定分区的分桶数,合理划分不同分区的数据,分桶列建议选择区分度大的列。 + +### 建表举例 + +Doris 的建表是一个同步命令,SQL 执行完成即返回结果,命令返回成功即表示建表成功。具体建表语法可以参考[CREATE TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE),也可以通过 `HELP CREATE TABLE` 查看更多帮助。 + +这里给出了一个采用了 Range 分区 和 Hash 分桶的建表举例。 + +```sql +-- Range Partition +CREATE TABLE IF NOT EXISTS example_range_tbl +( + `user_id` LARGEINT NOT NULL COMMENT "用户id", + `date` DATE NOT NULL COMMENT "数据灌入日期时间", + `timestamp` DATETIME NOT NULL COMMENT "数据灌入的时间戳", + `city` VARCHAR(20) COMMENT "用户所在城市", + `age` SMALLINT COMMENT "用户年龄", + `sex` TINYINT COMMENT "用户性别", + `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间", + `cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费", + `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间", + `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间" +) +ENGINE=OLAP +AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES LESS THAN ("2017-02-01"), + PARTITION `p201702` VALUES LESS THAN ("2017-03-01"), + PARTITION `p201703` VALUES LESS THAN ("2017-04-01"), + PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01")) +) +DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 +PROPERTIES +( + "replication_num" = "1" +); +``` + +这里以 AGGREGATE KEY 数据模型为例进行说明。AGGREGATE KEY 数据模型中,所有没有指定聚合方式(SUM、REPLACE、MAX、MIN)的列视为 Key 列。而其余则为 Value 列。 + +在建表语句的最后 PROPERTIES 中,关于 PROPERTIES 中可以设置的相关参数,可以查看[CREATE TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE)中的详细介绍。 + +ENGINE 的类型是 OLAP,即默认的 ENGINE 类型。在 Doris 中,只有这个 ENGINE 类型是由 Doris 负责数据管理和存储的。其他 ENGINE 类型,如 MySQL、 Broker、ES 等等,本质上只是对外部其他数据库或系统中的表的映射,以保证 Doris 可以读取这些数据。而 Doris 本身并不创建、管理和存储任何非 OLAP ENGINE 类型的表和数据。 + +`IF NOT EXISTS`表示如果没有创建过该表,则创建。注意这里只判断表名是否存在,而不会判断新建表 Schema 是否与已存在的表 Schema 相同。所以如果存在一个同名但不同 Schema 的表,该命令也会返回成功,但并不代表已经创建了新的表和新的 Schema。。 + +### 查看分区信息 + +可以通过 show create table 来查看表的分区信息。 + +```Plain +> show create table example_range_tbl ++-------------------+---------------------------------------------------------------------------------------------------------+ +| Table | Create Table | ++-------------------+---------------------------------------------------------------------------------------------------------+ +| example_range_tbl | CREATE TABLE `example_range_tbl` ( | +| | `user_id` largeint(40) NOT NULL COMMENT '用户id', | +| | `date` date NOT NULL COMMENT '数据灌入日期时间', | +| | `timestamp` datetime NOT NULL COMMENT '数据灌入的时间戳', | +| | `city` varchar(20) NULL COMMENT '用户所在城市', | +| | `age` smallint(6) NULL COMMENT '用户年龄', | +| | `sex` tinyint(4) NULL COMMENT '用户性别', | +| | `last_visit_date` datetime REPLACE NULL DEFAULT "1970-01-01 00:00:00" COMMENT '用户最后一次访问时间', | +| | `cost` bigint(20) SUM NULL DEFAULT "0" COMMENT '用户总消费', | +| | `max_dwell_time` int(11) MAX NULL DEFAULT "0" COMMENT '用户最大停留时间', | +| | `min_dwell_time` int(11) MIN NULL DEFAULT "99999" COMMENT '用户最小停留时间' | +| | ) ENGINE=OLAP | +| | AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) | +| | COMMENT 'OLAP' | +| | PARTITION BY RANGE(`date`) | +| | (PARTITION p201701 VALUES [('0000-01-01'), ('2017-02-01')), | +| | PARTITION p201702 VALUES [('2017-02-01'), ('2017-03-01')), | +| | PARTITION p201703 VALUES [('2017-03-01'), ('2017-04-01'))) | +| | DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 | +| | PROPERTIES ( | +| | "replication_allocation" = "tag.location.default: 1", | +| | "is_being_synced" = "false", | +| | "storage_format" = "V2", | +| | "light_schema_change" = "true", | +| | "disable_auto_compaction" = "false", | +| | "enable_single_replica_compaction" = "false" | +| | ); | ++-------------------+---------------------------------------------------------------------------------------------------------+ +``` + +可以通过 show partitions from your_table 来查看表的分区信息。 + +```Plain Review Comment: ```suggestion ```sql ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/auto-partitioning.md: ########## @@ -0,0 +1,280 @@ +--- +{ + "title": "自动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 使用场景 + +自动分区功能主要解决了用户预期基于某列对表进行分区操作,但该列的数据分布比较零散或者难以预测,在建表或调整表结构时难以准确创建所需分区,或者分区数量过多以至于手动创建过于繁琐的问题。 + +以时间类型分区列为例,在动态分区功能中,我们支持了按特定时间周期自动创建新分区以容纳实时数据。对于实时的用户行为日志等场景该功能基本能够满足需求。但在一些更复杂的场景下,例如处理非实时数据时,分区列与当前系统时间无关,且包含大量离散值。此时为提高效率我们希望依据此列对数据进行分区,但数据实际可能涉及的分区无法预先掌握,或者预期所需分区数量过大。这种情况下动态分区或者手动创建分区无法满足我们的需求,自动分区功能很好地覆盖了此类需求。 + +假设我们的表 DDL 如下: + +```sql +CREATE TABLE `DAILY_TRADE_VALUE` +( + `TRADE_DATE` datev2 NOT NULL COMMENT '交易日期', + `TRADE_ID` varchar(40) NOT NULL COMMENT '交易编号', + ...... +) +UNIQUE KEY(`TRADE_DATE`, `TRADE_ID`) +PARTITION BY RANGE(`TRADE_DATE`) +( + PARTITION p_2000 VALUES [('2000-01-01'), ('2001-01-01')), + PARTITION p_2001 VALUES [('2001-01-01'), ('2002-01-01')), + PARTITION p_2002 VALUES [('2002-01-01'), ('2003-01-01')), + PARTITION p_2003 VALUES [('2003-01-01'), ('2004-01-01')), + PARTITION p_2004 VALUES [('2004-01-01'), ('2005-01-01')), + PARTITION p_2005 VALUES [('2005-01-01'), ('2006-01-01')), + PARTITION p_2006 VALUES [('2006-01-01'), ('2007-01-01')), + PARTITION p_2007 VALUES [('2007-01-01'), ('2008-01-01')), + PARTITION p_2008 VALUES [('2008-01-01'), ('2009-01-01')), + PARTITION p_2009 VALUES [('2009-01-01'), ('2010-01-01')), + PARTITION p_2010 VALUES [('2010-01-01'), ('2011-01-01')), + PARTITION p_2011 VALUES [('2011-01-01'), ('2012-01-01')), + PARTITION p_2012 VALUES [('2012-01-01'), ('2013-01-01')), + PARTITION p_2013 VALUES [('2013-01-01'), ('2014-01-01')), + PARTITION p_2014 VALUES [('2014-01-01'), ('2015-01-01')), + PARTITION p_2015 VALUES [('2015-01-01'), ('2016-01-01')), + PARTITION p_2016 VALUES [('2016-01-01'), ('2017-01-01')), + PARTITION p_2017 VALUES [('2017-01-01'), ('2018-01-01')), + PARTITION p_2018 VALUES [('2018-01-01'), ('2019-01-01')), + PARTITION p_2019 VALUES [('2019-01-01'), ('2020-01-01')), + PARTITION p_2020 VALUES [('2020-01-01'), ('2021-01-01')), + PARTITION p_2021 VALUES [('2021-01-01'), ('2022-01-01')) +) +DISTRIBUTED BY HASH(`TRADE_DATE`) BUCKETS 10 +PROPERTIES ( + "replication_num" = "1" +); +``` + + + +该表内存储了大量业务历史数据,依据交易发生的日期进行分区。可以看到在建表时,我们需要预先手动创建分区。如果分区列的数据范围发生变化,例如上表中增加了 2022 年的数据,则我们需要通过[ALTER-TABLE-PARTITION](../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-TABLE-PARTITION)对表的分区进行更改。如果这种分区需要变更,或者进行更细粒度的细分,修改起来非常繁琐。此时我们就可以使用 AUTO PARTITION 改写该表 DDL。 + +## 语法 + +建表时,使用以下语法填充[CREATE-TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE)时的`partition_info`部分: + +1. AUTO RANGE PARTITION: + + ```sql + AUTO PARTITION BY RANGE (FUNC_CALL_EXPR) + ( + ) + ``` + + + + 其中 + + ```sql + FUNC_CALL_EXPR ::= date_trunc ( <partition_column>, '<interval>' ) + ``` + + + + 注意:在 2.1.0 版本,`FUNC_CALL_EXPR` 外围不需要被括号包围。 + +2. AUTO LIST PARTITION: + +```sql +AUTO PARTITION BY LIST(`partition_col`) +( +) +``` + + + +### 用法示例 + +1. AUTO RANGE PARTITION + + ```sql + CREATE TABLE `date_table` ( + `TIME_STAMP` datev2 NOT NULL COMMENT '采集日期' + ) ENGINE=OLAP + DUPLICATE KEY(`TIME_STAMP`) + AUTO PARTITION BY RANGE (date_trunc(`TIME_STAMP`, 'month')) + ( + ) + DISTRIBUTED BY HASH(`TIME_STAMP`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + ``` + + + +2. AUTO LIST PARTITION + + ```sql + CREATE TABLE `str_table` ( + `str` varchar not null + ) ENGINE=OLAP + DUPLICATE KEY(`str`) + AUTO PARTITION BY LIST (`str`) + ( + ) + DISTRIBUTED BY HASH(`str`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + ``` + +### 约束 + +1. 在 AUTO LIST PARTITION 中,**分区名长度不得超过 50**. 该长度来自于对应数据行上各分区列内容的拼接与转义,因此实际容许长度可能更短。 +2. 在 AUTO RANGE PARTITION 中,分区函数仅支持 `date_trunc`,分区列仅支持 `DATE` 或者 `DATETIME` 格式; +3. 在 AUTO LIST PARTITION 中,不支持函数调用,分区列支持 `BOOLEAN`, `TINYINT`, `SMALLINT`, `INT`, `BIGINT`, `LARGEINT`, `DATE`, `DATETIME`, `CHAR`, `VARCHAR` 数据类型,分区值为枚举值。 +4. 在 AUTO LIST PARTITION 中,分区列的每个当前不存在对应分区的取值,都会创建一个独立的新 PARTITION。 + +### NULL 值分区 + +当开启 session variable `allow_partition_column_nullable` 后,LIST 和 RANGE 分区都支持 NULL 列作为分区列。当分区列实际遇到 NULL 值的插入时: Review Comment: 这个默认值就是true,有必要特别说明吗? ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/manual-partitioning.md: ########## @@ -0,0 +1,230 @@ +--- +{ + "title": "手动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 分区列 + +- 分区列可以指定一列或多列,分区列必须为 KEY 列。多列分区的使用方式在后面多列分区小结介绍。 +- PARTITION 列默认必须为 NOT NULL 列,如果需要使用 NULL 列,应设置 session variable `allow_partition_column_nullable = true`。对于 LIST PARTITION,支持真正的 NULL 分区。对于 RANGE PARTITION,NULL 值会被划归**最小的 LESS THAN 分区**。 +- 不论分区列是什么类型,在写分区值时,都需要加双引号。 +- 分区数量理论上没有上限。 +- 当不使用分区建表时,系统会自动生成一个和表名同名的,全值范围的分区。该分区对用户不可见,并且不可删改。 +- 创建分区时不可添加范围重叠的分区。 + +## Range 分区 + +分区列通常为时间列,以方便的管理新旧数据。Range 分区支持的列类型 DATE, DATETIME, TINYINT, SMALLINT, INT, BIGINT, LARGEINT。 + +**分区信息,支持四种写法:** + +1. FIXED RANGE:定义分区的左闭右开区间。 + +```Plain +PARTITION BY RANGE(col1[, col2, ...]) +( + PARTITION partition_name1 VALUES [("k1-lower1", "k2-lower1", "k3-lower1",...), ("k1-upper1", "k2-upper1", "k3-upper1", ...)), + PARTITION partition_name2 VALUES [("k1-lower1-2", "k2-lower1-2", ...), ("k1-upper1-2", MAXVALUE, )) +) +``` + +示例如下: + +```shell +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES [("2017-01-01"), ("2017-02-01")), + PARTITION `p201702` VALUES [("2017-02-01"), ("2017-03-01")), + PARTITION `p201703` VALUES [("2017-03-01"), ("2017-04-01")) +) +``` + +2. LESS THAN:仅定义分区上界。下界由上一个分区的上界决定。 + +```Plain Review Comment: ```suggestion ```sql ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/basic-concepts.md: ########## @@ -0,0 +1,182 @@ +--- +{ + "title": "基本概念", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +本文档主要介绍 Doris 的建表和数据划分,以及建表操作中可能遇到的问题和解决方法。 + +## 基本概念 + +在 Doris 中,数据都以表(Table)的形式进行逻辑上的描述。 + +### Row & Column + +一张表包括行(Row)和列(Column): + +- Row:即用户的一行数据; + +- Column:用于描述一行数据中不同的字段; + +- Column 可以分为两大类:Key 和 Value。从业务角度看,Key 和 Value 可以分别对应维度列和指标列。Doris 的 key 列是建表语句中指定的列,建表语句中的关键字'unique key'或'aggregate key'或'duplicate key'后面的列就是 key 列,除了 key 列剩下的就是 value 列。从聚合模型的角度来说,Key 列相同的行,会聚合成一行。其中 Value 列的聚合方式由用户在建表时指定。关于更多聚合模型的介绍,可以参阅 [Doris 数据模型](../table-design/data-model/overview.md)。 + +### 分区和分桶(Partition & Bucket) + +Doris 使用分区和分桶的两层划分方式来组织和管理数据。 + +**分区** + +分区是指根据表中特定列的值进行分段,将表中的数据划分为更小,更易于管理的不相交的子集,每一个数据子集称为一个分区。分区可以视为最小的逻辑管理单元。合理地选择分区列有助于优化器根据查询谓词在查询计划中裁剪不相关的分区,从而减少需要扫描的数据量,提升查询性能。 + +目前 Doris 支持 Range 和 List 的分区划分方式。建表时如果不建立分区,此时 Doris 会生成一个默认的分区包含表中的所有数据,这个分区对用户是透明的。 + +**分桶** + +分桶是指将一个分区中的数据进一步按照某种规则被划分更小的不相交的数据单元。与根据特定列值对数据进行分段的分区不同,分桶不考虑实际的数据值,而是将数据均匀分布在预定义的桶中,从而减少数据倾斜的问题。分桶通过确保数据分布均匀并提高数据局部性以提升查询执行的性能。 + +目前 Doris 支持 Hash 和 Random 的分桶划分方式。 + +一个分桶在物理上对应一个数据分片(Tablet),数据分片在物理上是独立存储的,它是数据移动、复制等操作的最小物理存储单元。 + +**采用两层数据划分的好处** + +- 有时间维度或类似带有有序值的维度,可以以这类维度列作为分区列。分区粒度可以根据导入频次、分区数据量等进行评估。 + +- 历史数据删除需求:如有删除历史数据的需求(比如仅保留最近 N 天的数据)。使用复合分区,可以通过删除历史分区来达到目的。也可以通过在指定分区内发送 DELETE 语句进行数据删除。 + +- 解决数据倾斜问题:每个分区可以单独指定分桶数量。如按天分区,当每天的数据量差异很大时,可以通过指定分区的分桶数,合理划分不同分区的数据,分桶列建议选择区分度大的列。 + +### 建表举例 + +Doris 的建表是一个同步命令,SQL 执行完成即返回结果,命令返回成功即表示建表成功。具体建表语法可以参考[CREATE TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE),也可以通过 `HELP CREATE TABLE` 查看更多帮助。 + +这里给出了一个采用了 Range 分区 和 Hash 分桶的建表举例。 + +```sql +-- Range Partition +CREATE TABLE IF NOT EXISTS example_range_tbl +( + `user_id` LARGEINT NOT NULL COMMENT "用户id", + `date` DATE NOT NULL COMMENT "数据灌入日期时间", + `timestamp` DATETIME NOT NULL COMMENT "数据灌入的时间戳", + `city` VARCHAR(20) COMMENT "用户所在城市", + `age` SMALLINT COMMENT "用户年龄", + `sex` TINYINT COMMENT "用户性别", + `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间", + `cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费", + `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间", + `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间" +) +ENGINE=OLAP +AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES LESS THAN ("2017-02-01"), + PARTITION `p201702` VALUES LESS THAN ("2017-03-01"), + PARTITION `p201703` VALUES LESS THAN ("2017-04-01"), + PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01")) +) +DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 +PROPERTIES +( + "replication_num" = "1" +); +``` + +这里以 AGGREGATE KEY 数据模型为例进行说明。AGGREGATE KEY 数据模型中,所有没有指定聚合方式(SUM、REPLACE、MAX、MIN)的列视为 Key 列。而其余则为 Value 列。 + +在建表语句的最后 PROPERTIES 中,关于 PROPERTIES 中可以设置的相关参数,可以查看[CREATE TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE)中的详细介绍。 + +ENGINE 的类型是 OLAP,即默认的 ENGINE 类型。在 Doris 中,只有这个 ENGINE 类型是由 Doris 负责数据管理和存储的。其他 ENGINE 类型,如 MySQL、 Broker、ES 等等,本质上只是对外部其他数据库或系统中的表的映射,以保证 Doris 可以读取这些数据。而 Doris 本身并不创建、管理和存储任何非 OLAP ENGINE 类型的表和数据。 + +`IF NOT EXISTS`表示如果没有创建过该表,则创建。注意这里只判断表名是否存在,而不会判断新建表 Schema 是否与已存在的表 Schema 相同。所以如果存在一个同名但不同 Schema 的表,该命令也会返回成功,但并不代表已经创建了新的表和新的 Schema。。 + +### 查看分区信息 + +可以通过 show create table 来查看表的分区信息。 + +```Plain Review Comment: ```suggestion ```sql ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/manual-partitioning.md: ########## @@ -0,0 +1,230 @@ +--- +{ + "title": "手动分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +## 分区列 + +- 分区列可以指定一列或多列,分区列必须为 KEY 列。多列分区的使用方式在后面多列分区小结介绍。 +- PARTITION 列默认必须为 NOT NULL 列,如果需要使用 NULL 列,应设置 session variable `allow_partition_column_nullable = true`。对于 LIST PARTITION,支持真正的 NULL 分区。对于 RANGE PARTITION,NULL 值会被划归**最小的 LESS THAN 分区**。 +- 不论分区列是什么类型,在写分区值时,都需要加双引号。 +- 分区数量理论上没有上限。 +- 当不使用分区建表时,系统会自动生成一个和表名同名的,全值范围的分区。该分区对用户不可见,并且不可删改。 +- 创建分区时不可添加范围重叠的分区。 + +## Range 分区 + +分区列通常为时间列,以方便的管理新旧数据。Range 分区支持的列类型 DATE, DATETIME, TINYINT, SMALLINT, INT, BIGINT, LARGEINT。 + +**分区信息,支持四种写法:** + +1. FIXED RANGE:定义分区的左闭右开区间。 + +```Plain +PARTITION BY RANGE(col1[, col2, ...]) +( + PARTITION partition_name1 VALUES [("k1-lower1", "k2-lower1", "k3-lower1",...), ("k1-upper1", "k2-upper1", "k3-upper1", ...)), + PARTITION partition_name2 VALUES [("k1-lower1-2", "k2-lower1-2", ...), ("k1-upper1-2", MAXVALUE, )) +) +``` + +示例如下: + +```shell +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES [("2017-01-01"), ("2017-02-01")), + PARTITION `p201702` VALUES [("2017-02-01"), ("2017-03-01")), + PARTITION `p201703` VALUES [("2017-03-01"), ("2017-04-01")) +) +``` + +2. LESS THAN:仅定义分区上界。下界由上一个分区的上界决定。 + +```Plain +PARTITION BY RANGE(col1[, col2, ...]) +( + PARTITION partition_name1 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...), + PARTITION partition_name2 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...) +) +``` + +示例如下: + +```sql +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES LESS THAN ("2017-02-01"), + PARTITION `p201702` VALUES LESS THAN ("2017-03-01"), + PARTITION `p201703` VALUES LESS THAN ("2017-04-01"), + PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01")), + PARTITION `other` VALUES LESS THAN (MAXVALUE) +) +``` + +3. BATCH RANGE:批量创建数字类型和时间类型的 RANGE 分区,定义分区的左闭右开区间,设定步长。 + +```Plain Review Comment: ```suggestion ```sql ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/dynamic-partitioning.md: ########## @@ -0,0 +1,454 @@ +--- +{ + "title": "动态分区", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +开启动态分区的表,将会按照设定的规则添加、删除分区,从而对表的分区实现生命周期管理(TTL),减少用户的使用负担。 + +动态分区只支持在 DATE/DATETIME 列上进行 Range 类型的分区。 + +动态分区适用于分区列的时间数据随现实世界同步增长的情况。此时可以灵活的按照与现实世界同步的时间维度对数据进行分区。 + +对于更为灵活,适用场景更多的数据入库分区,请参阅[自动分区](#自动分区)功能。 Review Comment: ```suggestion 对于更为灵活,适用场景更多的数据入库分区,请参阅[自动分区](./auto-partitioning.md)功能。 ``` ########## i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/data-partitioning/basic-concepts.md: ########## @@ -0,0 +1,182 @@ +--- +{ + "title": "基本概念", + "language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +本文档主要介绍 Doris 的建表和数据划分,以及建表操作中可能遇到的问题和解决方法。 + +## 基本概念 + +在 Doris 中,数据都以表(Table)的形式进行逻辑上的描述。 + +### Row & Column + +一张表包括行(Row)和列(Column): + +- Row:即用户的一行数据; + +- Column:用于描述一行数据中不同的字段; + +- Column 可以分为两大类:Key 和 Value。从业务角度看,Key 和 Value 可以分别对应维度列和指标列。Doris 的 key 列是建表语句中指定的列,建表语句中的关键字'unique key'或'aggregate key'或'duplicate key'后面的列就是 key 列,除了 key 列剩下的就是 value 列。从聚合模型的角度来说,Key 列相同的行,会聚合成一行。其中 Value 列的聚合方式由用户在建表时指定。关于更多聚合模型的介绍,可以参阅 [Doris 数据模型](../table-design/data-model/overview.md)。 + +### 分区和分桶(Partition & Bucket) + +Doris 使用分区和分桶的两层划分方式来组织和管理数据。 + +**分区** + +分区是指根据表中特定列的值进行分段,将表中的数据划分为更小,更易于管理的不相交的子集,每一个数据子集称为一个分区。分区可以视为最小的逻辑管理单元。合理地选择分区列有助于优化器根据查询谓词在查询计划中裁剪不相关的分区,从而减少需要扫描的数据量,提升查询性能。 + +目前 Doris 支持 Range 和 List 的分区划分方式。建表时如果不建立分区,此时 Doris 会生成一个默认的分区包含表中的所有数据,这个分区对用户是透明的。 + +**分桶** + +分桶是指将一个分区中的数据进一步按照某种规则被划分更小的不相交的数据单元。与根据特定列值对数据进行分段的分区不同,分桶不考虑实际的数据值,而是将数据均匀分布在预定义的桶中,从而减少数据倾斜的问题。分桶通过确保数据分布均匀并提高数据局部性以提升查询执行的性能。 + +目前 Doris 支持 Hash 和 Random 的分桶划分方式。 + +一个分桶在物理上对应一个数据分片(Tablet),数据分片在物理上是独立存储的,它是数据移动、复制等操作的最小物理存储单元。 + +**采用两层数据划分的好处** + +- 有时间维度或类似带有有序值的维度,可以以这类维度列作为分区列。分区粒度可以根据导入频次、分区数据量等进行评估。 + +- 历史数据删除需求:如有删除历史数据的需求(比如仅保留最近 N 天的数据)。使用复合分区,可以通过删除历史分区来达到目的。也可以通过在指定分区内发送 DELETE 语句进行数据删除。 + +- 解决数据倾斜问题:每个分区可以单独指定分桶数量。如按天分区,当每天的数据量差异很大时,可以通过指定分区的分桶数,合理划分不同分区的数据,分桶列建议选择区分度大的列。 + +### 建表举例 + +Doris 的建表是一个同步命令,SQL 执行完成即返回结果,命令返回成功即表示建表成功。具体建表语法可以参考[CREATE TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE),也可以通过 `HELP CREATE TABLE` 查看更多帮助。 + +这里给出了一个采用了 Range 分区 和 Hash 分桶的建表举例。 + +```sql +-- Range Partition +CREATE TABLE IF NOT EXISTS example_range_tbl +( + `user_id` LARGEINT NOT NULL COMMENT "用户id", + `date` DATE NOT NULL COMMENT "数据灌入日期时间", + `timestamp` DATETIME NOT NULL COMMENT "数据灌入的时间戳", + `city` VARCHAR(20) COMMENT "用户所在城市", + `age` SMALLINT COMMENT "用户年龄", + `sex` TINYINT COMMENT "用户性别", + `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间", + `cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费", + `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间", + `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间" +) +ENGINE=OLAP +AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES LESS THAN ("2017-02-01"), + PARTITION `p201702` VALUES LESS THAN ("2017-03-01"), + PARTITION `p201703` VALUES LESS THAN ("2017-04-01"), + PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01")) +) +DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 +PROPERTIES +( + "replication_num" = "1" +); +``` + +这里以 AGGREGATE KEY 数据模型为例进行说明。AGGREGATE KEY 数据模型中,所有没有指定聚合方式(SUM、REPLACE、MAX、MIN)的列视为 Key 列。而其余则为 Value 列。 + +在建表语句的最后 PROPERTIES 中,关于 PROPERTIES 中可以设置的相关参数,可以查看[CREATE TABLE](../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE)中的详细介绍。 + +ENGINE 的类型是 OLAP,即默认的 ENGINE 类型。在 Doris 中,只有这个 ENGINE 类型是由 Doris 负责数据管理和存储的。其他 ENGINE 类型,如 MySQL、 Broker、ES 等等,本质上只是对外部其他数据库或系统中的表的映射,以保证 Doris 可以读取这些数据。而 Doris 本身并不创建、管理和存储任何非 OLAP ENGINE 类型的表和数据。 + +`IF NOT EXISTS`表示如果没有创建过该表,则创建。注意这里只判断表名是否存在,而不会判断新建表 Schema 是否与已存在的表 Schema 相同。所以如果存在一个同名但不同 Schema 的表,该命令也会返回成功,但并不代表已经创建了新的表和新的 Schema。。 + +### 查看分区信息 + +可以通过 show create table 来查看表的分区信息。 + +```Plain +> show create table example_range_tbl ++-------------------+---------------------------------------------------------------------------------------------------------+ +| Table | Create Table | ++-------------------+---------------------------------------------------------------------------------------------------------+ +| example_range_tbl | CREATE TABLE `example_range_tbl` ( | +| | `user_id` largeint(40) NOT NULL COMMENT '用户id', | +| | `date` date NOT NULL COMMENT '数据灌入日期时间', | +| | `timestamp` datetime NOT NULL COMMENT '数据灌入的时间戳', | +| | `city` varchar(20) NULL COMMENT '用户所在城市', | +| | `age` smallint(6) NULL COMMENT '用户年龄', | +| | `sex` tinyint(4) NULL COMMENT '用户性别', | +| | `last_visit_date` datetime REPLACE NULL DEFAULT "1970-01-01 00:00:00" COMMENT '用户最后一次访问时间', | +| | `cost` bigint(20) SUM NULL DEFAULT "0" COMMENT '用户总消费', | +| | `max_dwell_time` int(11) MAX NULL DEFAULT "0" COMMENT '用户最大停留时间', | +| | `min_dwell_time` int(11) MIN NULL DEFAULT "99999" COMMENT '用户最小停留时间' | +| | ) ENGINE=OLAP | +| | AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) | +| | COMMENT 'OLAP' | +| | PARTITION BY RANGE(`date`) | +| | (PARTITION p201701 VALUES [('0000-01-01'), ('2017-02-01')), | +| | PARTITION p201702 VALUES [('2017-02-01'), ('2017-03-01')), | +| | PARTITION p201703 VALUES [('2017-03-01'), ('2017-04-01'))) | +| | DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 | +| | PROPERTIES ( | +| | "replication_allocation" = "tag.location.default: 1", | +| | "is_being_synced" = "false", | +| | "storage_format" = "V2", | +| | "light_schema_change" = "true", | +| | "disable_auto_compaction" = "false", | +| | "enable_single_replica_compaction" = "false" | +| | ); | ++-------------------+---------------------------------------------------------------------------------------------------------+ +``` + +可以通过 show partitions from your_table 来查看表的分区信息。 + +```Plain +> show partitions from example_range_tbl ++-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+--------------- ++---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+ +| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium +| CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | ++-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+--------------- ++---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+ +| 28731 | p201701 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [0000-01-01]; ..types: [DATEV2]; keys: [2017-02-01]; ) | user_id | 16 | 1 | HDD +| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true | +| 28732 | p201702 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [2017-02-01]; ..types: [DATEV2]; keys: [2017-03-01]; ) | user_id | 16 | 1 | HDD +| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true | +| 28733 | p201703 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [2017-03-01]; ..types: [DATEV2]; keys: [2017-04-01]; ) | user_id | 16 | 1 | HDD +| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true | ++-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+--------------- ++---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+ +``` + +### 修改分区信息 + +通过 alter table add partition 来增加新的分区 + +```Plain +ALTER TABLE example_range_tbl ADD PARTITION p201704 VALUES LESS THAN("2020-05-01") DISTRIBUTED BY HASH(`user_id`) BUCKETS 5; +``` + +其它更多分区修改操作,参见 SQL 手册 ALTER-TABLE-PARTITION。 Review Comment: ```suggestion 其它更多分区修改操作,参见 SQL 手册 [ALTER-TABLE-PARTITION](../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-TABLE-PARTITION.md)。 ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org