
# Doris建表规范
该章节主要介绍Doris建表时需遵循的规范和建议。
#### 建表规范
- 【强制】表数据超过5亿条以上必须设置分区分桶策略。
- 【强制】分桶的列不要设置太多，一般情况下1或2个列，同时需要兼顾数据分布均匀和查询吞吐之间的均衡，考虑数据均匀是为了避免某些桶的数据存在倾斜影响数据均衡和查询效率，考虑查询吞吐是为了利用查询SQL的分桶剪裁优化避免全桶扫描提升查询性能，所以优先考虑哪些数据较为均匀且常用于查询条件的列适合做分桶列。可以使用以下方法分析是否会导致数据倾斜：
  ```
  SELECT a, b, COUNT(*) FROM tab GROUP BY a,b;
  ```
  命令执行后查看各个分组的数据条数是否相差不大，如果相差超过2/3或1/2，则需要重新选择分桶字段。
  
- 【强制】2000万以内数据禁止使用动态分区（动态分区会自动创建分区，而小表用户客户关注不到，会创建出大量不使用分区分桶）。
- 【强制】创建表时的副本数必须至少为2，默认是3，禁止使用单副本。
- 【强制】创建Doris表动态分区时，禁止使用auto partition特性，推荐使用Dynamic Partition。
- 【强制】没有聚合函数列的表不应该被创建为AGGREGATE表。
- 【强制】创建表并指定分桶（buckets）时，每个桶的数据大小应保持在100M-3G之间；单分区中最大分桶数不超过5000；单个表的分区总数不超过10000；整个集群中的表数量不超过5000。
- 【建议】动态分区Dynamic Partition不建议历史分区设置过多，如果以天为分区，历史分区最大不建议超过30；如果客户的数据需要永久保留又要使用分区，建议优先考虑手动分区。
- 【建议】对于有大量历史分区数据，但是历史数据比较少，或者不均衡，或者查询概率的情况，使用如下方式将数据放在特殊分区：
  - 对于历史数据，如果数据量比较小可以创建历史分区（比如年分区，月分区），将所有历史数据放到对应分区里。
  
  - 创建历史分区方式：FROM ("2000-01-01") TO ("2022-01-01") INTERVAL 1 YEAR。
   
- 【建议】1000万-2亿以内数据为了方便可以不设置分区，直接用分桶策略（不设置其实Doris内部会有个默认分区）。
- 【建议】如果分桶字段存在30%以上的数据倾斜，则禁止使用Hash分桶策略，改使用random分桶策略：Create table ... DISTRIBUTED BY RANDOM BUCKETS 10 ...
- 【建议】建表时第一个字段一定是最常查询使用的列，默认有前缀索引快速查询能力，选取分区分桶外最长查询且高基数的列，前缀索引36位，如果列超长也不能使用前缀索引能力。
- 【建议】亿级别以上数据，如果有模糊匹配或者等值/in条件，可以使用倒排索引或者是Bloomfilter。如果是低基数列的正交查询适合使用bitmap索引。

- 【建议】单表物化视图不能超过6个，物化视图不建议嵌套，不建议数据写入时通过物化视图进行重型聚合和Join计算等ETL任务。
- 【建议】手动分桶可以有效提升数据导入及查询性能。应避免使用自动分桶策略（Auto Bucket），因为自动分桶策略（Auto Bucket）可能导致Tablet数量过多，最终产生大量的小文件，影响整体性能。
- 【建议】2.1及以上版本如果存在高频大量数据入库，建议使用MOR。如果优先考虑查询性能且可接受较长入库耗时，建议使用MOW。2.0及以下版本不建议使用MOW。
- 【建议】创建Doris表时，单个数据库下建议不要超过1000张表，表多情况需要在多个数据库中创建。
- 【建议】创建表时，排序键key不能太多，一般建议3\~5个；太多key会导致数据写入较慢，影响数据导入性能。
- 【建议】创建主键表时需保持主键的列唯一，不建议将所有列都设置为主键列，且主键表需设置value列。主键表不建议用于数据去重场景。
- 【建议】建表时需要提前规划将来要使用的字段个数，可以多预留几十个字段，类型包括整型、字符型等。避免将来字段不够使用，需要较高代价临时去添加字段。
 
