GaussDB数据库开发设计建议

举报
yd_246436088 发表于 2025/11/26 09:44:05 2025/11/26
【摘要】 1.1  总结本文档围绕 GaussDB 数据库开发设计展开,核心涵盖数据库对象命名和设计建议、表设计最佳实践、SQL 查询最佳实践三大模块:命名层面建议避免关键字、统一风格(如表名用下划线分隔,临时表前缀tmp_),Schema&Database 设计推荐用 Schema 做业务隔离、创建 Database 时选 UTF-8 编码及关注 4 种兼容模式;表设计需合理选择Hash/Repli...


1.1  总结

本文档围绕 GaussDB 数据库开发设计展开,核心涵盖数据库对象命名和设计建议表设计最佳实践SQL 查询最佳实践三大模块:命名层面建议避免关键字、统一风格(如表名用下划线分隔,临时表前缀tmp_),Schema&Database 设计推荐用 Schema 做业务隔离、创建 Database 时选 UTF-8 编码及关注 4 种兼容模式;表设计需合理选择Hash/Replication/Range/List 分布策略(如大表用 Hash、小表用 Replication)、优化分布列(避免数据倾斜,差异超 10% 需调整)及使用分区表;SQL 查询则需优化 WHERE 子句(避免隐式类型转换、不用函数操作索引列)、SELECT/INSERT/UPDATE/DELETE 等子句(如批量 INSERT 用多值语法,DELETE 避免全表扫描),同时控制事务和子查询复杂度,确保开发设计高效、合规。

 

1.2   思维导图(mindmap


 

 

1.3   详细总结

一、数据库对象命名和设计建议

1. 数据库对象命名建议

建议类别

具体内容

关键说明

 

避免关键字

不使用保留 / 非保留关键字命名对象

可通过select * from pg_get_keywords()查询关键字

 

名称大小写

避免双引号定义名称(除非需限制大小写)

大小写敏感增加问题定位难度

 

统一风格

1. 多单词用下划线分隔;2. 望文知意,少自定义缩写;3. 变量名带类型前缀

增量 / 迁移系统遵守历史风格,集群内规则统一

 

表名规则

- 普通表:按业务含义命名

 

- 临时表:tmp_+后缀

 

- 非日志表:ul_+后缀

 

- 外表:f_+后缀

 

- redis_前缀

明确表类型,便于维护

 

2. Schema&Database 设计建议

1Database 设计

规则 / 建议

具体内容

关键数字 / 说明

 

创建规则

不直接用默认 postgres 数据库,按需新建

-

 

编码建议

UTF-8 编码

适配全球化,存储绝大多数字符

 

核心配置

关注ENCODING(字符集) DBCOMPATIBILITY(兼容模式)

支持 4 种模式:TDTeradata)、ORAOracle)、MySQLPGPostgreSQL),默认 MySQL

 

权限关注

Database owner 默认拥有所有对象的删除权限

删除权限影响大,需谨慎

 

2Schema 设计

             权限控制:非 sysadmin / owner 用户访问 Schema 下对象,需同时拥有 Schema usage权限和对象的对应操作权限;创建对象需create权限。

             权限风险Schema owner 默认拥有该 Schema 下所有对象的删除权限,需严格管控。

3. 表、字段、约束及视图设计建议

1)表设计核心关注

             数据均匀分布:通过合理选择分布列,避免数据集中在部分 DN(存储倾斜导致集群容量下降)。

             扫描压力分散:避免等值过滤集中扫描部分 DN,产生性能瓶颈。

             减少扫描量:用分区表剪枝机制,大幅降低数据扫描范围。

             减少随机 I/O:通过聚簇 / 局部聚簇(PCK)将热数据连续存储,转为连续 I/O

             避免数据 shuffle:优化关联 / 分组条件,减少节点间数据传输(节省网络资源,提升性能)。

2)字段设计建议

             高效类型优先:满足业务精度下,选择优先级为整数 > 浮点数 > NUMERIC(如 numeric 列改 int 后,点查询时间从 10+s 降至 1.8s)。

             关联字段统一:多表中同一含义的字段,需用相同数据类型(避免隐式转换消耗性能)。

             字符串类型:优先用变长类型(如 VARCHAR)并指定最大长度(需大于实际最大字符数,避免截断);禁选 CHAR (n) 等固定长度类型(除非明确数据长度固定)。

3)约束设计建议

约束类型

具体建议

适用范围 / 关键说明

 

DEFAULT/NULL

- 业务可补全值则不用 DEFAULT

 

- NULL 值字段加NOT NULL(优化器自动优化)

-

 

局部聚簇(PCK

- 仅列存表支持,一张表仅 1 PCK,列数≤2

 

- 建在col op const过滤条件列(op =/>/≥/≤/<

 

- distinct 值多的列

min/max 稀疏索引实现快速过滤

 

唯一约束

- 仅行存表支持

 

- 命名规则:UNI+构成字段

确保字段值唯一

 

主键约束

- 仅行存表支持

 

- 命名规则:PK+字段名

唯一标识表中记录

 

检查约束

- 仅行存表支持

 

- 命名规则:CK+字段名

限制字段值范围

 

4)视图和关联表设计

             视图:避免嵌套(除非强依赖)、少用排序操作。

             关联表:关联字段少、类型一致、命名体现关联关系(如同名)。

二、表设计最佳实践

1. 分布策略选择

分布策略

描述

适用场景

优缺点

Hash

按字段 Hash 值映射到各 DN

数据量大的事实表(如订单表)

优点:读写利用多 DN IO,速度快;缺点:分布列选差易倾斜

Replication

DN 存全量表数据

小表、维度表(如字典表)

优点:Join 避免数据重分布,减少网络开销;缺点:数据冗余

Range

按字段值范围映射到 DN

用户自定义分布规则场景(如按日期范围分 DN

优点:灵活;缺点:需用户具备数据抽象能力

List

按字段具体值映射到 DN

用户自定义分布规则场景(如按地区值分 DN

优点:灵活;缺点:需用户具备数据抽象能力

2. 分布列选择(Hash 表核心)

             选择原则1. 列值离散(如主键,确保数据均匀);2. 优先选查询中的连接条件(减少 DN 间通信)。

             倾斜检查:执行select xc_node_id, count(1) from tablename group by xc_node_id order by xc_node_id desc;不同 DN 数据量差超 5% 视为倾斜,超 10% 必须调整分布列

             特性支持GaussDB Kernel 支持多分布列,提升数据分布均匀性。

3. 分区表使用

             定义:逻辑表分物理块存储,数据存于分区,逻辑表不存数据。

             支持类型:仅范围分区表(按分区键范围映射,如按月份分销售数据)。

             优点1. 提升查询性能(仅扫目标分区);2. 增强可用性(单个分区故障不影响其他);3. 简化维护(仅修复故障分区)。

             缺点:索引扫描代价较高。

             建议:业务表优先按时间或地区 Range 分区。

4. 数据类型选择(高效原则)

优化方向

具体建议

收益

 

优先高效类型

整型运算效率 > 字符串 / 浮点数

减少计算耗时

 

用短字段类型

smallint 替代 intint 替代 bigint

减小数据文件大小,降低 IO 和内存消耗

 

关联列同类型

避免数据库动态转换类型

减少性能开销

 

5. 分布式事务设计

             核心原则分布式数据库业务必走分布式,业务改动量小时,优先设计单机事务(提升性能、并发,降低复杂度)。

             示例user_account(用户 ID、余额)和log_account(用户 ID、操作日志)均以用户 ID 为分布列,产生单机事务;禁user_account按用户 IDlog_account action 分布(跨节点事务)。

三、SQL 查询最佳实践

1. WHERE 子句最佳实践

建议

具体要求

反面示例

正确示例

含分布键等值条件

确保 DN 裁剪,避免全 DN 执行

无分布键条件

where user_id = 123user_id 为分布列)

避免隐式类型转换

字段类型与条件值类型一致

where phonenumber = 13512345678phonenumber VARCHAR

where phonenumber = '13512345678'

不用函数 / 表达式操作索引列

避免索引失效、全表扫描

where abs(income) > 1000

where income > 1000 or income < -1000

LIKE 语法规范

不将 % 放首字符

where name like '%'

where name like '%'

IN 候选限制

候选子集≤500

where id in (1,2,...,501)

拆分 SQL 或用其他过滤方式

避免 NULL 比较错误

不用!= NULL,用IS NOT NULL

where col1 != NULL

where col1 IS NOT NULL

2. SELECT 子句最佳实践

             禁通配符*:仅查询需用字段,减少数据传输。

             少用count()查大表行数:避免全表扫描。

             不用子查询在目标列:可能导致计划无法下推,影响性能。

             统计表行数用count(*):不用count(col)col NULL 时结果不准确)。

             避免大字段排序:如ORDER BY/GROUP BY操作大字段(如 TEXT),消耗资源。

3. INSERT 子句最佳实践

             批量插入用多值语法:INSERT INTO TABLE1 VALUES (),(),()效率高于多条INSERT INTO VALUES()

               INSERT ON DUPLICATE KEY UPDATE限制:1. 不更新主键 / 唯一约束列;2. 批量插入数据间无主键 / 唯一约束冲突;3. 禁用于多唯一约束表。

4. UPDATE 子句最佳实践

             必须有 WHERE 子句:避免全表更新。

             结合主键 / 索引:WHERE 条件用主键或索引列,提升效率。

             禁多表更新:不支持多表关联更新。

             LIMIT/ORDER BY/GROUP BY:避免不必要排序或目标行不明确。

             禁更新列作为更新源:如update t set a = a + 1, b = ab 用更新后 a 的值,逻辑风险)。

5. DELETE 子句最佳实践

             必须有 WHERE 子句:避免全表删除。

             TRUNCATE 清表:比 DELETE 高效(TRUNCATE 直接删物理文件,DELETE 仅标记数据,需 VACCUUM FULL 清理)。

             LIMIT / 多表删除:不支持 LIMIT,且不能单条 SQL 删多表。

             ORDER BY/GROUP BY:避免不必要排序。

             GTM-FREE 模式限制:删 Hash 表需指定分布列等值条件(禁跨节点事务)。

6. 关联查询、子查询与事务最佳实践

1)关联查询

             嵌套深度 < 8 层:避免复杂度过高。

             明确定义连接方式:用INNER JOIN/LEFT JOIN等,不用默认 JOIN(避免笛卡尔积)。

             表加别名:多表关联时用别名,逻辑清晰。

             关联列处理:1. 同数据类型;2. 含大量 NULL 时加IS NOT NULL过滤。

             少用嵌套子查询:优先表关联(子查询产生临时表,影响性能)。

2)子查询

             禁重复子查询:同一条 SQL 中不出现相同子查询(重复计算,浪费资源)。

             少用标量子查询:如where id = (select id from t2 LIMIT 1),建议拆分为两条 SQL

             嵌套深度≤2 层:减少临时表开销,复杂查询从业务逻辑优化。

             禁子查询在 SELECT 目标列:影响计划下推,降低性能。

3)事务

             GTM-FREE 模式限制:禁跨节点事务(如多 DN 操作),否则报错。

             大对象操作无事务:如CREATE/DROP DATABASEANALYZEVACUUM不支持事务。

             JDBC 执行规范:不拼接多条 SQL 为一条执行(中间操作失败可能重新开事务,逻辑混乱)。

 

1.4   关键问题

问题 1GaussDB Hash 分布表的分布列该如何选择?若数据倾斜需如何判断和处理?

答案

             分布列选择原则1. 优先选列值离散度高的字段(如主键、唯一键,确保数据均匀分布到各 DN);2. 其次选查询中频繁作为连接条件的字段(减少 DN 间数据 shuffle,降低网络开销)。

             数据倾斜判断:执行 SQL select xc_node_id, count(1) from tablename group by xc_node_id order by xc_node_id desc;,统计各 DNxc_node_id 对应 DN)的数据量,不同 DN 数据量差异超 5% 视为轻微倾斜,超 10% 必须调整分布列

             处理方式1. 更换分布列(选更离散的字段,如将性别改为用户 ID”);2. 使用 GaussDB Kernel 多分布列特性(通过多个字段的 Hash 值共同映射 DN,提升分布均匀性)。

问题 2:在 GaussDB SQL 开发中,WHERE 子句存在哪些常见性能风险?如何规避这些风险?

答案

             常见性能风险1. 隐式数据类型转换(导致索引失效、DN 无法裁剪);2. 对索引列使用函数 / 表达式(如abs(income) > 1000,索引失效,全表扫描);3. LIKE 查询左置 %(如like '%',无法走索引);4. 缺少分布键等值条件(计划下发到所有 DN,资源浪费);5. IN 候选子集超 500(执行效率骤降);6. != NULL判断非空(语法错误,且无法走索引)。

             规避措施1. 确保字段类型与条件值一致(如 VARCHAR 字段用字符串条件,phonenumber = '13512345678');2. 索引列条件避免函数 / 表达式,改为字段直接比较(如income > 1000 or income < -1000替代abs(income) > 1000);3. LIKE 查询 % 右置(like '%');4. 必含分布键等值条件(如user_id = 123user_id 为分布列);5. IN 候选超 500 时拆分 SQL 或用其他过滤逻辑;6. 非空判断用IS NOT NULL

问题 3GaussDB 分区表的适用场景是什么?使用时需注意哪些要点?

答案

             适用场景1. 数据量较大且有明确分区维度(如按时间分区的销售表、按地区分区的用户表);2. 查询常聚焦于部分数据(如仅查 “2024 10 的销售数据,可通过分区剪枝减少扫描量);3. 需提升可用性和维护效率(如单个分区故障不影响其他数据,修复仅针对故障分区)。

             使用要点1. 仅支持范围分区:需指定分区键(如日期、数值范围),不支持哈希分区等其他类型;2. 分区键选择:优先按时间或地区(业务查询高频维度),确保分区剪枝效果;3. 索引注意事项:分区表索引扫描代价较高,查询若依赖索引需评估性能;4. 数据管理:分区表是逻辑表,数据实际存于物理分区,删除 / 备份可按分区操作(如删除 “2023 的历史分区),简化维护。

 

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。