暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

openGauss数据库对象设计建议

MTL 2022-11-19
789

1、数据库对象命名

数据库对象命名需要满足约束:非时序表长度不超过63个字节,时序表长度不超过53个字符,以字母或下划线开头,中间字符可以是字母、数字、下划线、$、#。

  • 【建议】避免使用保留或者非保留关键字命名数据库对象。

     说明: 可以使用select * from pg_get_keywords()查询openGauss的关键字,或者在关键字章节中查看。

  • 【建议】避免使用双引号括起来的字符串来定义数据库对象名称,除非需要限制数据库对象名称的大小写。数据库对象名称大小写敏感会使定位问题难度增加。

  • 【建议】数据库对象命名风格务必保持统一。

    • 增量开发的业务系统或进行业务迁移的系统,建议遵守历史的命名风格。
    • 建议使用多个单词组成,以下划线分割。
    • 数据库对象名称建议能够望文知意,尽量避免使用自定义缩写(可以使用通用的术语缩写进行命名)。例如,在命名中可以使用具有实际业务含义的英文词汇或汉语拼音,但规则应该在数据库实例范围内保持一致。
    • 变量名的关键是要具有描述性,即变量名称要有一定的意义,变量名要有前缀标明该变量的类型。
  • 【建议】表对象的命名应该可以表征该表的重要特征。例如,在表对象命名时区分该表是普通表、临时表还是非日志表:

    • 普通表名按照数据集的业务含义命名。
    • 临时表以“tmp_+后缀”命名。
    • 非日志表以“ul_+后缀”命名。
    • 外表以“f_+后缀”命名。
    • 不创建以redis_为前缀的数据库对象。
  • 不创建以mlog_和以matviewmap_为前缀的数据库对象。

  • 【建议】非时序表对象命名建议不要超过63字节。如果过该长度内核会对表名进行截断,从而造成和设置值不一致的现象。且在不同字符集下,可能造成字符被截断,出现预期外的字符。



openGauss中可以使用Database和Schema实现业务的隔离,区别在于Database的隔离更加彻底,各个Database之间共享资源极少,可实现连接隔离、权限隔离等,Database之间无法直接互访。Schema隔离的方式共用资源较多,可以通过grant与revoke语法便捷地控制不同用户对各Schema及其下属对象的权限。

  • 从便捷性和资源共享效率上考虑,推荐使用Schema进行业务隔离。
  • 建议系统管理员创建Schema和Database,再赋予相关用户对应的权限。


2、DATABASE设计建议

  • 【规则】在实际业务中,根据需要创建新的Database,不建议直接使用数据库实例默认的postgres数据库。
  • 【建议】一个数据库实例内,用户自定义的Database数量建议不超过3个。
  • 【建议】为了适应全球化的需求,使数据库编码能够存储与表示绝大多数的字符,建议创建Database的时候使用UTF-8编码。
  • 【关注】创建Database时,需要重点关注字符集编码(ENCODING)和兼容性(DBCOMPATIBILITY)两个配置项。openGauss支持A、B、C和PG四种兼容模式,分别表示兼容O语法、MY语法、TD语法和POSTGRES语法,不同兼容模式下的语法行为存在一定差异,默认为A兼容模式。
  • 【关注】Database的owner默认拥有该Database下所有对象的所有权限,包括删除权限。删除权限影响较大,请谨慎使用。


3、Schema设计建议

  • 【关注】如果该用户不具有sysadmin权限或者不是该Schema的owner,要访问Schema下的对象,需要同时给用户赋予Schema的usage权限和对象的相应权限。
  • 【关注】如果要在Schema下创建对象,需要授予操作用户该Schema的create权限。
  • 【关注】Schema的owner默认拥有该Schema下对象的所有权限,包括删除权限。删除权限影响较大,请谨慎使用。


4、表设计建议

openGauss的数据分布在各个DN上。总体上讲,良好的表设计需要遵循以下原则:

  • 【关注】将表数据均匀分布在各个DN上。数据均匀分布,可以防止数据在部分DN上集中分布,从而导致因存储倾斜造成数据库实例有效容量下降。通过选择合适的分布列,可以避免数据倾斜。
  • 【关注】将表的扫描压力均匀分散在各个DN上。避免扫描压力集中在部分DN上,而导致性能瓶颈。例如,在事实表上使用等值过滤条件时,将会导致扫描压力不均匀。
  • 【关注】减少需要扫描的数据量。通过分区表的剪枝机制可以大幅减少数据的扫描量。
  • 【关注】尽量减少随机I/O。通过聚簇/局部聚簇可以实现热数据的连续存储,将随机I/O转换为连续I/O,从而减少扫描的I/O代价。
  • 【关注】尽量避免数据shuffle。shuffle,是指在物理上,数据从一个节点,传输到另一个节点。shuffle占用了大量宝贵的网络资源,减小不必要的数据shuffle,可以减少网络压力,使数据的处理本地化,提高数据库实例的性能和可支持的并发度。通过对关联条件和分组条件的仔细设计,能够尽可能地减少不必要的数据shuffle。

选择存储方案

【建议】表的存储类型是表定义设计的第一步,客户业务类型是决定表的存储类型的主要因素,表存储类型的选择依据请参考表1

表 1 表的存储类型及场景

存储类型

适用场景

行存

  • 点查询(返回记录少,基于索引的简单查询)。
  • 增、删、改操作较多的场景。

列存

  • 统计分析类查询(关联、分组操作较多的场景)。
  • 即席查询(查询条件不确定,行存表扫描难以使用索引)。

选择分布方案

【建议】表的分布方式的选择一般遵循以下原则:

表 2 表的分布方式及使用场景

分布方式

描述

适用场景

Hash

表数据通过Hash方式散列到数据库实例中的所有DN上。

数据量较大的事实表。

Replication

数据库实例中每一个DN都有一份全量表数据。

维度表、数据量较小的事实表。

Range

表数据对指定列按照范围进行映射,分布到对应DN。

用户需要自定义分布规则的场景。

List

表数据对指定列按照具体值进行映射,分布到对应DN。

用户需要自定义分布规则的场景。

选择分区方案

当表中的数据量很大时,应当对表进行分区,一般需要遵循以下原则:

  • 【建议】使用具有明显区间性的字段进行分区,比如日期、区域等字段上建立分区。
  • 【建议】分区名称应当体现分区的数据特征。例如,关键字+区间特征。
  • 【建议】将分区上边界的分区值定义为MAXVALUE,以防止可能出现的数据溢出。

典型的分区表定义如下:

""CREATE TABLE staffS_p1
(
  staff_ID       NUMBER(6) not null,
  FIRST_NAME     VARCHAR2(20),
  LAST_NAME      VARCHAR2(25),
  EMAIL          VARCHAR2(25),
  PHONE_NUMBER   VARCHAR2(20),
  HIRE_DATE      DATE,
  employment_ID  VARCHAR2(10),
  SALARY         NUMBER(8,2),
  COMMISSION_PCT NUMBER(4,2),
  MANAGER_ID     NUMBER(6),
  section_ID     NUMBER(4)
)
PARTITION BY RANGE (HIRE_DATE)
( 
   PARTITION HIRE_19950501 VALUES LESS THAN ('1995-05-01 00:00:00'),
   PARTITION HIRE_19950502 VALUES LESS THAN ('1995-05-02 00:00:00'),
   PARTITION HIRE_maxvalue VALUES LESS THAN (MAXVALUE)
);

选择分布键

Hash表的分布键选取至关重要,如果分布键选择不当,可能会导致数据倾斜,从而导致查询时,I/O负载集中在部分DN上,影响整体查询性能。因此,在确定Hash表的分布策略之后,需要对表数据进行倾斜性检查,以确保数据的均匀分布。分布键的选择一般需要遵循以下原则:

  • 【建议】选作分布键的字段取值应该比较离散,以便数据能在各个DN上均匀分布。当单个字段无法满足离散条件时,可以考虑使用多个字段一起作为分布键。一般情况下,可以考虑选择表的主键作为分布键。例如,在人员信息表中选择证件号码作为分布键。
  • 【建议】在满足第一条原则的情况下,尽量不要选取在查询中存在常量过滤条件的字段作为分布键。例如,在表dwcjk相关的查询中,字段zqdh存在常量过滤条件“zqdh='000001'”,那么就应当尽量不选择zqdh字段作为分布键。
  • 【建议】在满足前两条原则的情况,尽量选择查询中的关联条件为分布键。当关联条件作为分布键时,join任务的相关数据都分布在DN本地,将极大减少DN之间的数据流动代价。


5、字段设计

选择数据类型

在字段设计时,基于查询效率的考虑,一般遵循以下原则:

  • 【建议】尽量使用高效数据类型。

    选择数值类型时,在满足业务精度的情况下,选择数据类型的优先级从高到低依次为整数、浮点数、NUMERIC。

  • 【建议】当多个表存在逻辑关系时,表示同一含义的字段应该使用相同的数据类型。

  • 【建议】对于字符串数据,建议使用变长字符串数据类型,并指定最大长度。请务必确保指定的最大长度大于需要存储的最大字符数,避免超出最大长度时出现字符截断现象。除非明确知道数据类型为固定长度字符串,否则,不建议使用CHAR(n)、BPCHAR(n)、NCHAR(n)、CHARACTER(n)。

    关于字符串类型的详细说明,请参见常用字符串类型介绍。

常用字符串类型介绍

在进行字段设计时,需要根据数据特征选择相应的数据类型。字符串类型在使用时比较容易混淆,下表列出了openGauss中常见的字符串类型:

表 1 常用字符串类型

名称

描述

最大存储空间

CHAR(n)

定长字符串,n描述了存储的字节长度,如果输入的字符串字节格式小于n,那么后面会自动用空字符补齐至n个字节。

10MB

CHARACTER(n)

定长字符串,n描述了存储的字节长度,如果输入的字符串字节格式小于n,那么后面会自动用空字符补齐至n个字节。

10MB

NCHAR(n)

定长字符串,n描述了存储的字节长度,如果输入的字符串字节格式小于n,那么后面会自动用空字符补齐至n个字节。

10MB

BPCHAR(n)

定长字符串,n描述了存储的字节长度,如果输入的字符串字节格式小于n,那么后面会自动用空字符补齐至n个字节。

10MB

VARCHAR(n)

变长字符串,n描述了可以存储的最大字节长度。

10MB

CHARACTER VARYING(n)

变长字符串,n描述了可以存储的最大字节长度;此数据类型和VARCHAR(n)是同一数据类型的不同表达形式。

10MB

VARCHAR2(n)

变长字符串,n描述了可以存储的最大字节长度,此数据类型是为兼容Oracle类型新增的,行为和VARCHAR(n)一致。

10MB

NVARCHAR2(n)

变长字符串,n描述了可以存储的最大字节长度。

10MB

TEXT

不限长度(不超过1GB-8203字节)变长字符串。

1GB-8203字节


6、约束设计

DEFAULT和NULL约束

  • 【建议】如果能够从业务层面补全字段值,那么,就不建议使用DEFAULT约束,避免数据加载时产生不符合预期的结果。
  • 【建议】给明确不存在NULL值的字段加上NOT NULL约束,优化器会在特定场景下对其进行自动优化。
  • 【建议】给可以显式命名的约束显式命名。除了NOT NULL和DEFAULT约束外,其他约束都可以显式命名。

局部聚簇

Partial Cluster Key(局部聚簇,简称PCK)是列存表的一种局部聚簇技术,在openGauss中,使用PCK可以通过min/max稀疏索引实现事实表快速过滤扫描。PCK的选取遵循以下原则:

  • 【关注】一张表上只能建立一个PCK,一个PCK可以包含多列,但是一般不建议超过2列。
  • 【建议】在查询中的简单表达式过滤条件上创建PCK。这种过滤条件一般形如col op const,其中col为列名,op为操作符 =、>、>=、<=、<,const为常量值。
  • 【建议】在满足上面条件的前提下,选择distinct值比较多的列上建PCK。

唯一约束

  • 【关注】行存表、列存表均支持唯一约束。
  • 【建议】从命名上明确标识唯一约束,例如,命名为“UNI+构成字段”。

主键约束

  • 【关注】行存表、列存表均支持主键约束。
  • 【建议】从命名上明确标识主键约束,例如,将主键约束命名为 “PK+字段名”。

外键约束

  • 【关注】行存表支持外键约束,列存表不支持外键约束。
  • 【建议】从命名上明确标识外键约束,例如,将外键约束命名为 “FK+字段名”。

检查约束

  • 【关注】行存表支持检查约束,而列存表不支持。
  • 【建议】从命名上明确标识检查约束,例如,将检查约束命名为 “CK+字段名”。


7、视图和关联表设计

视图设计

  • 【建议】除非视图之间存在强依赖关系,否则不建议视图嵌套。
  • 【建议】视图定义中尽量避免排序操作。

关联表设计

  • 【建议】表之间的关联字段应该尽量少。
  • 【建议】关联字段的数据类型应该保持一致。
  • 【建议】关联字段在命名上,应该可以明显体现出关联关系。例如,采用同样名称来命名。


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论