Skip to content

适用虚谷数据库版本

v12.9



适用虚谷数据库版本

v12.9


对象设计规范

📄字数 3.8K
👁️阅读量 加载中...

在进行数据库开发时,开发人员会创建各类数据库对象,本文档旨在统一开发时对各类对象的设计原则,确保数据库具备高可维护性、高性能与高扩展性。

一、表结构设计

表是数据库开发人员最常用的对象之一,是关系型数据库的核心,其结构设计的优劣直接决定了系统的性能和稳定性。开发过程中通常会设计各种表对数据库进行操作,本节针对表结构设计提出建议。

1.1 字符集选择

正确设置表的字符集是避免出现乱码和保证数据存储正确性的基础。

  • 推荐使用UTF8作为数据库、表、字段的统一字符集。
    • 原因:UTF8是8位Unicode转换格式,具有良好的国际兼容性,适合多语言环境。
  • 推荐在整个数据库流程上保证统一的字符集:数据库连接->数据库实例两个层面的字符集设置保持一致,从根源上杜绝乱码问题。

1.2 主键设计

主键是表的身份标识,用于唯一确定表中的每行数据,一个良好设计的主键对于表来说十分重要。

  • 强制性:关系数据库标准理论规定,每一张表都应当有一个主键。没有主键的表可能导致数据更新异常、重复的无意义数据或频繁的全表扫描,影响整体业务性能与稳定,属于设计缺陷。
  • 单一性:推荐使用单一字段构成的主键,不推荐使用复合主键。复合主键创建的二级索引较为复杂、占用空间更大,并且在关联查询中很不方便。
  • 无业务含义:推荐使用与业务无关的、自增的整数类型作为主键。
    • 优点:
      • 性能:数值型、持续递增的主键有利于索引的紧凑存储,实现高效插入。
      • 稳定性:业务相关的数据可能会发生变更,使用业务数据作为主键会导致级联修改,成本极高。
      • 匿名性:避免主键暴露业务信息。
  • 类型选择:
    • 对于未来数据量可能超过20亿的大型表选择BIGINT作为主键类型。
    • 对于中小型表,使用INTEGER
    • 不推荐使用GUID或可变字符串类型作为主键,无序性会导致索引插入时产生大量的随机I/O与页分裂,严重影响写入性能。

1.3 逻辑删除

为了保证数据的可追溯性和安全性,应采用逻辑删除方式代替物理删除。

  • 实现方式:在表中增加一个删除标记字段,推荐使用TINYINT类型。
  • 访问方式:推荐前台业务在查询、更新时,增加检查删除标记字段。
  • 优点:
    • 可恢复:误删除的数据可以快速恢复。
    • 审计与分析:保留完整的数据记录,便于问题排查与数据溯源、分析。
    • 保持关联:避免因主表数据物理删除而导致关联表出现数据孤岛。

1.4 表的拆分

当单表的数据量过大时,会导致查询和维护困难,此时需要考虑对表进行拆分,可分为垂直拆分与水平拆分。

  • 垂直拆分:

    • 场景:当一个表字段过多,并且包含访问频率较低的字段时。
    • 方法:将表的字段按照访问频率、业务关联性等特征,拆分为一个主表与一个或多个拓展表。主表包含访问最频繁的核心字段,拓展表包含不常用的字段或大对象字段,二者通过相同主键进行关联。
    • 优点:减少主表的字段数量,提高核心查询的I/O效率与缓存命中率。
  • 水平拆分:

    • 场景:当单表行数过多,即使存在索引与分区,仍然出现性能瓶颈时。
    • 方法:将表中给的行数据,按照一定的规则分散到多个结构相同的表中。
    • 优点:突破单表的存储与性能瓶颈,实现快速拓展。

1.5 范式与反范式策略

在进行表结构设计时,为了建立起冗余更小、结构更合理的数据库,研究人员提出数据库三大范式,其描述了数据库创建时要遵循一定的规范。

范式分级与应用

范式等级含义简述适用场景
第一范式(1NF)每一列原子性,不可再分所有表(基础)
第二范式(2NF)非主属性完全依赖主键事实表、数据仓库建模
第三范式(3NF)非主属性不依赖于其他非主属性日常业务表设计的推荐目标
BCNF/更高范式更严格的依赖消除高度复杂的数据一致性要求、模型分析

通常情况下,业务表默认遵循3NF,部分情况下可降低至2NF,但至少需要保持1NF

反范式策略

范式规定了数据库设计应当遵循的标准,然而在某些实际生产环境中,“完全范式化”虽然保证了数据的一致性与灵活性,但往往会导致系统在高并发或复杂分析场景下出现性能瓶颈,或导致复杂度大幅升高。因此,研究人员提出反范式策略,旨在避免完全范式化所带来的性能与复杂度问题。反范式策略是在性能、业务、运维的权衡下做出的工程选择。

反范式策略适用场景

  1. 高频查询/写入下的多表连接性能瓶颈

    • 冗余主表部分字段至子表/汇总表,减少关键路径上的连接次数。
  2. 聚合场景

    • 创建汇总表,定时与分表进行同步,维持计数、区间统计等信息,避免全表扫描。
  3. 历史快照与审计信息

    • 冗余快照数据,避免因主表更新而导致历史追溯失真。

反范式策略的注意事项

  • 冗余字段文档化:在表结构、字段中注释冗余字段的来源与同步方式。
  • 一致性:建议使用触发器、定时作业任务保证主表与冗余字段的同步。
  • 只读:冗余字段应只用于查询、聚合使用,不得作为数据来源。
  • 变更风险:当主表结构或业务逻辑变更时,同步评审所有相关冗余字段。

所有表的设计都推荐包含应有的注释,并在业务改变时相应修改注释。

二、字段结构设计

字段是表的最小数据单元,良好的字段结构设计能够有效的节约存储空间,提升查询时的性能。

在字段设计中,建议遵循以下原则:

  1. 选择最恰当的数据类型:在满足业务需求的前提下,选择存储空间最小的数据类型。

    • 整数:根据数值表示范围选择TINYINTSMALLINTINTEGERBIGINT,在存储空间不紧张的场景,使用BIGINT,防止未来出现溢出。
    • 字符串:使用VARCHAR类型,并设定一个合理的、贴近业务范围的最大长度,避免预留过多空间。
    • 浮点数:应当使用NUMERIC类型,不推荐使用FLOATDOUBLE类型,以防出现精度丢失。
    • 日期时间:使用DATETIMETIMESTAMP,避免直接使用字符串存储日期时间类型,容易造成不必要的隐式转换。
  2. 避免使用NULL值:除非业务逻辑明确需要表示未知状态,否则所有字段都应设置NOT NULL或给定默认值。

    • 原因:NULL值会增加逻辑查询的复杂程度,影响索引效率。
  3. 一致性:在不同表中代表同一业务含义的字段,应当统一使用相同的数据类型。

  4. 注释:推荐每个字段都增加详细注释,指明业务含义、单位、数值表示范围等信息。

  5. 字段冗余:指在数据库中有意地在多个位置存储相同数据的设计策略,其主要目的是通过减少表连接操作来提升查询性能。应当遵循以下原则;

    • 不是频繁修改的字段。
    • 不是存储大文本的字段。

三、分区表设计

当出现数据量较大且访问数据较为集中时,推荐在创建表时使用分区表。

3.1 适用场景

  • 大数据量:单表数据量>=1亿行,或单日写入>=100万行。
  • 冷热分离:需要按照时间、用户、地理位置等维度快速进行数据裁剪或数据迁移。
  • 合规留存:例如资金、审计等项目需要按照规定保留,且需要定期清理。

3.2 分区键设计原则

  1. 高命中:分区键必须是查询中使用最频繁的过滤条件,以实现分区裁剪。
  2. 低修改:避免使用频繁更新的字段作为分区键,会触发迁移。
  3. 唯一索引:分区表的唯一索引必须包含表分区的分区键。

3.3 分区类型

  • RANGE分区:最常用的分区类型,适合于按时间或连续数值范围进行分区。
  • LIST分区:适用于按地区、渠道等离散且固定的值进行分区。
  • HASH分区:用于将数据打散到不同分区,适用于业务范围不明显但希望I/O分散的场景,选择区分度大、在查询中出现频次最高的字段作为分区键。

分区表建议定期进行维护,如创建新分区、归档或删除过期分区。

四、索引设计

索引是数据库开发过程中提升查询性能的有效手段,但滥用索引也会导致写入性能降低并占用大量存储空间等问题,本节介绍在索引设计中建议遵守的规范和原则。

4.1 设计原则

  1. 目标明确:为WHEREJOINORDER BYGROUP BY子句中频繁使用的字段建立索引。

  2. 选择性:优先为区分度高的字段建立索引。区分度越高,索引的查询效率越高。

  3. 单列索引:

    • 建议对索引字段设置NOT NULL属性,通常根据业务定义默认值。
    • JOIN表达式中使用的字段,类型建议保持一致;在多表关联查询时,保证被关联字段上存在索引。
    • 建议将输入条件进行过滤,避免因大量结果集查找而导致的搜索空间爆炸。
  4. 复合索引:

    • 遵循“最左前缀”原则,将最常用、区分度最高的字段放在复合索引的最左侧。
    • 对过滤表达式中频繁使用的字段添加到索引后面,形成覆盖索引,避免回表。
    • 多列查询条件使用复合索引。

4.2 注意事项

  • 避免重复索引,冗余的索引影响写入性能,同时占用存储空间。
  • 在复合索引创建的前提下,无需再单独创建最左字段索引。
  • 减少分区表全局索引的定义,全局索引的维护代价高昂,不建议过多使用。
  • 当修改字段上的索引时,确认索引状态,处于有效或失效。

五、其他结构设计

对于其他的数据库对象,建议依照如下表格:

对象 / 主题主要规范与最佳实践
视图 (View)封装复杂 Join;避免视图嵌套。
存储过程 / 函数仅限批量或强事务场景;所有脚本纳入版本控制。
触发器 (Trigger)谨慎使用,仅用于审计或自动字段填充;需注明目的与性能评估。

六、数据库对象限制

本章针对 XuguDB 中各类数据库对象的设计与使用,列出关键限制与边界,帮助开发与运维团队在架构层面规避兼容性、性能或运行时错误。

限制项最大值/范围
最大标识符长度127 字节
最大用户口令长度127 字节
最大路径长度256 字节
单个字段最大长度非大对象:60000 字节
大对象:2GB
最大记录长度60000 字节
最大字段个数(每表)2040 列
嵌套事务最大级数32768 层
最大 X 日志记录长度65536 字节
OBJECT、VARRAY 类型成员数量65535 项
分区列最大数量32 列
索引记录最大长度4000 字节
最大字段数量(单查询)2047 个
包 ID 最大分配额度1048576(≈1M)

更多可自定义控制的对象限制请参阅系统配置章节。