实现读写分离与优化查询性能:通过物化视图在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, …...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
