当前位置: 首页 > news >正文

实现读写分离与优化查询性能:通过物化视图在MySQL、PostgreSQL和SQL Server中的应用

实现读写分离与优化查询性能:通过物化视图在MySQL、PostgreSQL和SQL Server中的应用

在数据库管理中,读写分离是一种常见的性能优化方法,它通过将读操作和写操作分发到不同的服务器或数据库实例上,来减轻单个数据库的负载,提高应用的响应速度和吞吐量。物化视图作为一种存储在数据库中的查询结果集,提供了一种有效的数据缓存机制,可以进一步提高查询效率,特别是在处理复杂聚合数据时。本文将探讨如何在MySQL、PostgreSQL和SQL Server中使用物化视图来实现读写分离和优化查询性能。

场景设定

为了具体说明,我们以一个学校管理系统为例,该系统中有三个主要的表:学生表(Students)、课程表(Courses)、以及学生选课关系表(Enrollments)。我们的目标是创建一个物化视图,包含每个学生及其选修的课程数量,以此来提高查询效率。

MySQL的实现

MySQL直到最近版本才开始支持物化视图,通常需要通过创建一个实际的表来手动实现物化视图的效果,并通过事件调度器或触发器来维护数据的一致性。
截至我最后更新的信息,在MySQL官方版本中,并没有直接支持物化视图(Materialized View)的功能。物化视图是数据库视图的一种,它们将查询结果存储在磁盘上,可以提高数据检索速度,但需要管理数据的更新和刷新。

尽管MySQL官方版本不直接支持物化视图,有一些方法可以模拟这个功能:

  1. 手动创建物化视图:通过创建一个普通的表并将查询结果插入到这个表中来模拟物化视图。这需要手动或通过定时任务来更新数据。

  2. 使用第三方工具:例如,Flexviews是一个为MySQL添加物化视图支持的工具。它提供了增量刷新物化视图的功能。

  3. 使用触发器:创建数据库触发器,以在基础数据发生变化时自动更新模拟的物化视图表。

  4. 存储过程:编写存储过程定期刷新物化视图表中的数据。

  5. 使用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&#xff1…...

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(),恢复画布的保存状态后处理,例如控制框的渲染等 值得注意的是&#xff0…...

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, …...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图,如果边框加在dom上面,pdf-lib导出svg的时候并不会导出边框,所以只能在echarts图上面加边框 grid的边框是在图里…...

2.2.2 ASPICE的需求分析

ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...

13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析

LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...