使用 OceanBase 数据库进行应用开发的路径如下:

  1. 径始于开发工具,它回答了“如何连接和操作数据库”这一最基本的问题。无论是命令行的 obclient、图形化的 ODC,还是集成到应用程序中的 JDBC 驱动,它们都是与 OceanBase 数据库交互的桥梁,为后续的所有工作提供了入口;
  2. 通过桥梁进入后,便面对数据库对象设计这一核心领域。这里决定了数据的组织方式和内在架构,是保证效率与可维护性的基石。对兼容模式、分区策略、表组和索引的规划,如同为数据建造一个结构合理、道路通畅的“城市”,确保了数据能够被高效地存储和访问;
  3. 在稳固的“城市”基础上,DML 与 DQL 语句是进行日常“市政管理”和“市民服务”的工具。数据的增删改查、以及通过多种连接查询进行复杂的数据关联与分析,都是在这里完成的,它直接支撑了上层业务逻辑的实现;
  4. 然而,随着“城市”规模扩大和“交通”日益复杂,性能瓶颈必然出现,这就引入了 SQL 调优这门“交通优化科学”。通过识别慢查询、解读执行计划,并运用索引和 Hint 等工具进行优化,确保了即使在数据量和并发量增长的情况下,数据库系统依然能够保持流畅和响应迅速;
  5. 最后,任何“城市”都不是孤岛,数据导入导出正是数据库与外界进行“贸易与交流”的港口。无论是通过 ODC 进行便捷的数据交换,还是使用 OBDumper/OBLoader 进行大规模迁移,抑或利用 LOAD DATA 和外部表进行高性能数据加载,这些工具实现了数据在 OceanBase 与外部系统间的安全、高效流动,完成了数据生命周期的闭环。

总的来说,这五个模块环环相扣:工具是手段,设计是蓝图,操作是实践,调优是保障,流转是扩展。通过理论与实际相结合,不仅能够熟练使用 OceanBase 进行应用开发,更能理解其设计哲学并根据业务需求对其进行有效的设计、优化和集成。

一、OceanBase 开发工具

1、客户端连接工具

OceanBase 提供了多种客户端工具以适应不同场景,核心区别在于对租户模式的支持

工具 支持租户模式 特点与适用场景
MySQL Client MySQL 模式 操作系统自带或通用客户端。适用于习惯 MySQL 命令行的场景,但功能有限
OB Client MySQLOracle 模式 OceanBase 官方命令行工具,针对 OceanBase 优化,语法兼容 MySQL Client,是命令行操作的首选
ODC (OceanBase Developer Center,开发者中心) MySQLOracle 模式 官方图形化开发管理工具,提供数据开发、SQL 诊断、数据导出导入等全套功能。分桌面版Web 版,是图形化操作的首选

OB ClientODC 都是客户端连接工具,可以连接数据库并执行 SQL,两者对比如下:

对比维度 OB Client (命令行客户端) ODC (图形化客户端,开发者中心)
核心定位 数据库连接与交互式命令行工具。类似于操作系统中的“终端”或“命令提示符” 数据库开发与管理的集成工作站。类似于编程用的“Visual Studio Code”或“IntelliJ IDEA”
核心功能 1. 建立数据库连接; 2. 执行输入的任何合法 SQL 或命令; 3. 返回最原始的文本结果 1. 可视化对象管理:点选创建/修改表、索引、视图等; 2. 智能 SQL 窗口:语法高亮、自动补全、格式化、执行历史; 3. 数据操作:图形化数据增删改查、导入导出; 4. 协同与管控:SQL 脚本版本管理、数据库变更工单流程(企业版)、会话管理等
核心用户 DBA、运维工程师、自动化脚本。追求精准控制和效率,用于运维、调试、批量任务 应用开发者、数据分析师、SQL 初学者。追求开发效率、降低操作门槛,用于日常开发、数据查询和分析
优势 轻量、精准、可脚本化。适合快速单次操作、嵌入自动化流程、在服务器上直接调试 高效、直观、功能集成。大幅提升复杂操作的效率,降低出错率,管理数据库对象更轻松
使用场景举例 快速检查一个服务状态写一个脚本批量更新数据 设计一张新表的多个字段和索引,或编写调试一段复杂的多表关联查询

在实际工作中,通常会两者结合使用,在不同的场景下选用最合适的工具。

2、使用 OB Client 客户端连接数据库

连接 OceanBase 多租户架构的核心在于正确指定 “用户@租户” 身份和 OBProxy 地址。

基本连接命令

obclient -h<OBProxy_IP> -P<PORT> -u<用户名>@<租户名>#<集群名> -D<数据库名> -p -c -A
  • -h:提供 OceanBase 数据库连接 IP,通常是 OBProxy 服务器的 IP 地址(如果是直连数据库,则为数据库 IP 地址);
  • -P:提供 OceanBase 数据库连接端口,通常是 OBProxy 的默认监听端口 2883(如果是直连数据库,则默认端口为 2881);
  • -u:提供租户的连接用户,格式为 用户名@租户名#集群名(如果是直连数据库,格式为 用户名@租户名);
  • -D:可选,指定连接后默认使用的数据库;
  • -p:提示输入对应用户的密码;
  • -c:可选,表示在 MySQL 运行环境中不要忽略注释,Hint 是特殊的注释,不受 -c 影响;
  • -A:可选,表示在 OB Client 连接数据库时,不自动获取统计信息。

obclient 的其他命令可以在 OceanBase 官网中随时查阅。

3、ODC 的部署与使用

ODC 有桌面版、Web 版两种产品形态,两者对比如下:

对比维度 ODC 桌面版 ODC Web 版
产品形态 独立的桌面客户端应用程序,在本地电脑下载安装 通过浏览器访问的 Web 应用程序,通常部署在服务器上
核心定位 个人开发与本地管理 企业级协同开发与集中管理
适用场景 适合个人开发者进行本地数据库开发、学习和测试 适合企业团队,需要多人协作、统一管理和安全管控的场景
核心优势 安装便捷,下载即用,升级无障碍;功能完整,包含 ODC 全部核心开发工具能力;离线可用,连接数据库后,可在本地独立工作 除了开发工具能力还包含了企业协作能力,同时Web 版在稳定性和性能上有更好的保障
部署方式 在个人电脑上安装 在企业服务器或云环境上部署,团队共享访问

下面介绍桌面版 ODC 的安装步骤和使用 ODC 创建数据源的过程 。

  1. 在官网上下载桌面版 ODC,下载地址点此进入

  2. 点击下载好的安装包,进入安装向导,选择安装路径后进行安装。

  3. 安装完成后,打开桌面版 ODC,开始新建数据源,这里选择 OceanBase 的 MySQL 类型。

  4. 在弹出的新建数据源面板中,填写连接地址、数据库用户名和密码等信息,点确定,自定义一个连接名,完成数据源的创建。

4、应用程序开发驱动(以 Java 为例)

使用 Java 等语言开发应用,需通过 OceanBase 官方 JDBC 驱动连接数据库。

  1. 获取驱动:从 OceanBase 官网下载与数据库版本匹配的 JDBC 驱动 JAR 包

  2. 项目配置:将驱动 JAR 包导入 Java 项目依赖中。

  3. 编写连接代码

    // 1. 加载驱动
    Class.forName("com.oceanbase.jdbc.Driver");
    // 2. 设置连接字符串
    String jdbcUrl = "jdbc:oceanbase://<IP>:<Port>/<数据库名>?user=<用户名>@<租户名>#<集群名>&password=<密码>";
    // 3. 建立连接
    Connection connection = DriverManager.getConnection(jdbcUrl);
    

详细操作步骤见 OceanBase 官网:点此进入


二、OceanBase 数据库对象设计

1、设计起点:租户与数据库

  1. 租户兼容模式:创建租户时,需在 MySQLOracle 两种兼容模式中选择其一,此选择决定后续所有语法和对象行为,且创建后不可更改。该设计旨在支持从原有数据库系统平滑迁移。
  2. 创建数据库
    • MySQL 模式中,DATABASESCHEMA 概念等同,使用 CREATE DATABASE 语句创建。
    • Oracle 模式中,SCHEMA 与用户绑定,创建用户(CREATE USER)时会自动生成一个同名的缺省 Schema。

2、核心设计:表与分区

  1. 表结构设计:遵循通用原则,包括选择合适数据类型、定义主键(OceanBase 要求每表必须有主键)、设置约束等,以保障数据完整性与准确性。
  2. 分区策略:为优化分布式性能,大表需设计为分区表。主要策略有:
    • RANGE 分区:按连续范围(如日期)划分,适用于时间序列数据,便于管理历史数据。
    • LIST 分区:按离散值列表(如地区)划分,适用于明确枚举值的场景。
    • HASH 分区:通过哈希函数将数据均匀打散,适用于无明显分区逻辑、追求负载均衡的场景。
    • 组合分区:上述方式的组合,先进行一级分区,再在分区内进行二级分区,管理超大规模数据。

3、关键优化:表组与索引

  1. 表组:用于优化分布式关联查询性能。通过将关联密切的表加入同一表组,OceanBase 会尽量将相同分区号的数据调度到同一台OBServer 节点,实现数据共置,从而避免跨节点网络开销。
    • Sharing 模式NONE(最宽松)、PARTITION(要求一级分区定义相同)、ADAPTIVE(要求一、二级分区定义均相同),可根据业务关联性选择。
  2. 索引设计
    • 主键与唯一索引:主键全局唯一且非空;唯一索引保证列值唯一,可包含重复的 NULL 值。
    • 局部索引:索引数据与表分区一一对应,维护效率高,但无法直接保证全局唯一性。
    • 全局索引:独立于表分区的单一索引,可保证全局唯一,但维护代价较高(涉及跨分区事务)。可进一步设计为全局分区索引以平衡负载。

4、高级对象:视图、序列与存储过程

  1. 视图:用于封装复杂查询逻辑,简化应用开发,同时可作为安全层,屏蔽敏感字段。
  2. 序列:提供全局唯一的有序数字序列,常用于生成自增主键。
  3. 存储过程:在数据库服务器端存储和执行一组 SQL 语句,减少网络交互,封装复杂业务逻辑。

上面只是列出了一个结构清晰、重点突出的知识框架。在未来学习或实践中,当需要深入研究某个知识点时,就可以有目的地去查阅相应的官方文档或进行实践,这样学习效率最高。


三、OceanBase DML 与 DQL 语句

1、数据操作:模拟与插入

在开发过程中,常需生成测试数据以验证业务逻辑。除手动编写 INSERT 语句外,使用 ODC(OceanBase Developer Center)的“生成模拟数据”功能可大幅提升效率。

  1. 功能流程:在 ODC 中选择目标表,启动功能,设定需生成的数据行数。
  2. 列数据生成:可为每列指定模拟规则(如随机姓名、范围内数字、特定枚举值等)。
  3. 自动执行:提交后,ODC 会自动在表中插入指定行数的、符合定义的模拟数据,简化了测试数据的准备工作。

2、多表关联查询

连接查询用于关联多张表中的数据,是最核心的查询操作之一。不同类型决定了结果集的包含范围

连接类型 关键说明 结果集特征
内连接 返回所有匹配的行 仅包含两表中能通过连接条件关联起来的记录。不匹配的行不出现(交集)
左连接 以左表为基准,返回其全部 包含左表所有行。右表无匹配时,对应字段以 NULL 填充
右连接 以右表为基准,返回其全部 包含右表所有行。左表无匹配时,对应字段以 NULL 填充
全连接 返回左表和右表中的所有 包含两表全部记录。任何一侧无匹配时,该侧字段以 NULL 填充(并集)

核心要点:连接类型的选择取决于业务需求——是需要精确匹配(内连接),还是需要确保某一方的数据完整性(左/右连接)。

3、分区查询与裁剪

对于分区表,OceanBase 提供了针对性的查询优化机制,以提升在大数据量下的查询性能。

  1. 显式分区查询:可以在SQL语句中直接指定分区名,仅查询特定分区的数据。

    -- 仅查询 P1 分区
    SELECT * FROM students PARTITION (P1); 
    
  2. 自动分区裁剪:这是优化器的核心能力。当查询条件中包含分区键时,优化器会自动分析 WHERE 条件,仅访问符合条件的分区,避免全表扫描。

    -- 假设表按年级 grade 分区,可以通过 WHERE 条件指定分区键 grade 的查询范围,优化器会自动过滤
    SELECT * FROM students WHERE grade = '2024';
    
  3. 性能价值分区裁剪能极大减少 SQL 执行时需要扫描的数据量,是分布式数据库处理海量数据时保证查询效率的关键技术。


四、OceanBase SQL 调优

1、调优核心流程

SQL 性能调优是一个系统性工作,遵循 “发现 -> 分析 -> 优化 -> 验证” 的闭环流程。

  1. 识别慢查询
    • 运维监控:通过 OCP 性能监控 直接查看慢查询排行榜。
    • 系统视图分析:查询 GV$OB_SQL_AUDIT 系统视图,按 SQL 执行时间范围、执行耗时等指标筛选和排序,定位性能瓶颈 SQL。
  2. 分析执行计划:使用 EXPLAIN 命令或 ODC 图形化工具 查看目标 SQL 的执行计划,理解其数据访问路径(是全表扫描还是索引扫描?关联顺序是否合理?)。
  3. 实施优化:基于分析结果,采取相应措施(如增加索引改写 SQL使用 Hint 等)。
  4. 验证效果:对比优化前后的执行计划与执行时间,确认问题已解决,并持续监控。

2、执行计划解析:数据库的“诊断报告”

执行计划展示了 SQL 语句将被如何执行,是分析性能问题的关键。

  1. 获取方式

    EXPLAIN [BASIC | EXTENDED] your_sql_statement;
    
    • BASIC:默认,为基本的执行计划展示,展示核心算子预估代价
    • EXTENDED:为最详细的计划展示,在 BASIC 基础上,增加输出列、过滤条件等详细信息。
  2. 核心算子解读

    常见算子 含义与触发场景 性能提示
    TABLE FULL SCAN 全表扫描。当无可用索引或索引失效时触发 主要优化对象。对大表进行全表扫描通常意味着性能低下
    TABLE GET 主键等值查询。利用主键直接定位单行数据 效率最高的访问方式,通常无需优化
    TABLE RANGE SCAN 索引范围扫描。通过索引检索一个范围内的数据 效率取决于索引选择性和扫描范围
    NESTED-LOOP JOIN 嵌套循环连接。适用于驱动表(小表)结果集较小的场景 若驱动表很大,效率会急剧下降
    HASH JOIN 哈希连接。通常用于大数据量且无索引的等值连接 需要在内存中构建哈希表,消耗内存
    MERGE JOIN 归并连接。适用于两端数据已有序的场景 较少见,要求输入已排序

3、核心优化手段

  1. 索引优化:针对 TABLE FULL SCAN(全表扫描)最有效。

    • 原理:将全表扫描转换为高效的索引扫描 (TABLE RANGE SCAN) 或主键访问 (TABLE GET)。
    • 决策点:在筛选性高(重复值少)且常在 WHEREORDER BYJOIN 条件中出现的列上创建索引。
  2. Hint(优化器提示):指导优化器选择特定执行路径。

    • 用途:当优化器因统计信息不准等原因未选择最优计划时,手动干预。

    • 语法示例

      SELECT /*+ INDEX(table_name index_name) */ ... ; -- 强制使用某个索引
      SELECT /*+ FULL(table_name) */ ... ; -- 强制全表扫描(通常用于小表或测试)
      SELECT /*+ LEADING(t1 t2) USE_NL(t2) */ ... ; -- 指定连接顺序和连接算法
      
    • 注意

      • Hint 是强干预,应谨慎使用,并随数据变化定期复审;
      • 在 SQL 语句中,若表名存在别名,即 table_name [AS] alias,必须写表别名,才能使 Hint 生效。

4、建立优化规范与闭环

  1. 事前预防:在研发阶段制定 SQL 开发规范,明确索引、分区、表组的设计原则。
  2. 事中管控:上线前进行 SQL 审核,利用执行计划分析工具评估风险。
  3. 事后监控:上线后通过监控持续捕获慢 SQL,分析并优化,形成持续改进的闭环。

五、数据导入导出

1、概览:工具与方式

OceanBase 提供多种数据流转工具,可根据数据量、环境与操作习惯选择。

方式/工具 类型 核心用途与特点
ODC 图形化工具 导入/导出:通过界面点选,适合中小数据量交互式操作
OBDumper 命令行工具 数据导出:专为 OceanBase 优化的高性能导出工具,支持全量/部分表、分区、多格式(SQL/CSV)导出
OBLoader 命令行工具 数据导入:与 OBDumper 配套,支持大容量数据导入,具备限流、数据清洗能力
SELECT … INTO OUTFILE SQL 命令 数据导出:将查询结果直接导出到服务器文件。要求直连 OBServer 且有文件权限
LOAD DATA SQL 命令 数据导入:将服务器上的数据文件快速加载到表中。V4.2.2 后支持 LOCAL 从客户端加载
外部表 数据库对象 数据导入:创建映射至外部文件(如 CSV)的只读表,实现免搬运数据直接查询

2、核心工具详解

1. OBDumper & OBLoader (命令行对)

这对工具适合大批量数据迁移,需在 JAVA 环境中运行。

  • 核心功能

    • OBDumper:导出表结构(DDL)数据,可按表、分区筛选,输出 SQL 或 CSV。
    • OBLoader:导入 DDL 和数据,支持并发控制、错误容忍、简易数据转换
  • 关键参数示例

    # 导出示例:将库中所有对象的结构和数据以 CSV 格式导出到指定目录,可以将 --csv 替换为 --sql
    ./obdumper -h <IP 地址> -P <端口号> -u'<用户名>@<租户名>#<集群名>' -p -D <数据库名> --ddl --csv --all -f <指定导出目录>
    
    # 导入示例:将指定目录下的 CSV 格式的数据导入到库中,可以将 --csv 替换为 --sql
    ./obloader -h <IP 地址> -P <端口号> -u'<用户名>@<租户名>#<集群名>' -p -D <数据库名> --ddl --csv --all -f <指定导入目录>
    

2. LOAD DATA (高速 SQL 导入)

用于将服务器或本地的数据文件快速灌入表,性能极高。

  • 基本语法

    LOAD DATA [LOCAL] INFILE '/path/to/data.csv'
    INTO TABLE target_table
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY '\n';
    
  • 重要特性

    • LOCAL:V4.2.2 起支持,允许从客户端机器读取文件,无需上传服务器。
    • 旁路导入:通过 Hint(如 /*+ direct(true,1024), parallel(16) */)可启用直接写入模式,绕过 SQL 层,直接在 data 文件中分配空间并插入数据,从而极致提升大批量数据导入速度。

3. 外部表

适合频繁查询外部数据文件且不希望移动数据的场景。

  • 创建与使用

    -- 1. 设置安全路径(允许访问的目录)
    SET GLOBAL secure_file_priv = '/safe/path/';
    
    -- 2. 创建外部表(指向 CSV 文件)
    CREATE EXTERNAL TABLE ext_class (
        cs_id INT,
        cs_name VARCHAR(50)
    ) LOCATION ('file:///safe/path/class.csv') FORMAT 'CSV';
    
    -- 3. 像普通表一样查询(数据仍在外部文件)
    SELECT * FROM ext_class;
    

3、最佳实践与流程建议

  1. 环境准备:使用命令行工具前,确保 JAVA 环境(JDK 1.8+)正确,并分配足够内存(如 -Xmx4G)。
  2. 权限检查:操作账号需具备对应表的 SELECT(导出)INSERT(导入) 及 **FILE(服务器文件读写)**权限。
  3. 流程选择
    • 中小数据量/交互操作使用 ODC
    • 全库迁移/大规模备份恢复使用 OBDumper + OBLoader
    • 定期批量加载日志或数据文件使用 LOAD DATA(尤其启用旁路导入)。
    • 实时分析外部系统产生的文件使用外部表
  4. 性能关键:对于海量数据,LOAD DATA旁路导入是性能最快的选择,但需注意其事务特性与常规 INSERT 不同。

六、实操

接下来将通过一个《在线教育信息系统》的例子,来了解和熟悉上述使用 OceanBase 进行应用开发的理论知识。

1、数据库对象设计

首先,根据业务需求来设计好表、视图、存储过程等数据库对象:

学生表字段

学号(S_ID,主键 PK) 姓名(S_Name) 性别(Sex) 年龄(Age) 班号(CS_ID)

班级表字段

班级号(CS_ID,主键 PK) 班级名(CS_Name)

课程表字段

课程号(C_ID,主键) 课程名(C_Name) 讲师(Teacher)

选课表字段

学号(S_ID,外键 FK) 课程号(C_ID,外键 FK) 成绩(Score)

视图:包含学生信息,如学生姓名、班级、课程名、成绩。

存储过程:统计某学生的选课数量。

序列:自动生成班级号 CS_ID。

2、数据库对象创建

  1. 创建《在线教育信息系统》的数据库 school_db,并选中;

    CREATE DATABASE school_db DEFAULT CHARACTER SET utf8mb4;
    USE school_db;
    
  2. 在 school_db 数据库中创建学生表、班级表、课程表和选课表,分别用于存储相应的信息;

    -- 创建学生表
    CREATE TABLE students (
      S_ID BIGINT NOT NULL,
      S_Name VARCHAR(50) NOT NULL,
      Sex CHAR(1),
      Age INT,
      CS_ID INT NOT NULL,
      PRIMARY KEY (S_ID)
    ) partition by hash (S_ID) partitions 6;
    
    -- 创建班级表
    CREATE TABLE classes (
      CS_ID INT NOT NULL,
      CS_Name VARCHAR(50) NOT NULL,
      PRIMARY KEY (CS_ID)
    );
    
    -- 创建课程表
    CREATE TABLE courses (
      C_ID BIGINT NOT NULL,
      C_Name VARCHAR(50) NOT NULL,
      Teacher VARCHAR(50) NOT NULL,
      PRIMARY KEY (C_ID)
    );
    
    -- 创建选课表
    CREATE TABLE enrollment (
      S_ID BIGINT,
      C_ID BIGINT,
      score DECIMAL(5, 2),
      FOREIGN KEY (S_ID) REFERENCES students(S_ID),
      FOREIGN KEY (C_ID) REFERENCES courses(C_ID)
    ) partition by hash (S_ID) partitions 6;
    
  3. 之后,可以在这四张表中分别插入几条测试数据;

  4. 创建学生信息视图 v_students_info,简化查询 SQL 语句的复杂性,以更加方便的方式获取所需的数据;

    create view v_students_info AS
    select
      s.s_name,
      c.c_name,
      e.score,
      cs.cs_name
    from
      students s,
      enrollment e,
      courses c,
      classes cs
    where
      s.s_id = e.s_id
      and e.c_id = c.c_id
      and s.cs_id = cs.cs_id
    
    select * from v_students_info;
    
  5. 创建序列 seq1,该序列的作用是自动生成班级号 CS_ID;

    -- 如果序列将用于已有数据的表,创建前务必查询当前最大值,并设置一个更大的 START WITH 值,这是为了确保不产生冲突
    -- 如果这个序列计划用于一张新建的表,或者给已有表添加的一个新的 ID 字段,那么直接创建并使用即可,与旧数据无关
    SELECT MAX(CS_ID) FROM classes;
    
    CREATE SEQUENCE seq1
    START WITH
      200 MINVALUE 1 MAXVALUE 1000000
      INCREMENT BY 1 NOCYCLE NOORDER CACHE 30;
    
    -- 下次插入新班级时,不需要再手动指定 CS_ID,数据库会自动调用 seq1.NEXTVAL 来生成一个唯一的新 CS_ID
    INSERT INTO classes (CS_ID, CS_Name) VALUES
    (seq1.NEXTVAL, '通信原理五班'),
    (seq1.NEXTVAL, '信号与系统七班'),
    (seq1.NEXTVAL, '计算机网络六班');
    
  6. 创建存储过程 enroll_count(类似于一个自定义函数),该存储过程的作用是可以统计某个学生的选课数量;

    -- DELIMITER //:临时将 SQL 语句的结束分隔符从默认的分号 ; 改为双斜线 //。如果不修改分隔符,数据库客户端一看到第一个 ; 就会误以为“创建存储过程”这个命令已经结束,从而导致错误。这只是创建过程中的一个临时约定。
    -- DELIMITER ;:最后将 SQL 语句的结束分隔符恢复为默认的分号 ;。
    DELIMITER //                   
    CREATE PROCEDURE enroll_count(IN id INT, OUT enroll_count INT)
    BEGIN
    SELECT
      COUNT(*) INTO enroll_count
    FROM
      enrollment
    WHERE
      s_id = id;
    END //
    DELIMITER ; 
    
    -- 调用存储过程,可以通过 java 程序或者命令行等方式进行调用。传入学生 ID(例如 2024001),并用变量 @course_count 接收输出值
    -- 说明:该用户变量必须以 @ 开头,会话级别。该变量在当前客户端连接(会话)中一直存在,直到连接断开,常用于在 SQL 间传递值,或在命令行中交互使用
    CALL enroll_count(2024001, @course_count);
    -- 查看结果,@course_count 变量中保存了 ID 为 2024001 的学生的选课总数
    SELECT @course_count;
    

在 ODC 中的操作截图

3、数据读写与 SQL 调优

(1)写数据

除了手动编写 SQL 向数据库插入数据外,在进行数据库性能测试或功能验证等需要大量模拟数据的场景时,也可以通过使用 ODC 的模拟 数据功能,帮助开发人员快速创建逼真的测试环境。

例如,使用 ODC 的模拟数据功能,向学生表插入数据:

(2)读数据

① 多表连接查询

这里进行多表连接查询,实践内连接、左连接、右连接以及全连接。

以学生表和班级表进行连接查询为例,通用结构:

SELECT
  s.*,
  c.cs_name
FROM
  students s
  [JOIN_TYPE] classes c on s.cs_id = c.cs_id   -- 连接类型在此切换
ORDER BY
  s_id;

连接类型 [JOIN_TYPE] 的可选项:

  • 内连接INNER JOIN结果:仅返回有对应班级的学生。
  • 左连接LEFT JOIN结果:返回所有学生,若学生无对应班级,则 cs_nameNULL
  • 右连接RIGHT JOIN结果:返回所有班级,若班级无学生,则学生的各字段为 NULL
  • 全连接FULL JOIN结果:返回学生和班级的全部记录,任何未匹配部分用 NULL 填充。

总结INNER 取交集,LEFT/RIGHT 保一侧,FULL 取并集。

② 分区查询与裁剪

OceanBase 数据库支持按分区查询数据,用户可以在 SQL 语句中直接指定需要访问的分区。数据库优化器也可以通过 WHERE 条件中分区键的查询范围来计算需要访问的分区并相应地进行分区裁剪

以查询学生表第一个分区的数据为例,查询时指定分区:

SELECT * FROM students PARTITION(P0);

数据表是分区表,进行 SQL 查询时:

  • 查询条件包含分区键时,优化器能通过分区裁剪精准定位到少量相关分区,实现快速查询。

  • 查询条件不包含分区键时,优化器将无法进行裁剪,被迫执行全分区扫描以访问所有分区数据。

这种从“精准定位”到“全面扫描”的退化,会导致 I/O、CPU 消耗和查询延迟显著增加,这是分区表最主要的性能陷阱。

(3)SQL 调优

每个系统初上线时,数据量有限且并发较低,因此,大多数 SQL 查询不会遇到性能问题。然而,随着用户数量和数据量的增长,原本有效的 SQL 查询可能不再适应新的环境,此时就可以通过查看 SQL 语句的执行计划进行分析。查看目标 SQL 的执行计划有两种方式:使用 EXPLAIN 命令或 ODC 图形化工具。

接下来将在学生表中插入 20 万条数据,查看 SQL 的执行计划,并根据执行计划进行 SQL 优化。

EXPLAIN SELECT * FROM students WHERE S_Name = "张明";

未进行优化前,SQL 的执行计划如下,可以看到是 TABLE FULL SCAN全表扫描的执行方式

可以通过为 S_Name 列创建合适的索引,来减少数据的扫描量:

create index i_s_name on students(S_Name); 

索引创建成功后,再次执行相同的 SQL,可以看到这次执行计划选择了 TABLE RANGE SCAN索引扫描的执行方式

一般情况下,优化器会为用户查询选择最佳的执行计划,不需要用户使用 Hint 指定,但在某些场景下,优化器生成的执行计划可能无法满足用户的要求,这时就需要用户使用 Hint 来主动指定并生成特殊的执行计划

例如通过指定 Hint,使上述查询语句采用全表扫描的执行方式。

EXPLAIN SELECT /*+ FULL(students)*/ *  FROM students where S_Name='张明';

4、ODC 数据导入导出

ODC 支持以图形化的方式批量导出和导入数据库对象的结构和数据,在导入导出过程中,可以按开发者的要求进行设置。

(1)数据导出

实践:使用 ODC 导出班级表中的数据。

导出成功后,可以查看到导出的数据

(2)数据导入

实践:使用 ODC 导入数据到班级表中。

先清空班级表中的数据:

truncate table classes; 

导入成功后,可以查看到导入的数据

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐