混合使用MariaDB和MongoDB的SQL与NoSQL

news2025/1/12 13:17:54

假设你有一个在Node.js(或任何其他平台)上开发的应用程序。这个应用程序连接到一个MongoDB数据库(NoSQL),用于存储对书籍的评价(给出的星级数量和评论)。再假设你有另一个在Java(或Python、C#、TypeScript...等)上开发的应用程序。这个应用程序连接到一个MariaDB数据库(SQL,关系型),用于管理书籍目录(标题、出版年份、页数)。

你被要求创建一个报告,展示每本书的标题和评分信息。注意,MongoDB数据库不包含书籍的标题,而关系型数据库不包含评分。我们需要混合由NoSQL应用程序创建的数据和由SQL应用程序创建的数据。

一个常见的方法是独立查询这两个数据库(使用不同的数据源),并处理数据以匹配,例如,按ISBN(书籍的ID)进行匹配,并将组合的信息放入一个新对象中。这需要在Java、TypeScript、C#、Python或能够连接到这两个数据库的任何其他命令式编程语言中完成。

【squids.cn】 目前可体验全网zui低价RDS,免费的迁移工具DBMotion、SQL开发工具等

图片

多语种应用程序

这种方法是可行的。但是,数据的联接是数据库的工作。它们为这种数据操作而生。此外,使用这种方法,SQL应用程序不再只是一个纯SQL应用程序;它成为一个数据库多语种,这增加了复杂性,使其更难维护。

使用像MaxScale这样的数据库代理,您可以使用最适合数据的语言——SQL,在数据库级别连接这些数据。您的SQL应用程序不需要成为多语种。

尽管这在基础架构中需要额外的元素,但你还可以获得数据库代理所提供的所有功能。例如自动故障转移、透明数据屏蔽、拓扑隔离、缓存、安全过滤器等。

MaxScale是一个功能强大、智能的数据库代理,理解SQL和NoSQL。它也了解Kafka(用于CDC或数据摄取),但那是另一个话题。简而言之,有了MaxScale,你可以将你的NoSQL应用程序连接到一个完全符合ACID的关系数据库,并将数据存储在其他SQL应用程序使用的表旁边。

图片

MaxScale允许SQL应用程序使用NoSQL数据

让我们在一个简单且易于跟随的MaxScale实验中尝试这最后一种方法。你需要在你的计算机上安装以下内容:

  • Docker 

  • mariadb-shell工具 

  • mongosh工具 

设置MariaDB数据库 

使用一个简单的文本编辑器,创建一个新文件并保存为docker-compose.yml。该文件应包含以下内容:

version: "3.9"
services:
  mariadb:
    image: alejandrodu/mariadb
    environment:
      - MARIADB_CREATE_DATABASE=demo
      - MARIADB_CREATE_USER=user:Password123!
      - MARIADB_CREATE_MAXSCALE_USER=maxscale_user:MaxScalePassword123!


  maxscale:
    image: alejandrodu/mariadb-maxscale
    command: --admin_host 0.0.0.0 --admin_secure_gui false
    ports:
      - "3306:4000"
      - "27017:27017"
      - "8989:8989"
    environment:
      - MAXSCALE_USER=maxscale_user:MaxScalePassword123!
      - MARIADB_HOST_1=mariadb 3306
      - MAXSCALE_CREATE_NOSQL_LISTENER=user:Password123!

这是一个Docker Compose文件。它描述了由Docker创建的一组服务。我们正在创建两个服务(或容器)——一个MariaDB数据库服务器和一个MaxScale数据库代理。它们将在你的机器上本地运行,但在生产环境中,常常会在不同的物理机器上部署它们。请记住,这些Docker镜像不适用于生产环境!它们旨在适用于快速的演示和测试。你可以在GitHub上找到这些镜像的源代码。要获取MariaDB的官方Docker镜像,请前往Docker Hub上的MariaDB页面。

前面的Docker Compose文件配置了一个带有名为demo的数据库(或模式;在MariaDB中它们是同义词)的MariaDB数据库服务器。它还创建了一个用户名为user、密码为Password123!的用户。该用户在demo数据库上有适当的权限。还有一个额外的用户,名为maxscale_user,密码为MaxScalePassword123!。这是MaxScale数据库代理用于连接到MariaDB数据库的用户。

Docker Compose文件还通过禁用HTTPS(在生产环境中不要这么做!)、暴露一组端口(稍后会详细讨论)以及配置数据库用户和MariaDB数据库代理的位置(通常是一个IP地址,但在这里我们可以使用在Docker文件中之前定义的容器的名称)来配置数据库代理。最后一行创建了一个NoSQL监听器,我们将使用它在默认端口(27017)上作为MongoDB客户端连接。

要使用命令行启动服务(容器),请移至保存Docker Compose文件的目录,并运行以下命令:

docker compose up -d

下载所有软件并启动容器后,你将拥有一个MariaDB数据库和MaxScale代理,两者都已预先配置为此实验。

在MariaDB中创建SQL表 

首先,让我们连接到关系型数据库。在命令行中,执行以下命令:

mariadb-shell --dsn mariadb://user:'Password123!'@127.0.0.1

检查你是否可以看到demo数据库:

show databases;

切换到demo数据库:

use demo;

图片

使用MariaDB Shell连接数据库

创建books表:

CREATE TABLE books(  isbn VARCHAR(20) PRIMARY KEY,  title VARCHAR(256),  year INT);

插入一些数据。我打算使用陈词滥调的方法插入我的书:

INSERT INTO books(title, isbn, year)VALUES  ("Vaadin 7 UI Design By Example", "978-1-78216-226-1", 2013),  ("Data-Centric Applications with Vaadin 8", "978-1-78328-884-7", 2018),  ("Practical Vaadin", "978-1-4842-7178-0", 2021);

通过运行以下命令,检查书籍是否存储在数据库中:

SELECT * FROM books;

图片

使用MariaDB Shell插入数据

在MariaDB中创建一个JSON集合 

我们还没有安装MongoDB,但我们可以使用一个MongoDB客户端(或应用程序)连接创建集合和文档,就好像我们正在使用MongoDB一样,只是数据存储在一个功能强大、完全支持ACID的可扩展关系型数据库中。让我们试试看!

在命令行中,使用MongoDB shell工具连接到MongoDB...等等...其实是MariaDB数据库!执行以下命令:

mongosh

默认情况下,此工具尝试连接到在你的本地机器(127.0.0.1)上运行的MongoDB服务器(这次恰好是MariaDB),使用默认端口(20017)。如果一切顺利,当你运行以下命令时,你应该能够看到demo数据库:

show databases

切换到demo数据库:

use demo

图片

使用Mongo Shell连接到MariaDB

我们已经从一个非关系型客户端连接到了关系型数据库!现在,让我们创建评分集合并插入一些数据:

db.ratings.insertMany([  {    "isbn": "978-1-78216-226-1",    "starts": 5,    "comment": "A good resource for beginners who want to learn Vaadin"  },  {    "isbn": "978-1-78328-884-7",    "starts": 4,    "comment": "Explains Vaadin in the context of other Java technologies"  },  {    "isbn": "978-1-4842-7178-0",    "starts": 5,    "comment": "The best resource to learn web development with Java and Vaadin"  }])

检查评分是否已在数据库中保存:

db.ratings.find()

图片

使用Mongo Shell查询MariaDB数据库

使用MariaDB中的JSON函数 

此时,我们有一个单一的数据库,从外部看起来像一个NoSQL(MongoDB)数据库和一个关系型(MariaDB)数据库。我们能够连接到相同的数据库,并从MongoDB客户端和SQL客户端读写数据。所有数据都存储在MariaDB中,因此我们可以使用SQL将来自MongoDB客户端或应用的数据与来自MariaDB客户端或应用的数据进行连接。让我们探索MaxScale如何使用MariaDB存储MongoDB数据(集合和文档)。

使用像mariadb-shell这样的SQL客户端连接到数据库,并显示demo模式中的表:

show tables in demo;

你应该看到books和ratings表都列出了。ratings是作为MongoDB集合创建的。MaxScale转译了从MongoDB客户端发送的命令,并创建了一个表来存储数据。让我们看看这个表的结构:

describe demo.ratings;

图片

一个NoSQL集合存储为MariaDB关系型表

ratings表包含两列:

  • id:对象ID。 

  • doc:以JSON格式的文档。 

如果我们查看表的内容,我们会看到关于ratings的所有数据都存储在以JSON格式的doc列中:

SELECT doc FROM demo.ratings \G

图片

NoSQL文档存储在MariaDB数据库中

让我们回到我们的原始目标——显示书籍标题及其评分信息。以下情况并非如此,但让我们暂时假设ratings表是一个常规表,有stars和comment列。如果是这样的话,将此表与books表连接起来就很容易了,我们的工作就完成了:​​​​​​​

/* this doesn’t work */SELECT b.title, r.stars, r.commentFROM ratings rJOIN books b USING(isbn)

回到现实。我们需要将实际ratings表的doc列转换为查询中的新表的关系表达式。像这样:​​​​​​​

/* this still doesn’t work */SELECT b.title, r.stars, r.commentFROM ratings rtJOIN ...something to convert rt.doc to a table... AS rJOIN books b USING(isbn)

那个东西是JSON_TABLE函数。MariaDB包括一套全面的JSON函数用于操作JSON字符串。我们将使用JSON_TABLE函数将doc列转换为我们可以用来执行SQL连接的关系形式。JSON_TABLE函数的一般语法如下:​​​​​​​

JSON_TABLE(json_document, context_path COLUMNS (    column_definition_1,    column_definition_2,    ...  )) [AS] the_new_relational_table

其中:

  • json_document:要使用的返回JSON文档的字符串或表达式。 

  • context_path:定义用作行源的节点的JSON Path表达式。 

列定义(column_definition_1、column_definition_2等)具有以下语法:

new_column_name sql_type PATH path_in_the_json_doc [on_empty] [on_error]

结合这些知识,我们的SQL查询将如下所示:​​​​​​​

SELECT b.title, r.stars, r.commentFROM ratings rtJOIN JSON_TABLE(rt.doc, '$' COLUMNS(    isbn VARCHAR(20) PATH '$.isbn',    stars INT PATH '$.starts',    comment TEXT PATH '$.comment'  )) AS rJOIN books b USING(isbn);

图片

在一个SQL查询中连接NoSQL和SQL数据

我们本可以使用ISBN值作为MongoDB ObjectID,从而作为ratings表中的id列,但我会把这个留给你作为一个练习(提示:使用MongoDB客户端或应用插入数据时使用_id而不是isbn)。

关于可伸缩性的一点话 

有一种误解,即关系型数据库不具有水平扩展性(添加更多节点),而NoSQL数据库具有。但是,关系型数据库在扩展时不牺牲ACID属性。MariaDB拥有多种存储引擎,适用于不同的工作负载。例如,您可以使用Spider来实现数据分片,从而扩展MariaDB数据库。您还可以使用各种存储引擎在每个表的基础上处理不同的工作负载。在单个SQL查询中都可以进行跨引擎连接。

图片

在一个逻辑MariaDB数据库中结合多个存储引擎

另一个更现代的选择是使用MariaDB Xpand的分布式SQL。一个分布式SQL数据库通过透明的分片在应用程序中呈现为一个单一的逻辑关系型数据库。它采用无共享架构,可以扩展读写操作。

图片

分布式SQL数据库部署

结论 

我们的工作在这里完成了!现在,您的系统可以对独立于SQL或NoSQL应用程序创建的数据进行ACID兼容的可扩展的360度视图。减少了从NoSQL迁移到SQL的需求,或使SQL应用程序成为数据库多语言用户。

作者:Alejandro Duarte

更多技术干货请关注公众号 “云原生数据库”

【squids.cn】 目前可体验全网zui低价RDS,免费的迁移工具DBMotion、SQL开发工具等

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

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

相关文章

冠达管理:国内产量最大!又一龙头来了…本周4股可申购

本周(9月11日—9月15日),共有4只新股将申购,其间创业板2只(飞南资源、万邦医药),科创板1只(中研股份),沪市主板1只(恒兴新材)。 资料…

【acwing总结】快速排序

原题链接 时间复杂度 nlogn 快排利用分治思想的原理 主要步骤有以下几种 (1):确认分界点 可以q[l] 可以是q[lr] 可以是q[r],也可以是随机值 (2):调整区间 将小于等于分界点的,放到左边去&…

cpp-httplib 源码剖析

文章目录 前言一、cpp-httplib 是什么?二、Server类整体架构三、绑定和监听bind_internallisten_internal 四、路由添加路由路由 五、处理接受请求process_server_socket_coreprocess_request 前言 之前实现自己的http库的时候感觉有一些设计的不是很好&#xff0c…

虹科分享 | Chae$4:针对金融和物流客户的新Chaes恶意软件变体 | 自动移动目标防御

介绍--Chae$4 随着网络威胁的世界以惊人的速度发展,保持领先于这些数字危险对企业来说变得越来越关键。2023年1月,Morphisec发现了一个令人震惊的趋势,许多客户,主要是物流和金融部门的客户,受到了Chaes恶意软件的新的…

【踩坑】Latex中multicolumn/multirow单元格竖线消失的恢复方法

消失的情况: 修复方法: 1、第一点是确保单元格数量正确; 2、第二点是一个小细节,这里的c后面要加个"|": \multicolumn{3}{c|} 当然,如果是左边少,那就加左边;或者直接左…

Python爬虫实战:抓取和分析新闻数据与舆情分析

在信息爆炸的时代,新闻和舆情分析对于企业和个人来说都具有重要意义。而Python作为一门优秀的编程语言,非常适合用于构建强大的爬虫工具,并用于抓取和分析新闻数据。本文将分享使用Python爬虫抓取和分析新闻数据,并进行舆情分析的…

2023年下半年杭州/深圳软考(中/高级)认证报名,来这呀

软考是全国计算机技术与软件专业技术资格(水平)考试(简称软考)项目,是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试,既属于国家职业资格考试,又是职称资格考试。 系统集成…

OceanMind海睿思加入信通院TC1-WG7工作组,推进IT内控与审计标准体系化发展

近日,中新赛克海睿思通过中国通信标准化协会下(CCSA)的互联网与应用技术工作委员会(TC1)审议批准,正式成为IT内控与审计技术工作组(WG7)成员单位。 IT内控与审计技术工作组 是 中国信…

用了5年的fiddler抓包,这个超级实用的功能今天才知道!

我们在使用fiddler抓包获取请求响应时间时都会看Statics页面中的Overall Elapsed值!如果只看单个请求的响应时间没有什么问题;但是如果我们需要看多个请求的响应时间或者想对页面中所有抓包的请求排序进而找到最耗时的请求,使用该方法显然是无…

C#难点语法讲解之委托---从应用需求开始讲解

一、委托的定义 委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 简单解释:变量好控制,方法不好控制,委托可以把方法变成变量 二、例子解释定义 如果我们有一个数组,里面有10个…

如何注册喀麦隆商标?

想象一下,你正在喀麦隆的雨林中寻找宝藏,突然你发现了一个从未被人发现的部落。这个部落的人们用一种独特的图案作为他们的标记,来展示他们的身份和与众不同。这个图案就是喀麦隆的商标! 在商业世界中,商标就像这个独特…

开启更高效之路,美创科技暗数据发现和数据分类分级系统全新升级

数字经济时代,数据分类分级作为平衡数据保护和流通利用的基础工作,愈发受到广泛的关注。但面对海量繁杂的数据,如何快速地实现数据梳理与分类分级,对于绝大多数组织而言,并非易事—— ◼︎ 在缺少标准方法和自动化、智…

洁净在线监测系统-天文台日冕仪内洁净环境监测应用

近日,北京中邦兴业技术部在云南完成了一项极具创新性的洁净环境在线监测项目,此次项目的交付,代表着中邦兴业技术的又一次突破与创新,打破了洁净检测仪器在传统行业的应用,成功将激光尘埃粒子计数器LIGHTHOUSE-3016,应…

20230911java面经整理

1.java线程安全的数据类型 Vector:每个方法都有synchronized hashttable:每个方法都有synchronized stack:继承了vector arrayblockingqueue:阻塞队列 concurrentHashMap:使用segment分段锁 concurrentLinkedQueue&am…

flink on yarn任务中文乱码问题解决记录

开发反馈预生产部分部分flink任务出现中文乱码的问题 找到乱码的flink任务所在的节点,登录服务器,执行locale命令: 发现是locale没有设置好,使用vim编辑文本,写入中文都直接乱码 对比其他几台机器,发现主…

【算法】常见位运算总结

目录 1.基础位运算2. 给一个数n,确定它的二进制表示中的第x位是0还是13.将一个数n的二进制表示的第x位修改成14.将一个数n的二进制表示的第x位修改成0、5. 位图的思想6.提取一个数(n)二进制表示中最右侧的17.干掉一个数(n)二进制表示中最右侧的18.位运算的优先级9.异…

瞄准热门需求:7个最受欢迎的跑腿小程序开发灵感

跑腿服务在如今快节奏的社会中扮演着重要角色,而跑腿小程序成为满足人们日常需求的利器。如果你正计划开发一款跑腿小程序,那么把握住最热门的需求绝对是成功的关键。在本文中,我作为跑腿小程序开发领域的专家,将分享七个最受欢迎…

【UIPickerView案例07-省市选择界面数据展示03-城市选择Bug修复 Objective-C语言】

一、咱们先把前面的内容捋一下——省市选择界面: 1.首先呢,我们说,实现一个案例,第一步,先看界面, 1)第一步:先看界面, 2)第二步:分析一下它的基本结构, 3)第三步:搭建界面, 4)第四步:加载数据, 5)第五步:显示数据, 是不是五步, 大的就这五步, …

SpringMVC文件上传与下载、JREBEL使用

目录 一、引言 二、文件的上传 1、单文件上传 1.1、数据表准备 1.2、添加依赖 1.3、配置文件 1.4、编写表单 1.5、编写controller层 2、多文件上传 2.1、编写form表单 2.2、编写controller层 2.3、测试 三、文件下载 四、JREBEL使用 1、下载注册 2、离线设置 一…

“文件的上传与下载:实现与优化“

目录 引言1.文件的上传2.文件的下载3. JRebel安装使用4. 文件批量上传总结 引言 在开发过程中,文件的上传与下载是常见的需求。本篇博客将以CSND为例,介绍文件上传与下载的常见方式,以及如何通过优化提升性能和用户体验。 1.文件的上传 使…