实现读写分离与优化查询性能:通过物化视图在MySQL、PostgreSQL和SQL Server中的应用
实现读写分离与优化查询性能:通过物化视图在MySQL、PostgreSQL和SQL Server中的应用
在数据库管理中,读写分离是一种常见的性能优化方法,它通过将读操作和写操作分发到不同的服务器或数据库实例上,来减轻单个数据库的负载,提高应用的响应速度和吞吐量。物化视图作为一种存储在数据库中的查询结果集,提供了一种有效的数据缓存机制,可以进一步提高查询效率,特别是在处理复杂聚合数据时。本文将探讨如何在MySQL、PostgreSQL和SQL Server中使用物化视图来实现读写分离和优化查询性能。
场景设定
为了具体说明,我们以一个学校管理系统为例,该系统中有三个主要的表:学生表(Students)、课程表(Courses)、以及学生选课关系表(Enrollments)。我们的目标是创建一个物化视图,包含每个学生及其选修的课程数量,以此来提高查询效率。
MySQL的实现
MySQL直到最近版本才开始支持物化视图,通常需要通过创建一个实际的表来手动实现物化视图的效果,并通过事件调度器或触发器来维护数据的一致性。
截至我最后更新的信息,在MySQL官方版本中,并没有直接支持物化视图(Materialized View)的功能。物化视图是数据库视图的一种,它们将查询结果存储在磁盘上,可以提高数据检索速度,但需要管理数据的更新和刷新。
尽管MySQL官方版本不直接支持物化视图,有一些方法可以模拟这个功能:
-
手动创建物化视图:通过创建一个普通的表并将查询结果插入到这个表中来模拟物化视图。这需要手动或通过定时任务来更新数据。
-
使用第三方工具:例如,Flexviews是一个为MySQL添加物化视图支持的工具。它提供了增量刷新物化视图的功能。
-
使用触发器:创建数据库触发器,以在基础数据发生变化时自动更新模拟的物化视图表。
-
存储过程:编写存储过程定期刷新物化视图表中的数据。
-
使用MariaDB:如果您愿意切换到MySQL的一个分支,MariaDB从10.3版本开始提供了系统版本化表的概念,这可以用来实现类似物化视图的功能。
下面我将提供一个实例,展示如何使用Flexviews工具为MySQL添加物化视图,并且展示如何从Java后端调用它们。此示例假设您已经具备了Flexviews的基本安装知识以及Java开发的相关背景。
步骤 1: 设计数据库和表结构
1.1 首先,我创建了三个基本的表:students(学生表),courses(课程表)以及student_courses(学生选课表),它们的结构如下:
CREATE TABLE `students` (`student_id` INT NOT NULL AUTO_INCREMENT,`name` VARCHAR(100) NOT NULL,PRIMARY KEY (`student_id`)
);CREATE TABLE `courses` (`course_id` INT NOT NULL AUTO_INCREMENT,`title` VARCHAR(100) NOT NULL,PRIMARY KEY (`course_id`)
);CREATE TABLE `student_courses` (`student_id` INT NOT NULL,`course_id` INT NOT NULL,PRIMARY KEY (`student_id`, `course_id`),FOREIGN KEY (`student_id`) REFERENCES `students`(`student_id`),FOREIGN KEY (`course_id`) REFERENCES `courses`(`course_id`)
);
1.2 接下来,我插入了一些示例数据来模拟真实场景。
步骤 2: 安装Flexviews
2.1 我首先下载了Flexviews工具,并将其解压缩到我的服务器上。
2.2 然后,我运行了Flexviews附带的安装脚本来设置必要的存储过程和函数。
步骤 3: 配置Flexviews
3.1 创建了一个新的物化视图来存储学生及其选课的信息。这需要我在MySQL中执行Flexviews提供的存储过程。
3.2 为了创建物化视图,我需要首先定义一个Flexviews的视图,然后创建一个物化视图:
CALL flexviews.create('mv_student_course_summary', 'replace');CALL flexviews.add_table('mv_student_course_summary', 'students', 's', '');
CALL flexviews.add_table('mv_student_course_summary', 'student_courses', 'sc', 's.student_id = sc.student_id');
CALL flexviews.add_table('mv_student_course_summary', 'courses', 'c', 'sc.course_id = c.course_id');CALL flexviews.add_expr('mv_student_course_summary', 'column', 's.student_id', 'student_id');
CALL flexviews.add_expr('mv_student_course_summary', 'column', 's.name', 'student_name');
CALL flexviews.add_expr('mv_student_course_summary', 'column', 'c.title', 'course_title');CALL flexviews.enable('mv_student_course_summary');
步骤 4: 刷新物化视图
4.1 定义物化视图后,我定期调用刷新程序来更新数据。这可以通过设置一个定时任务来实现。
CALL flexviews.refresh( 'mv_student_course_summary', 'BOTH' );
步骤 5: 从Java后端调用物化视图
5.1 在我的Java应用程序中,我使用了JDBC来连接MySQL数据库,然后执行查询以获取物化视图的数据。
5.2 示例代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class FlexviewsExample {public static void main(String[] args) {String dbURL = "jdbc:mysql://yourHost:yourPort/yourDatabase";String username = "yourUsername";String password = "yourPassword";try {Connection conn = DriverManager.getConnection(dbURL, username, password);Statement stmt = conn.createStatement();String mvQuery = "SELECT student_id, student_name, course_title FROM mv_student_course_summary";ResultSet rs = stmt.executeQuery(mvQuery);while (rs.next()) {int studentId = rs.getInt("student_id");String studentName = rs.getString("student_name");String courseTitle = rs.getString("course_title");// 输出结果或进行其他处理System.out.println("Student ID: " + studentId + ", Name: " + studentName + ", Course: " + courseTitle);}} catch (Exception e) {e.printStackTrace();}}
}
5.3 为了运行上面的Java代码,我确保了JDBC驱动已经被添加到类路径中,并且数据库连接参数已经设置正确。
步骤 6: 测试和验证
6.1 最后,我进行了一系列的测试来确保物化视图可以正确地反映底层数据源的变化,并且Java应用程序能够正确地查询这些数据。
以上就是我实现MySQL中物化视图支持并通过Java后端调用的完整步骤。
如果MySQL在未来的版本中引入了物化视图,您应该查看该版本的官方文档以获取最新信息。对于模拟物化视图的最佳实践,通常需要根据应用的具体需求来定制解决方案。
对于读写分离,可以使用MySQL复制功能,将数据同步到一个或多个只读副本,查询操作可以在这些只读副本上执行,而写操作则在主数据库上执行。
PostgreSQL的实现
PostgreSQL原生支持物化视图,可以直接创建物化视图并在需要时刷新。
CREATE MATERIALIZED VIEW StudentCourseCount AS
SELECT s.student_id, COUNT(e.course_id) AS course_count
FROM Students s
JOIN Enrollments e ON s.student_id = e.student_id
GROUP BY s.student_id;
刷新物化视图:
REFRESH MATERIALIZED VIEW StudentCourseCount;
PostgreSQL同样支持读写分离,通常通过流复制和热备份来实现。应用程序可以将读请求路由到只读副本,而将写请求发送到主数据库。
SQL Server的实现
SQL Server通过索引视图提供类似物化视图的功能。创建一个索引视图需要首先创建一个普通视图,然后在其上创建一个唯一聚集索引。
CREATE VIEW StudentCourseCount WITH SCHEMABINDING AS
SELECT s.student_id, COUNT_BIG(e.course_id) AS course_count
FROM dbo.Students s
JOIN dbo.Enrollments e ON s.student_id = e.student_id
GROUP BY s.student_id;CREATE UNIQUE CLUSTERED INDEX IDX_StudentCourseCount ON StudentCourseCount(student_id);
SQL Server的读写分离可以通过数据库镜像、日志传送或Always On可用性组来实现,从而将读操作重定向到辅助数据库。
总结
通过在MySQL、PostgreSQL和SQL Server中创建和使用物化视图(或其等效物),可以显著提高复杂查询的性能,特别是在处理大量数据和进行频繁聚合时。结合读写分离策略,可以进一步优化数据库系统的整体性能,确保数据的高可用性和可靠性。在实现这些策略时,重要的是要充分理解各个数据库管理系统的特性和限制,以选择最适合特定应用场景的解决方案。
相关文章:
实现读写分离与优化查询性能:通过物化视图在MySQL、PostgreSQL和SQL Server中的应用
实现读写分离与优化查询性能:通过物化视图在MySQL、PostgreSQL和SQL Server中的应用 在数据库管理中,读写分离是一种常见的性能优化方法,它通过将读操作和写操作分发到不同的服务器或数据库实例上,来减轻单个数据库的负载&#x…...
pytest中文使用文档----10skip和xfail标记
1. 跳过测试用例的执行 1.1. pytest.mark.skip装饰器1.2. pytest.skip方法1.3. pytest.mark.skipif装饰器1.4. pytest.importorskip方法1.5. 跳过测试类1.6. 跳过测试模块1.7. 跳过指定文件或目录1.8. 总结 2. 标记用例为预期失败的 2.1. 去使能xfail标记 3. 结合pytest.param方…...
【Spring MVC】快速学习使用Spring MVC的注解及三层架构
💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:【Spring MVC】快速学习使用Spring MVC的注解及三层架构 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 Spring Web MVC一: 什么是Spring Web MVC࿱…...
Python(乱学)
字典在转化为其他类型时,会出现是否舍弃value的操作,只有在转化为字符串的时候才不会舍弃value 注释的快捷键是ctrl/ 字符串无法与整数,浮点数,等用加号完成拼接 5不入??? 还有一种格式化的方法…...
OpenHarmony实战:轻量级系统之子系统移植概述
OpenHarmony系统功能按照“系统 > 子系统 > 部件”逐级展开,支持根据实际需求裁剪某些非必要的部件,本文以部分子系统、部件为例进行介绍。若想使用OpenHarmony系统的能力,需要对相应子系统进行适配。 OpenHarmony芯片适配常见子系统列…...
Neo4j基础知识
图数据库简介 图数据库是基于数学里图论的思想和算法而实现的高效处理复杂关系网络的新型数据库系统。它善于高效处理大量的、复杂的、互连的、多变的数据。其计算效率远远高于传统的关系型数据库。 在图形数据库当中,每个节点代表一个对象,节点之间的…...
HTTP/1.1 特性(计算机网络)
HTTP/1.1 的优点有哪些? 「简单、灵活和易于扩展、应用广泛和跨平台」 1. 简单 HTTP 基本的报文格式就是 header body,头部信息也是 key-value 简单文本的形式,易于理解。 2. 灵活和易于扩展 HTTP 协议里的各类请求方法、URI/URL、状态码…...
每日一题————P5725 【深基4.习8】求三角形
题目: 题目乍一看非常的简单,属于初学者都会的问题——————————但是实际上呢,有一些小小的坑在里面。 就是三角形的打印。 平常我们在写代码的时候,遇到打印三角形的题,一般简简单单两个for循环搞定 #inclu…...
第三题:时间加法
题目描述 现在时间是 a 点 b 分,请问 t 分钟后,是几点几分? 输入描述 输入的第一行包含一个整数 a。 第二行包含一个整数 b。 第三行包含一个整数 t。 其中,0≤a≤23,0≤b≤59,0≤t, 分钟后还是在当天。 输出描…...
【RAG】内部外挂知识库搭建-本地GPT
大半年的项目告一段落了,现在自己找找感兴趣的东西学习下,看看可不可以搞出个效果不错的local GPT,自研下大模型吧 RAG是什么? 检索增强生成(RAG)是指对大型语言模型输出进行优化,使其能够在生成响应之前引用训练数据来…...
MySQL——锁
全局锁 全局锁是一种数据库锁定机制,它可以锁定整个数据库,阻止其他会话对数据库的读写操作。在MySQL中,全局锁定可以使用FLUSH TABLES WITH READ LOCK命令来实现。执行这个命令后,MySQL将获取一个全局读锁,直到当前会…...
C++(12): std::mutex及其高级变种的使用
1. 简述 在多线程或其他许多场景下,同时对一个变量或一段资源进行读写操作是一个比较常见的过程,保证数据的一致性和防止竞态条件至关重要。 C的标准库中为我们提供了使用的互斥及锁对象,帮助我们实现资源的互斥操作。 2. std::mutex及其衍…...
基于ROS软路由的百元硬件升级方案实现突破千兆宽带
前言 很多用户得利于FTTR光网络不断推广,家用宽带带宽已经实现千兆速率的突破。而现在很多ISP运营商已经在多个城市率先推出2000M光宽带。这种情况下,要想将自家宽带的带宽能够充分发挥利用,就需要对原有的千兆设备进行升级来满足突破千兆的…...
OpenHarmony实战开发-分布式关系型数据库
介绍 本示例使用ohos.data.relationalStore 接口和ohos.distributedDeviceManager 接口展示了在eTS中分布式关系型数据库的使用,在增、删、改、查的基本操作外,还包括分布式数据库的数据同步同能。 效果预览 使用说明: 1.启动应用后点击“”按钮可以添…...
图片标注编辑平台搭建系列教程(6)——fabric渲染原理
原理 fabric的渲染步骤大致如下: 渲染前都设置背景图然后调用ctx.save(),存储画布的绘制状态参数然后调用每个object自身的渲染方法最后调用ctx.restore(),恢复画布的保存状态后处理,例如控制框的渲染等 值得注意的是࿰…...
Qt中QIcon图标设置(标题、菜单栏、工具栏、状态栏图标)
1 exe程序图标概述 在 Windows 操作系统中,程序图标一般会涉及三个地方; (1) 可执行程序(以及对应的快捷方式)的图标 (2) 程序界面标题栏图标 (3)程序在任务…...
C语言程序10题
第101题 (10.0分) 难度:易 第2章 /*------------------------------------------------------- 【程序填空】 --------------------------------------------------------- 功能:计算平均成绩并统计90分以上人数。 --…...
定时器-间歇函数
1.开启定时器 setInterval(function (){console.log(一秒执行一次)},1000) function fn(){console.log(一秒执行一次) } setInterval(fn,1000) //调用有名的函数,只写函数名 1.函数名字不需要加小括号 2.定时器返回是一个id数字 每个定时器的序号是不一样的 2.关…...
Ajax-XMLHttpRequest基本使用
一、Ajax的原理 就是XMLHttpRequest对象。 二、为什么学习XHR? 有更多与服务器数据通信方式,了解Ajax内部。 三、XHR使用步骤 1.创建XHR对象 2.调用open方法,设置url和请求方法 3.监听loadend事件,接受结果 4.调用send方法…...
门控循环单元(GRU)
概述 门控循环单元(Gated Recurrent Unit, GRU)由Junyoung Chung等人于2014年提出,原论文为《Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling》。GRU是循环神经网络(Recurrent Neural Network, …...
解决SQL Server TLS协议不匹配:从驱动程序到安全配置的全面指南
1. 为什么会出现TLS协议不匹配的错误 最近在帮客户排查一个Java程序连接SQL Server的问题时,遇到了这个经典的TLS协议版本不匹配错误。错误信息显示"服务器选择了TLS1.0协议,但客户端只接受TLS1.2"。这种情况在现代开发环境中越来越常见&#…...
Llama-3.2V-11B-cot效果对比:与Qwen-VL、InternVL在CoT任务上的实测分析
Llama-3.2V-11B-cot效果对比:与Qwen-VL、InternVL在CoT任务上的实测分析 1. 模型概述与测试背景 Llama-3.2V-11B-cot 是一个基于Meta Llama 3.2 Vision架构的视觉语言模型,专门针对系统性推理任务进行了优化。该模型采用MllamaForConditionalGeneratio…...
Escrcpy - 免费开源!电脑控制安卓手机的投屏工具 (屏幕镜像 / 无线 / AI 自动化 / 录屏)
上班时想要看手机不方便?在电脑前办公时常要用到一些手机 APP?或你是开发者,需要在电脑上测试手机应用?又或是想在电脑上管理手机文件,甚至希望能直接远程操控手机? 在 iOS 都推出了官方 iPhone 镜像功能&…...
实战演练:从零构建基于线性表的图书管理系统
1. 为什么选择线性表实现图书管理系统 刚接触数据结构时,很多人会疑惑:为什么图书管理系统要用线性表实现?这个问题我也思考了很久。直到去年帮学校图书馆升级系统时,我才真正理解线性表的优势。想象一下图书馆的书架,…...
REFramework精进指南:7个核心实践与5个避坑策略
REFramework精进指南:7个核心实践与5个避坑策略 【免费下载链接】REFramework REFramework 是 RE 引擎游戏的 mod 框架、脚本平台和工具集,能安装各类 mod,修复游戏崩溃、卡顿等问题,还有开发者工具,让游戏体验更丰富。…...
USB通讯速度翻倍秘诀:手把手教你用WinUsb替代HID协议(附Zadig驱动配置图解)
USB通讯速度翻倍实战:WinUsb替代HID协议全指南 在物联网设备开发中,USB通讯速度常常成为性能瓶颈。传统HID协议虽然免驱方便,但其62.5KB/s的传输速率对于数据采集、固件升级等场景显得捉襟见肘。本文将带你深入理解WinUsb技术,通过…...
基于comsol技术的磁可调双带高效吸收器
comsol磁可调双带吸收器。搞电磁超材料的兄弟应该都懂,玩双带吸收器最头疼的就是怎么动态调谐。传统结构一旦加工成型,吸收峰就焊死在固定频段了。最近在COMSOL里折腾磁可调方案发现个骚操作——在铁氧体基底里埋钇铁石榴石(YIG)阵…...
淘宝商品详情字段解析:SKU、价格、库存接口全梳理
在电商数据采集、竞品分析、价格监控等场景中,淘宝商品详情数据是核心资产。本文聚焦淘宝开放平台商品详情接口的SKU、价格、库存三大核心字段,从接口调用到字段解析,再到实战代码与避坑指南,提供一套完整的技术方案,助…...
Obsidian笔记记录与Gitee云存储
Obsidian下载 首先下载ObsidianObsidian - 磨砺你的思维,下载完成后打开会弹出本地仓库创建的提示 每个仓库都是一个相对独立的空间,我们的笔记和插件都存放在里面,如核心插件的插入模板的模板文件夹和第三方插件都是各仓库独立,…...
真正的管理者,从不陷于具体事务
真正的管理者,从不陷于具体事务在管理实践中,存在一种普遍的误解:优秀的管理者必须巨细靡遗、亲力亲为,深入到每一项具体事务中,才能体现其负责与能干。然而,真正的管理智慧,绝非埋首于琐碎&…...
