Databend 实现高效实时查询:深入解读 Dictionary 功能

news2024/12/24 11:25:55

作者:洪文丽

开源之夏2024“支持 External Dictionaries”项目参与者

东北大学软件工程专业云计算方向大二在读,喜欢挑战自我,尝试新鲜事物

背景介绍

在大型系统中,数据通常存储在多个不同的数据源中,例如 PostgreSQL、MySQL 和 Redis 负责存储在线数据,而 Databend 和 ClickHouse 则用于存储分析数据。传统的分析查询方法往往需要同时使用到多种不同的数据,通常通过 ETL 过程将数据导入一个系统后进行查询,但这种方式存在以下问题:

  1. 数据变动导致不一致性:

在多源数据系统中,数据可能会在不同的系统中以不同的频率和时间点进行更新。例如,在线数据源如 MySQL 和 Redis 可能会实时更新,而分析系统如 Databend 更新频率较低。这种时间差异可能导致数据不一致,分析结果可能与实际在线数据不符。

  1. 多表 join 操作性能低下:

在传统的 ETL 过程中,将数据从多个源导入到一个分析系统后,进行多表 join 操作时可能会遇到性能瓶颈。大规模的 join 操作需要对多个表进行复杂的匹配和计算,这可能导致查询响应时间变长,特别是在数据量大且 join 操作复杂的情况下。

  1. 数据系统管理复杂度高:

在大型系统中,管理多个数据源意味着需要处理不同的存储和查询机制。例如,MySQL 和 PostgreSQL 需要数据库管理和优化,Redis 需要确保缓存有效性,而 Databend 需要优化分析数据的存储和查询。每种系统都有不同的配置和维护要求,这增加了管理的复杂度和运维成本。数据备份、恢复、监控和性能调优等任务也需要分别在多个系统中进行。

为了解决这些问题,Databend 实现了字典功能。通过集成 MySQL、Redis 等外部数据源,Databend 实现了数据的实时查询与分析,不仅显著提升了查询性能,还确保了数据的一致性,减少了传统 ETL 流程的复杂性,特别适用于需要快速响应的实时分析场景。用户通过字典函数 dict_get 能够直接从外部数据源检索数据,简化了数据管理,并优化了大数据处理的效率。如图所示为字典功能示意图: 

字典功能介绍

2.1 DDL 语法

  1. 基本语法
CREATE OR REPLACE DICTIONARY [db_name].dictionary_name
(
 field1 type1 [DEFAULT expr1],
 field2 type2 [DEFAULT expr2],
 ...
)
PRIMARY KEY primary_key
SOURCE(source_type [source_options]);
  1. 字典的配置参数 PRIMARY KEY:字典的主键,用作查找数据的 key。 SOURCE:字典的数据源类型,如 MySQL、Redis 等。

  2. 数据源配置

    1.   目前支持 MySQL 和 Redis 作为数据源

    2.   MySQL 数据源

    3. host (必填):MySQL 服务器的主机名或 IP 地址。

    4. port (必填):MySQL 服务器的端口号,默认为 3306。

    5. username (必填):用于连接 MySQL 服务器的用户名。

    6. password (必填):用户的密码。

    7. db (必填):要连接的数据库名称。

    8. table (必填):数据库中的具体表名。

    9.   示例配置:

    10. SOURCE(MYSQL(
      host='your_host'
      port='3306'
      username='your_username'
      password='your_password'
      db='your_db'
      table='your_table'
      ))
    11.   Redis数据源

    12. host (必填):Redis 服务器的主机名或 IP 地址。

    13. port (必填):Redis 服务器的端口号,默认为 6379。

    14. username (选填):如果 Redis 服务器设置了用户认证,则提供用户名。

    15. password (选填):用户的密码。

    16. db_index (选填):指定要使用的 Redis 数据库,默认为 0,最大值为 15。

    17.   示例配置:

    18. SOURCE(REDIS(
      host='your_host'
      port='6379'
      username='your_username'
      password='your_password'
      db_index='db_index'
      ))
  3. 字段类型配置

    1. MySql数据源支持:booleanstringnumber类型,其中 number 类型涵盖了整型(如 intbigint)和浮点型(如 float32float64)。
    2. Redis数据源支持:string类型,用于键值对的简单存储和检索。
    3. 值得注意的是,在 dict_get 函数中,若无法从外部数据源检索到对应的键值,系统会返回用户指定的默认值,或者使用系统的默认值。这一机制确保即使在外部数据源中未找到匹配的键,Databend 依然能够返回合理的结果,从而避免数据缺失对后续操作的影响,提高了系统的鲁棒性和查询的稳定性。

2.2 查询函数语法

Databend 支持使用 dict_get 函数查询字典数据。

dict_get([db_name].dict_name, 'attr_name', key_expr)
  • [db_name].dict_name:外部字典的名称,可能包括数据库名(如果字典存储在特定的数据库中)和字典名。如果当前会话已经选择了一个特定的数据库,那么可以省略数据库名,只提供字典名。
  • 'attr_name':要查询的字典中字段的名称,必须为字符串。
  • key_expr:查询的 key 表达式,与字典中的 PRIMARY KEY 类型相同。

使用示例

假设我们有一个学生成绩管理系统,我们需要存储和查询学生的成绩信息、课程信息等数据。这些信息分别存储在 Databend、MySQL 和 Redis 中。

  • Databend 中有一个学生成绩表

    • CREATE TABLE student_scores (
       student_id INT,
       course_id INT,
       score INT
      );

插入一些测试数据

INSERT INTO student_scores
VALUES (1, 1, 62),(1, 2, 75),(1, 3, 88),(2, 1, 93),
        (2, 2, 54),(2, 3, 99),(3, 1, 67),(3, 2, 80),
        (3, 3, 57),(4, 1, 66),(4, 2, 83),(4, 3, 91); 
  • MySQL 中有一个课程信息表

    • CREATE TABLE courses (
       course_id INT PRIMARY KEY,
       course_name VARCHAR(255),
      );

插入一些测试数据

INSERT INTO courses
VALUES (1, 'math'),(2, 'english'),(3, 'chinese');
  • Redis 中存储了学生的姓名

    • 127.0.0.1:6379> set 1 'Andy'
      127.0.0.1:6379> set 2 'Nancy'
      127.0.0.1:6379> set 3 'Lucy'
      127.0.0.1:6379> set 4 'Jack'

在 Databend 中创建字典

CREATE DICTIONARY courses_dict
(
    course_id INT,
    course_name STRING
)
PRIMARY KEY course_id
SOURCE(MYSQL(
    host='localhost'
    port='3306'
    username='root'
    password='123456'
    db='test'
    table='courses'
));
CREATE DICTIONARY student_name_dict
(
    student_id string,
    student_name string
)
PRIMARY KEY student_id
SOURCE(REDIS(
    host='127.0.0.1'
    port='6379'
));

通过 Databend 的字典功能,可以轻松关联多个数据源并进行查询:

  • 查询同学选课的信息,关联课程名称和学生姓名

    • SELECT student_id,
          dict_get(student_name_dict, 'student_name', to_string(student_id)) as student_name,
          course_id,
          dict_get(courses_dict, 'course_name', course_id) as course_name
      FROM student_scores;
    • +------------+--------------+-----------+-------------+
      | student_id | student_name | course_id | course_name |
      +------------+--------------+-----------+-------------+
      | 1          | Andy         | 1         | math        |
      | 1          | Andy         | 2         | english     |
      | 1          | Andy         | 3         | chinese     |
      | 2          | Nancy        | 1         | math        |
      | 2          | Nancy        | 2         | english     |
      | 2          | Nancy        | 3         | chinese     |
      | 3          | Lucy         | 1         | math        |
      | 3          | Lucy         | 2         | english     |
      | 3          | Lucy         | 3         | chinese     |
      | 4          | Jack         | 1         | math        |
      | 4          | Jack         | 2         | english     |
      | 4          | Jack         | 3         | chinese     |
      +------------+--------------+-----------+-------------+
  • 查询同学平均成绩的排名

    • SELECT student_id,
          dict_get(student_name_dict, 'student_name', to_string(student_id)) as student_name,
          avg(score) as avg_score
      FROM student_scores
      GROUP BY student_id
      ORDER BY avg_score DESC;
    • +------------+--------------+-----------+
      | student_id | student_name | avg_score |
      +------------+--------------+-----------+
      | 2          | Nancy        | 82.0      |
      | 4          | Jack         | 80.0      |
      | 1          | Andy         | 75.0      |
      | 3          | Lucy         | 68.0      |
      +------------+--------------+-----------+
  • 查询各门课程的平均分数

    • SELECT course_id,
          dict_get(courses_dict, 'course_name', course_id) as course_name,
          avg(score) as avg_score
      FROM student_scores
      GROUP BY course_id;
    • +-----------+-------------+-----------+
      | course_id | course_name | avg_score |
      +-----------+-------------+-----------+
      | 2         | english     | 73.0      |
      | 1         | math        | 72.0      |
      | 3         | chinese     | 83.75     |
      +-----------+-------------+-----------+

通过以上的示例,可以看到字典功能可以有效地结合 Databend、MySQL 和 Redis 处理学生成绩管理系统中的联合查询,提高查询效率和数据管理能力。

四、总结

在这篇文章中,我们介绍了字典功能的基本用法,并通过一个简单的例子展示了使用字典来查询多个数据源的数据。字典功能在很多应用场景都可以使用,特别是有外部数据源需要定期同步场景,例如,一个金融分析系统需要实时分析股票价格数据,通过为股票价格数据创建字典,可以从数据源实时读取最新的股票价格数据,结合其它数据进行实时的分析计算。字典功能在提高查询性能、简化数据管理、确保数据一致性等方面具有广泛的应用价值。

目前,Databend 字典已经支持了对 MySQL 和 Redis 数据源的访问,未来会支持更多数据源,包括 PostgreSQL、MongoDB、Sqlite、HTTP 接口等,满足更多数据处理和分析场景的需求。同时,字典查询的性能也会继续优化,通过引入缓存和批量查询机制,减少外部数据源的查询延迟,提升并发查询性能。

关于 Databend

Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。 👨‍💻‍ Databend Cloud:databend.cn

📖 Databend 文档:docs.databend.cn/

💻 Wechat:Databend

✨ GitHub:github.com/datafuselab…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180316.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【设计模式-职责链】

定义 职责链模式是一种行为设计模式,**它通过将请求发送给链上的多个处理者来避免请求发送者与处理者之间的紧密耦合。每个处理者可以选择处理请求或将其传递给链中的下一个处理者。**这样,可以将处理请求的责任链式组织,从而实现更灵活的请…

LeetCode 面试经典150题 66.加一

题目:给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。 思路: 代码&…

winform 中 panel 中添加可视对象错位问题

今天在写程序的时候,发现动态添加到panel_wokrarea中的按钮,同样是posx0,有时并不能对齐,会和当前窗口中panel_wokrarea在屏幕上的显示区域的最左边(panel_wokrarea很宽) 经分析,是因为panel 在…

828华为云征文 | 华为云Flexus X实例在混合云环境中的应用与实践

目录 前言 1. 混合云环境的优势与挑战 1.1 混合云的优势 1.2 混合云的挑战 2. Flexus X实例的配置与集成 2.1 Flexus X实例简介 2.2 Flexus X实例的混合云部署 2.3 配置步骤与措施 3. 数据迁移与同步策略 3.1 数据迁移方案 3.2 数据同步措施 4. 安全性与合规性管理…

我们用等距投影制作了一个动画视频

一家国际网络安全公司委托我们制作一部关于其网络安全产品的解释性视频。为了有效传达产品的价值给潜在客户和利益相关者,我们决定采用等距投影技术制作动画视频。等距投影是一种复杂的视觉呈现方式,它能够让人物和物体看起来具有三维效果,而…

FileLink跨网文件交换|解决网络隔离导致的文件共享难题

在现代企业的运营中,跨网文件交换已经成为一个重要的需求。然而,网络隔离和安全政策往往使得文件共享变得困难。FileLink作为一种创新的解决方案,旨在有效应对这些挑战,提升文件共享效率。 一、网络隔离的挑战 网络隔离常常是出于…

基于ESP8266—AT指令连接阿里云+MQTT透传数据(2)

MQTT_TX设备为发送数据的Topic,使用MQTT-fx软件实现 MQTT_RX设备为接收(订阅)数据的Topic,使用ESP8266通过AT指令实现 一、使用MQTT-fx实现发送数据 首先进入控制台,获取发送设备 “ MQTT_TX ” 的MQTT连接参数,具体具体操作如…

NineData云原生智能数据管理平台新功能发布|2024年9月版

本月发布 3 项更新,其中重点发布 3 项。 重点发布 数据复制 - 新增 Oracle 到 Kafka 复制链路 数据复制功能新增支持将 Oracle 中的数据复制到 Kafka,实现数据的实时流转和分发,支持全量和增量。 数据复制 - 新增库表分组复制 创建复制任务…

电信杯扬帆起航 灵途科技携手中国地质大学推动产学协同创新

近日,由中国地质大学机械与电子信息学院主办的“电信杯”正式启动。作为该校电子信息领域的一项特色创新赛事,此次活动由中国地质大学电子信息工程研创会主办,武汉灵途传感科技有限公司、中建三局智能技术有限公司和武汉盛帆电子股份有限公司…

手把手教你用Python进行Web抓取(附代码)

本教程以在Fast Track上收集百强公司的数据为例,教你抓取网页信息。 作为一名数据科学家,我在工作中所做的第一件事就是网络数据采集。使用代码从网站收集数据,当时对我来说是一个完全陌生的概念,但它是最合理、最容易获取的数据来…

CAN总线的错误类型

前言 CAN总线的错误类型主要包括:位错误、填充错误、格式错误、ACK错误和CRC错误。这里一定要做好CAN总线的错误类型、错误帧类型、节点状态之间的区别。 错误类型是帧传输出错的原因类型;错误帧类型(主动错误帧、被动错误帧)是帧…

实习问题(配置文件获取参数)

Java中用SpringBoot框架,当我们要获取配置文件yml里的参数时,用Value注解获取 如果配置文件中没有srvSealUploadPath这个参数的话,可以用Value("${srvSealUploadPath:data/idoc/temp}"),这个的意思是,如果配…

【Python入门】20个Python自动化脚本,解放双手、事半功倍

如果你正在学习Python,那么你需要的话可以,点击这里👉Python重磅福利:入门&进阶全套学习资料、电子书、软件包、项目源码等等免费分享! 在当今的快节奏工作环境中,自动化不再是一种奢侈,而是…

谷歌浏览器完美清除缓存

1.在页面上按下键盘的F12,打开控制台。 2.鼠标放到刷新图标上,点击鼠标右键,选择‘清空缓存并硬性重新加载’。 这样浏览器对网站页面的缓存就彻底被清理干净了。 目前支持该操作方式的浏览器有谷歌和Edge浏览器。 有的浏览器不支持该方式操…

线上热迁移数据库

1、背景 在线平台用的是公司自己的服务器上面搭建的 MongoDB,测试那边反馈珊瑚海平台 MongoDB 有时会掉线,于是计划将本地数据库迁移到云平台。 2、问题所在 1、因为平台测试的同事还在正在使用平台进行测试工作,所以不可能把平台停掉&…

Web认识 -- 第一课

文章目录 前言一、HTML是什么?二、了解Web1. 基本概念2.Web标准3. Web构成1.前端1. HTML2.CSS3. javaScript4.常见浏览器介绍 2.Web标签构成1.结构标准2.表现标准 -- css3. 行为标准 -- javaScript 总结 前言 这里是我们进入前端学习的开端,在本次更新之后我会陆续…

VUE前后端分离毕业设计题目项目有哪些,VUE程序开发常见毕业论文设计推荐

目录 0 为什么选择Vue.js 1 Vue.js 的主要特点 2 前后端分离毕业设计项目推荐 3 后端推荐 4 总结 0 为什么选择Vue.js 使用Vue.js开发计算机毕业设计是一个很好的选择,因为它不仅具有现代前端框架的所有优点,还能让你专注于构建高性能、高可用性的W…

【C++】map和set的介绍和使用

1.序列式容器与关联式容器 序列式容器&#xff1a; 底层为线性序列的数据结构&#xff0c; 里面存储的是元素本身 。如vector/list/string/deque/forward_list。 关联式容器&#xff1a; 也是用来存储数据的&#xff0c;于序列式容器不同的是&#xff0c; 里面存储的是<key&…

一文详解WebRTC、RTSP、RTMP、SRT

背景 好多开发者&#xff0c;希望对WebRTC、RTSP、RTMP、SRT有个初步的了解&#xff0c;知道什么场景该做怎样的方案选择&#xff0c;本文就四者区别做个大概的介绍。 WebRTC 提到WebRTC&#xff0c;相信好多开发者第一件事想到的就是低延迟&#xff0c;WebRTC&#xff08;W…

基于IntraWeb的数据表格的多选实现

基于IntraWeb的数据表格的多选实现 既可以单条操作&#xff0c;也可以多选操作。 delphi源代码。 BS开发Web网站开发&#xff0c;不需要安装服务器&#xff0c;Apache和IIS都不需要&#xff0c;自带企业级服务器。 运行exe服务器就架好了&#xff0c;直接打开手机浏览器或者…