云服务器内容精选

  • 规则 禁止修改表索引类型。 Hudi表的索引会决定数据存储方式,随意修改索引类型会导致表中已有的存量数据与新增数据之间出现数据重复和数据准确性问题。常见的索引类型如下: 布隆索引:Spark引擎独有索引,采用bloomfiter机制,将布隆索引内容写入到Parquet文件的footer中。 Bucket索引:在写入数据过程中,通过主键进行Hash计算,将数据进行分桶写入;该索引写入速度最快,但是需要合理配置分桶数目;Flink、Spark均支持该索引写入。 状态索引:Flink引擎独有索引,是将行记录的存储位置记录到状态后端的一种索引形式,在作业冷启动过程中会遍历所有数据存储文件生成索引信息。 用Flink状态索引,Flink写入后,不支持Spark继续写入。 Flink在写Hudi的MOR表只会生成log文件,后续通过compaction操作,将log文件转为parquet文件。Spark在更新Hudi表时严重依赖parquet文件是否存在,如果当前Hudi表写的是log文件,采用Spark写入就会导致重复数据的产生。在批量初始化阶段 ,先采用Spark批量写入Hudi表,在用Flink基于Flink状态索引写入不会有问题,原因是Flink冷启动的时候会遍历所有的数据文件生成状态索引。 实时入湖场景中,Spark引擎采用Bucket索引,Flink引擎可以用Bucket索引或者状态索引。 实时入湖都是需要分钟内或者分钟级的高性能入湖,索引的选择会影响到写Hudi表的性能。在性能方面各个索引的区别如下: Bucket索引 优点:写入过程中对主键进行hash分桶写入,性能比较高,不受表的数据量限制。Flink和Spark引擎都支持,Flink和Spark引擎可以实现交叉混写同一张表。 缺点:Bucket个数不能动态调整,数据量波动和整表数据量持续上涨会导致单个Bucket数据量过大出现大数据文件。需要结合分区表来进行平衡改善。 Flink状态索引 优点:主键的索引信息存在状态后端,数据更新只需要点查状态后端即可,速度较快;同时生成的数据文件大小稳定,不会产生小文件、超大文件问题。 缺点:该索引为Flink特有索引。在表的总数据行数达到数亿级别,需要优化状态后端参数来保持写入的性能。使用该索引无法支持Flink和Spark交叉混写。 对于数据总量持续上涨的表,采用Bucket索引时,须使用时间分区,分区键采用数据创建时间。 参照Flink状态索引的特点,Hudi表超过一定数据量后,Flink作业状态后端压力很大,需要优化状态后端参数才能维持性能;同时由于Flink冷启动的时候需要遍历全表数据,大数据量也会导致Flink作业启动缓慢。因此基于简化使用的角度,针对大数据量的表,可以通过采用Bucket索引来避免状态后端的复杂调优。 如果Bucket索引+分区表的模式无法平衡Bueckt桶过大的问题,还是可以继续采用Flink状态索引,按照规范去优化对应的配置参数即可。
  • 建议 基于Flink的流式写入的表,在数据量超过2亿条记录,采用Bucket索引,2亿以内可以采用Flink状态索引。 参照Flink状态索引的特点,Hudi表超过一定数据量后,Flink作业状态后端压力很大,需要优化状态后端参数才能维持性能;同时由于Flink冷启动的时候需要遍历全表数据,大数据量也会导致Flink作业启动缓慢。因此基于简化使用的角度,针对大数据量的表,可以通过采用Bucket索引来避免状态后端的复杂调优。 如果Bucket索引+分区表的模式无法平衡Bueckt桶过大的问题,还是可以继续采用Flink状态索引,按照规范去优化对应的配置参数即可。 基于Bucket索引的表,按照单个Bucket 2GB数据量进行设计。 为了规避单个Bucket过大,建议单个Bucket的数据量不要超过2GB(该2GB是指数据内容大小,不是指数据行数也不是parquet的数据文件大小),目的是将对应的桶的Parquet文件大小控制在256MB范围内(平衡读写内存消耗和HDFS存储有效利用),因此可以看出2GB的这个限制只是一个经验值,因为不同的业务数据经过列存压缩后大小是不一样的。 为什么建议是2GB? 2GB的数据存储成列存Parquet文件后,大概的数据文件大小是150MB ~ 256MB左右。不同业务数据会有出入。而HDFS单个数据块一般会是128MB,这样可以有效的利用存储空间。 数据读写占用的内存空间都是原始数据大小(包括空值也是会占用内存的),2GB在大数据计算过程中,处于单task读写可接受范围之内。 如果是单个Bucket的数据量超过了该值范围,可能会有什么影响? 读写任务可能会出现OOM的问题,解决方法就是提升单个task的内存占比。 读写性能下降,因为单个task的处理的数据量变大,导致处理耗时变大。
  • 建议 基于Flink的流式写入的表,在数据量超过2亿条记录,采用Bucket索引,2亿以内可以采用Flink状态索引。 参照Flink状态索引的特点,Hudi表超过一定数据量后,Flink作业状态后端压力很大,需要优化状态后端参数才能维持性能;同时由于Flink冷启动的时候需要遍历全表数据,大数据量也会导致Flink作业启动缓慢。因此基于简化使用的角度,针对大数据量的表,可以通过采用Bucket索引来避免状态后端的复杂调优。 如果Bucket索引+分区表的模式无法平衡Bueckt桶过大的问题,还是可以继续采用Flink状态索引,按照规范去优化对应的配置参数即可。 基于Bucket索引的表,按照单个Bucket 2GB数据量进行设计。 为了规避单个Bucket过大,建议单个Bucket的数据量不要超过2GB(该2GB是指数据内容大小,不是指数据行数也不是parquet的数据文件大小),目的是将对应的桶的Parquet文件大小控制在256MB范围内(平衡读写内存消耗和HDFS存储有效利用),因此可以看出2GB的这个限制只是一个经验值,因为不同的业务数据经过列存压缩后大小是不一样的。 为什么建议是2GB? 2GB的数据存储成列存Parquet文件后,大概的数据文件大小是150MB ~ 256MB左右。不同业务数据会有出入。而HDFS单个数据块一般会是128MB,这样可以有效的利用存储空间。 数据读写占用的内存空间都是原始数据大小(包括空值也是会占用内存的),2GB在大数据计算过程中,处于单task读写可接受范围之内。 如果是单个Bucket的数据量超过了该值范围,可能会有什么影响? 读写任务可能会出现OOM的问题,解决方法就是提升单个task的内存占比。 读写性能下降,因为单个task的处理的数据量变大,导致处理耗时变大。
  • 规则 禁止修改表索引类型。 Hudi表的索引会决定数据存储方式,随意修改索引类型会导致表中已有的存量数据与新增数据之间出现数据重复和数据准确性问题。常见的索引类型如下: 布隆索引:Spark引擎独有索引,采用bloomfiter机制,将布隆索引内容写入到Parquet文件的footer中。 Bucket索引:在写入数据过程中,通过主键进行Hash计算,将数据进行分桶写入;该索引写入速度最快,但是需要合理配置分桶数目;Flink、Spark均支持该索引写入。 状态索引:Flink引擎独有索引,是将行记录的存储位置记录到状态后端的一种索引形式,在作业冷启动过程中会遍历所有数据存储文件生成索引信息。 用Flink状态索引,Flink写入后,不支持Spark继续写入。 Flink在写Hudi的MOR表只会生成log文件,后续通过compaction操作,将log文件转为parquet文件。Spark在更新Hudi表时严重依赖parquet文件是否存在,如果当前Hudi表写的是log文件,采用Spark写入就会导致重复数据的产生。在批量初始化阶段 ,先采用Spark批量写入Hudi表,在用Flink基于Flink状态索引写入不会有问题,原因是Flink冷启动的时候会遍历所有的数据文件生成状态索引。 实时入湖场景中,Spark引擎采用Bucket索引,Flink引擎可以用Bucket索引或者状态索引。 实时入湖都是需要分钟内或者分钟级的高性能入湖,索引的选择会影响到写Hudi表的性能。在性能方面各个索引的区别如下: Bucket索引 优点:写入过程中对主键进行hash分桶写入,性能比较高,不受表的数据量限制。Flink和Spark引擎都支持,Flink和Spark引擎可以实现交叉混写同一张表。 缺点:Bucket个数不能动态调整,数据量波动和整表数据量持续上涨会导致单个Bucket数据量过大出现大数据文件。需要结合分区表来进行平衡改善。 Flink状态索引 优点:主键的索引信息存在状态后端,数据更新只需要点查状态后端即可,速度较快;同时生成的数据文件大小稳定,不会产生小文件、超大文件问题。 缺点:该索引为Flink特有索引。在表的总数据行数达到数亿级别,需要优化状态后端参数来保持写入的性能。使用该索引无法支持Flink和Spark交叉混写。 对于数据总量持续上涨的表,采用Bucket索引时,须使用时间分区,分区键采用数据创建时间。 参照Flink状态索引的特点,Hudi表超过一定数据量后,Flink作业状态后端压力很大,需要优化状态后端参数才能维持性能;同时由于Flink冷启动的时候需要遍历全表数据,大数据量也会导致Flink作业启动缓慢。因此基于简化使用的角度,针对大数据量的表,可以通过采用Bucket索引来避免状态后端的复杂调优。 如果Bucket索引+分区表的模式无法平衡Bueckt桶过大的问题,还是可以继续采用Flink状态索引,按照规范去优化对应的配置参数即可。
  • 索引设计规范 使用数据库索引实践推荐的索引类型。 索引设计建议使用推荐类型,如果需要使用禁用、不推荐、限制使用的索引类型,建议联系GaussDB数据库专家进行评估。 表1 数据库索引实践推荐 索引类型 说明 是否推荐 主键/唯一索引 单列或多列主键/唯一索引 推荐 表达式索引 索引列为表的一列或多列计算而来的一个函数或者标量表达式 限制使用 对于HASH分布表,主键和唯一索引必须包含分布键。 当设计组合索引时,优化器会通过计算代价来选择合适的执行计划。例如:在组合索引(a,b,c)下,当查询时如果只使用过滤条件b,优化器经过计算索引成本较低时,会选择索引。 不建议单表创建多个唯一索引。 同时维护多个唯一索引的开销远大于维护一个多列唯一索引,如果业务逻辑上多个唯一索引,与一个多列唯一索引等价,应使用多列唯一索引。 组合索引字段个数不超过5个。 禁止组合索引组合字符串的总长度超过200。 索引(包括单列索引和复合索引)字段应为NOT NULL字段。 同字段上创建索引的维护效率不同。数值类型字段优于字符类型及其他数据类型,因此对于考虑创建索引的ID、时间等字段,建议使用数值类型进行存储。 建议在关联列上创建索引。 GaussDB支持HASH JOIN,但是当内表较小等RESCAN代价较低的情况下,仍然可能选择NESTLOOP JOIN来完成关联。如果通过EXPLAIN可以查看到NESTLOOP JOIN计划,则可以通过在关联列上创建索引,提高NESTLOOP JOIN效率。 父主题: 数据库设计规范
  • 库表规范 所有创建的MySQL表必须为InnoDB引擎,适配MySQL的其它引擎不支持事务。 小数类型为decimal,禁止使用float和double。 float和double在存储的时候,存在精度损失的问题,很可能在值比较的时候得到的结果有误。如果存储的数据范围超过decimal的范围,建议将数据拆成整数和小数分开存储。 禁用保留字,如desc、range、match、delayed等,请参考保留关键字。 数据表必须有主键,可以使用业务相关,有序且具有唯一性的字段作为主键,也可以使用业务无关的自增长字段作为主键。 表字段必须有默认值加NOT NULL,数字类型默认值推荐给0,varchar等字符类型默认值推荐空字符串''。 无主键不仅容易导致主库执行速度慢和复制延迟问题。 避免使用分区表,如有需要,可以使用多个独立的表代替。 分区表的缺点: DDL操作需要锁定所有分区,导致所有分区上操作都被阻塞。 当表数据量较大时,对分区表进行DDL或其他运维操作难度大风险高。 分区表使用较少,存在未知风险。 当单台服务器性能无法满足时,对分区表进行分拆的成本较高。 当分区表操作不当导致访问所有分区时,会导致严重的性能问题。 建议表包含两个字段:create_time,update_time, 且均为datetime类型。 数据仓库拖取数据时可以利用这两个统一字段无需询问业务。 在数据库出现意外时可以判断数据进入数据库和修改的时间,在极端情况可以帮助数据恢复的判断。 varchar是可变长字符串,不预先分配存储空间,长度不要超过2048。 如果存储长度大于此值,定义字段类型为text,或者独立出来一张表,用主键来对应,避免影响其他字段索引效率。 表单行行内长度不得超过1024字节。 控制单表字段数量,字段上限50个。 如果存储的字符串长度几乎相等,使用char定长字符串类型。 字段允许适当跨表冗余,以避免关联查询,提高查询性能,但必须考虑数据一致。 冗余字段应遵循: 不是频繁修改的字段。 不是varchar超长字段和text字段。 合适的存储长度(不建议使用LONG TEXT, BLOB等长类型字段),不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。 父主题: 设计规范
  • 保留关键字 GaussDB(for MySQL)的保留关键字在兼容社区MySQL8.0的基础上,新增了部分保留关键字,需要在业务使用中避免使用保留关键字来命名。 社区MySQL 8.0的保留字与关键字请参见关键字和保留字。 GaussDB(for MySQL)新增的关键字和保留字如表1所示。 表1 GaussDB(for MySQL)新增的保留关键字 保留字 相关场景 EXTRA_HEALTH 高可用 PBS 备份恢复 REDO 主从复制 SLICEID 共享存储 SLOWIO 共享存储 SPACEUSAGE 共享存储 RDS_INSTANT 回收站 RECYCLE_BIN 回收站 RDS_RECYCLE 回收站 RDS_TAC 回收站 RDS_GDB_CTRL RegionlessDB 父主题: 设计规范
  • 数据库特性规范 表1 数据库价值特性推荐 特性分类 特性列表 说明 表类型 HASH分布表 自动分片的表,建议数据量大的表使用(如交易记录)。 REPLICATE分布表 不分片的普通表,建议数据少的表使用(如国家名称表)。 事务 分布式事务(弱一致) GTM Free模式,在sharding场景下可保证强一致,不保证跨DN分片读一致性。建议完美sharding业务使用。 分布式事务(强一致) GTM Lite模式,保证跨DN读写一致性,建议非完美sharding业务使用。 扩容 在线平滑扩容 在线业务的最大阻塞小于5s,主要是为了追增切换期间写入日志,扩容速度100G/小时。 部署 3AZ3副本 建议默认采用3AZ3副本部署。 数据类型 整数类型 TINYINT, SMALLINT, INTEGER, BIGINT 任意精度类型 NUMERIC/DECIMAL 浮点类型 REAL/FLOAT4,DOUBLE PRECISION/FLOAT8,FLOAT 布尔类型 BOOLEAN 定长字符 CHAR(n) 变长字符 VARCHAR(n),NVARCHAR2(n), TEXT 时间类型 DATE, TIME, TIMETZ, TIMESTAMP, TIMESTAMPTZ, SMALLDATETIME, INTERVAL, REALTIME 二进制类型 BYTEA(变长二进制类型) 位串类型 BIT(n), VARBIT(n) 函数 字符处理函数 字符类数据类型处理函数 二进制字符串函数 二进制字符类型处理函数 数字操作函数 数值类型处理函数 时间和日期处理函数 时间和日期类型处理函数 索引 主键/唯一索引 单列或多列主键/唯一索引 BTREE索引 索引类型 未包含在价值列表中的特性(包括但不限于自定义,UUID等数据类型,触发器等特性),如需使用建议联系GaussDB 数据库技术人员进行评估。
  • 索引规范 避免因为字段类型不同造成的隐式转换,导致索引失效。 业务上具有唯一特性的字段,即使是多个字段的组合,建议在所有具有唯一特性字段的最小集合上建立唯一索引。 例如:一个表含有有a,b,c,d,e,f字段,在业务上ab和ef分别是具有唯一特性的字段集合,那么最好在最小集合ab和ef上分别建立唯一索引。 即使在应用层做了完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。 同时需要考虑建立的唯一索引对查询是否真正有帮助,没有帮助的索引可以考虑删除; 需要考虑多建立的索引对插入性能的影响,根据唯一性相关的数据正确性需求,以及性能需求来权衡是不是需要多建立唯一性索引。 尽量在定长的字段(如:INT)上建立索引;在varchar字段上建立索引时,必须指定索引长度,无需对全字段建立索引,根据实际文本区分度决定索引长度即可。 索引长度与区分度是一对矛盾体,一般对字符串类型数据,长度为20的索引区分度会高达90%以上,可以使用count(distinct left(列名,索引长度))/count(*)的区分度来确定。(有区分度的放前面,没有区分度的放后面)。 页面搜索避免使用左模糊(如:SELECT * FROM users WHERE u_name LIKE ‘%hk’)或者全模糊,避免从索引扫描退化为全表扫描,如果需要请在应用层解决。 索引文件具有B-tree的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。 利用覆盖索引来进行查询操作,避免回表,但是覆盖索引加的字段不能太多,要兼顾写性能。 能够建立索引的种类:主键索引、唯一索引、普通索引,而覆盖索引是一种查询的效果,利用explain的结果,extra列会出现:using index。 SQL性能优化的目标:至少要达到range级别,要求是ref级别,如果可以是consts最好。 创建组合索引的时候,区分度最高的在左边。 单张表的索引数量控制在5个以内,或不超过表字段个数的20%。 创建索引避免有如下误解: 宁滥勿缺。误认为一个查询就需要建一个索引。 宁缺勿滥。误认为索引会消耗空间、严重拖慢更新和新增速度。 抵制唯一索引。误认为业务的唯一性一律需要在应用层通过“先查后插”方式能解决。 父主题: 设计规范
  • 字段设计规范 字段设计应使用推荐类型。 字段设计需使用推荐字段,如果需要使用禁用、不推荐的字段类型,建议联系技术支持进行评估。 这些数据类型不推荐或禁止的原因是业务使用场景较少,未大规模商用。 对于业务上有迫切字段类型要求的,联系技术支持,提交需求。 表1 数据库数据类型最佳实践 数据类型 说明 是否推荐 UUID 不同集群可能产生相同UUID 禁止,建议业务直接采用中间件平台提供的分布式ID 序列整型 即自增列,包括SMALLSERIAL,SERIAL,BIGSERIAL 禁止 整数类型 TINYINT, SMALLINT, INTEGER, BIGINT 推荐 任意精度类型 NUMERIC/DEMICAL 推荐 浮点类型 REAL/FLOAT4,DOUBLE PRECISION/FLOAT8,FLOAT 推荐 布尔类型 BOOLEAN 推荐 定长字符 CHAR(n) 推荐 变长字符 VARCHAR(n),NVARCHAR2(n) VARCHAR/TEXT 推荐 时间类型 DATE, TIME, TIMESTAMP, SMALLDATETIME, INTERVAL, REALTIME 推荐 TIMETZ,TIMESTAMPTZ 不推荐 二进制类型 BYTEA(变长二进制类型) 推荐 CLOB(字符大对象),BLOB(二进制大对象),RAW(变长十六进制) 禁止 位串类型 BIT(n), VARBIT(n) 推荐 特殊字符类型 NAME,"CHAR",通常供数据库系统内部使用 禁止 JSON类型 JSON类型目前不支持操作符 禁止 自定义类型 可用于定义枚举EMU等类型 禁止 HLL数据类型 建议直接使用HLL相关函数,减少性能影响 禁止 货币类型 MONEY 存储带有固定小数精度的货币金额 禁止 几何类型 POINT, LSEG, BOX, PATH, POLYGON, CIRCLE 禁止 网络地址类型 存储IPV4 IPV6 MAC地址数据类型 禁止 文本搜索类型 用于支持全文检索 禁止 合理选用字符串数据类型。优先使用变长字符类VARCHAR。只有该字段输入确定为固定字符则使用定长字符类型,或需要自动补充空格,才使用CHAR(n)。 典型的定长字段类型,例如“sex”字段,仅允许输入“f”或“m”一个字节长度的字符。这类字段建议使用定长数据类型(如CHAR(n))。 如果不存在此特点,或者后续可能扩展需要输入更长的字符,请优先使用变长字符类型(如VARCHAR, TEXT),且不建议指定变长类型的长度。 原因如下: 定长字段会对不够长度的输入数据补充空格,然后存入数据库中,产生不必要的存储空间浪费。 如果定义为定长字符类型,后续扩展长度,需要对全表进行扫描重写,性能开销大,影响在线业务。 对于指定固定长度的变长字段,每次插入时会检查是否长度越界,带来性能开销。 字符类型字段不应存储数字类型的数据。 如果对存储在字符类型字段中的数据进行数值计算,或者与数值进行比较操作(如置于过滤条件中),会带来不必要的数据类型转换的开销,同时该字段上的索引可能失效,影响查询性能。 字符类型字段不应存储时间或日期类数据。 如果对存储在字符类型字段中的数据与日期类数据进行计算或比较操作(如置于过滤条件中),会带来不必要的数据类型转换的开销,同时该字段上的索引可能失效,影响查询性能。 对于明确不存在NULL值的字段加上NOT NULL约束。 对于NOT NULL字段,优化器在某些场景下会进行特殊优化,可较大提升查询性能。 相关联字段的数据类型应保持一致。 在进行关联操作时,如果字段类型不一致,会带来数据类型转换开销。 大字段(例如varchar(1000)、varchar(4000))不建议超过8个。 字段定义时建议同时创建COMMENT注释信息,以便于未来维护。 不同类型字段说明、取值范围及使用方法请参考数据类型章节。 用于WHERE条件过滤和关联的字段都应设置NOT NULL约束。 对于NOT NULL字段,优化器在某些场景下会进行特殊优化,可较大提升查询性能。 不建议对表预留字段。大部分场景下可支持快速新增、删除表字段,或者修改字段的DEFAULT值。 新增列必须符合以下要求,否则会带来全表更新开销,影响在线业务。 数据类型为以下类型中的一种:BOOL, BYTEA, SMALLINT, BIGINT, SMALLINT, INTEGER, NUMERIC, FLOAT, DOUBLE PRECISION, CHAR, VARCHAR, TEXT, TIMESTAMPTZ, TIMESTAMP, DATE, TIME, TIMETZ, INTERVAL; 新增列的DEFAULT值长度不超过128个字节; 新增列DEFAULT值不包含volatile函数; 新增列设置有DEFAULT值,且DEFAULT值不为NULL。 如果不确定是否满足条件,请联系数据库技术人员进行评估。 尽量使用高效的数值类数据类型。在满足业务精度的情况下,选择的优先级从高到低依次为整数、浮点数、NUMERIC。 合理设置数值字段的数据类型,根据取值范围选择合适的数值类型,尽量少用NUMERIC/DECIMAL类型。 NUMERIC和DECIMAL等价,NUMERIC(或DECIMAL)数据类型操作对CPU消耗较高。 表2 数值类数据类型存储空间及取值范围 类型 存储空间/Byte 最小值 最大值 TINYINT 1 0 255 SMALLINT 2 -32768 32767 INTEGER 4 -2,147,483,648 2,147,483,647 BIGINT 8 -9,223,372,036,854,775,808 9,223,372,036,854,775,807 REAL/FLOAT4 4 6位十进制数字精度 DOUBLE PRECISION/FLOAT8 8 15位十进制数字精度 父主题: 数据库设计规范