React从基础入门到高级实战:React 核心技术 - 错误处理与错误边界:构建稳定的应用
React 错误处理与错误边界:构建稳定的应用
在开发 React 应用时,错误处理是确保应用稳定性和用户体验的重要环节。无论是运行时错误、API 请求失败还是用户操作失误,合理的错误处理机制都能防止应用崩溃,并为用户提供清晰友好的反馈。React 提供了多种工具和技术来捕获和处理错误,其中**错误边界(Error Boundaries)**是处理组件渲染错误的强大机制。
本文面向关注应用稳定性的开发者,旨在帮助你全面掌握 React 中的错误处理技术。我们将从基础的 try-catch 和异步错误处理讲起,逐步深入到错误边界、全局错误处理和用户友好错误提示的实现方法。通过一个数据加载组件的案例和一个练习任务(为应用添加全局错误提示页面),你将学会如何在实际项目中应用这些技术。
文章目标
- 理解 try-catch 在 React 中的应用及其局限性。
- 掌握错误边界(Error Boundaries)的实现和使用场景。
- 学会使用 React Error Boundary 库实现全局错误处理。
- 设计用户友好的错误提示,提升用户体验。
- 通过数据加载组件案例和练习任务,巩固所学知识。
- 强调错误处理的优雅性,确保应用稳定运行。
1. try-catch 与异步错误处理
1.1 try-catch 在 React 中的应用
在 JavaScript 中,try-catch
是捕获同步错误的经典方法。在 React 组件中,我们通常在事件处理函数或生命周期方法中使用 try-catch
来捕获可能抛出错误的代码。这种方法简单直接,适用于处理同步操作中的异常。
代码示例
考虑一个按钮点击事件的处理函数,假设 someFunctionThatMightThrow
可能会抛出错误:
class MyComponent extends React.Component {state = { error: null };handleClick = () => {try {const result = someFunctionThatMightThrow();// 处理成功情况} catch (error) {console.error('发生错误:', error);this.setState({ error: error.message });}};render() {return (<div><button onClick={this.handleClick}>点击</button>{this.state.error && <p>错误: {this.state.error}</p>}</div>);}
}
- 优点:
try-catch
易于实现,能够捕获同步代码中的错误并防止其传播。 - 局限性:无法捕获异步操作(如
setTimeout
、Promise
)中的错误,因为异步代码在try-catch
块之外执行。
1.2 异步错误处理
对于异步操作,错误处理需要结合 catch
或 async/await
来实现。React 组件中常见的异步场景包括 API 请求、定时器或文件操作。
使用 Promise 的错误处理
假设我们需要在组件挂载时从服务器获取数据:
class AsyncComponent extends React.Component {state = { data: null, error: null };componentDidMount() {fetchData().then((data) => {this.setState({ data });}).catch((error) => {console.error('API 错误:', error);this.setState({ error: error.message });});}render() {return (<div>{this.state.error ? (<p>加载失败: {this.state.error}</p>) : (<p>数据: {this.state.data || '加载中...'}</p>)}</div>);}
}
then
和catch
:then
处理成功情况,catch
捕获 Promise 拒绝时的错误。
使用 async/await 的错误处理
async/await
使异步代码更易读,结合 try-catch
可以优雅地处理错误:
class AsyncComponent extends React.Component {state = { data: null, error: null };async componentDidMount() {try {const data = await fetchData();this.setState({ data });} catch (error) {console.error('API 错误:', error);this.setState({ error: error.message });}}render() {return (<div>{this.state.error ? (<p>加载失败: {this.state.error}</p>) : (<p>数据: {this.state.data || '加载中...'}</p>)}</div>);}
}
- 优点:代码结构清晰,逻辑更接近同步代码。
- 注意:确保在异步函数中使用
try-catch
,否则错误不会被捕获。
异步错误处理的注意事项
- 错误传播:未捕获的异步错误不会触发 React 的错误处理机制,可能导致“未处理的 Promise 拒绝”警告。
- 状态管理:异步操作通常涉及加载状态,建议添加
loading
状态以提升用户体验。
2. 错误边界:componentDidCatch
和 ErrorBoundary
2.1 什么是错误边界?
错误边界(Error Boundaries)是 React 提供的一种特殊组件,用于捕获子组件树中的 JavaScript 错误,防止整个应用崩溃。错误边界通过实现 componentDidCatch
生命周期方法来捕获渲染期间的错误,并提供备用 UI。
基本实现
class ErrorBoundary extends React.Component {state = { hasError: false, error: null };static getDerivedStateFromError(error) {// 在渲染阶段更新 statereturn { hasError: true, error };}componentDidCatch(error, errorInfo) {// 在提交阶段记录错误信息console.error('捕获到错误:', error, errorInfo);}render() {if (this.state.hasError) {return <h1>出错了: {this.state.error.message}</h1>;}return this.props.children;}
}
getDerivedStateFromError
:静态生命周期方法,用于捕获错误并更新状态。componentDidCatch
:记录错误详情,可用于日志记录或发送错误报告。- 使用方式:将需要保护的组件包裹在
<ErrorBoundary>
中。
使用示例
function BuggyComponent() {throw new Error('模拟错误');return <div>这不会渲染</div>;
}function App() {return (<ErrorBoundary><BuggyComponent /></ErrorBoundary>);
}
- 当
BuggyComponent
抛出错误时,<ErrorBoundary>
会捕获错误并显示备用 UI。
2.2 错误边界的局限性
尽管错误边界非常强大,但它有以下限制:
- 仅捕获渲染错误:无法捕获事件处理函数、异步代码或服务器端渲染中的错误。
- 无法捕获自身错误:错误边界组件自身的错误不会被捕获。
- 仅适用于类组件:函数组件无法直接实现
componentDidCatch
。
2.3 函数组件中的错误边界
目前,React 官方尚未为函数组件提供内置的错误边界支持,但 React 18 引入了实验性的 useErrorBoundary
Hook。当前,开发者通常使用第三方库(如 react-error-boundary
)来解决这一问题。
3. 全局错误处理:React Error Boundary 库
3.1 为什么需要全局错误处理?
在大型 React 应用中,错误可能发生在任何组件中,分散的错误处理会导致代码重复和用户体验不一致。全局错误处理机制可以统一捕获和处理错误,确保用户获得一致的反馈。
3.2 使用 React Error Boundary 库
react-error-boundary
是一个流行的错误边界库,支持函数组件,提供丰富的错误处理功能。
安装
npm install react-error-boundary
基本使用
import { ErrorBoundary } from 'react-error-boundary';function ErrorFallback({ error, resetErrorBoundary }) {return (<div><h1>出错了</h1><p>{error.message}</p><button onClick={resetErrorBoundary}>重试</button></div>);
}function App() {return (<ErrorBoundary FallbackComponent={ErrorFallback}><BuggyComponent /></ErrorBoundary>);
}
- FallbackComponent:自定义错误显示组件,接收
error
和resetErrorBoundary
参数。 - resetErrorBoundary:重置错误状态,恢复组件的正常渲染。
3.3 实现全局错误处理
通过在应用的顶层组件(如 App
)中包裹 <ErrorBoundary>
,可以实现全局错误捕获。
import { ErrorBoundary } from 'react-error-boundary';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';function ErrorFallback({ error, resetErrorBoundary }) {return (<div><h1>抱歉,发生了一个错误</h1><p>{error.message}</p><button onClick={resetErrorBoundary}>重试</button></div>);
}function App() {return (<ErrorBoundary FallbackComponent={ErrorFallback}><Router><Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} /></Routes></Router></ErrorBoundary>);
}
- 效果:任何子组件抛出错误时,应用会显示统一的错误页面。
4. 用户友好的错误提示
4.1 设计原则
用户友好的错误提示应遵循以下原则:
- 清晰:错误信息简洁明了,告诉用户发生了什么。
- 友好:避免使用技术术语,采用用户易懂的语言。
- 引导:提供解决方案或操作建议,如“重试”或“联系客服”。
- 品牌一致:错误页面应与应用风格一致,保持品牌形象。
4.2 实现方法
- 自定义错误页面:设计一个通用的错误组件,包含错误信息和操作按钮。
- 错误分类:根据错误类型(如网络错误、权限错误)显示不同提示。
- 日志记录:在后台记录错误详情,便于开发者调试。
代码示例
function ErrorFallback({ error }) {return (<div className="error-page"><h1>抱歉,发生了一个错误</h1><p>错误信息: {error.message}</p><button onClick={() => window.location.reload()}>刷新页面</button><p>或联系客服: support@example.com</p></div>);
}
- 样式:通过 CSS 定制错误页面外观。
- 功能:提供刷新页面或联系支持的选项。
5. 案例:数据加载组件
以下是一个数据加载组件,展示如何处理 API 错误并提供用户友好的反馈。
import { useState, useEffect } from 'react';function DataLoader() {const [data, setData] = useState(null);const [error, setError] = useState(null);const [loading, setLoading] = useState(true);useEffect(() => {const fetchData = async () => {try {const response = await fetch('https://api.example.com/data');if (!response.ok) throw new Error('网络请求失败');const result = await response.json();setData(result);} catch (err) {setError(err.message);} finally {setLoading(false);}};fetchData();}, []);if (loading) return <p>加载中...</p>;if (error) return <p>加载失败: {error}</p>;return <div>数据: {JSON.stringify(data)}</div>;
}
- 错误处理:捕获网络请求错误并显示错误信息。
- 用户反馈:通过
loading
和error
状态提供清晰的反馈。
6. 练习:为应用添加全局错误提示页面
请为一个多页面 React 应用添加全局错误处理机制,具体要求如下:
- 使用
react-error-boundary
库。 - 设计一个通用的错误提示页面,包含错误信息和重试按钮。
- 在应用的顶层组件中包裹
<ErrorBoundary>
。 - 确保错误页面与应用风格一致。
参考实现
import { ErrorBoundary } from 'react-error-boundary';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';function ErrorFallback({ error, resetErrorBoundary }) {return (<div className="error-page"><h1>抱歉,发生了一个错误</h1><p>{error.message}</p><button onClick={resetErrorBoundary}>重试</button></div>);
}function Home() {return <h2>首页</h2>;
}function About() {throw new Error('关于页面错误');return <h2>关于</h2>;
}function App() {return (<ErrorBoundary FallbackComponent={ErrorFallback}><Router><Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} /></Routes></Router></ErrorBoundary>);
}
- 测试:访问
/about
路径会触发错误,显示错误页面。 - 样式:可添加 CSS 使错误页面与应用风格一致。
7. 强调错误处理的优雅性
优雅的错误处理不仅能提升用户体验,还能增强应用的可靠性。以下是几点建议:
- 避免应用崩溃:使用错误边界捕获错误,防止整个应用崩溃。
- 提供有用反馈:错误提示应帮助用户理解问题并提供解决方案。
- 记录错误:在后台记录错误详情,便于开发者快速定位和修复。
- 设计备用方案:在关键功能失败时,提供替代操作或降级体验。
8. 总结与进阶建议
本文系统介绍了 React 中的错误处理技术,从基础的 try-catch 到高级的错误边界和全局错误处理,帮助你构建稳定且用户友好的应用。
总结
- try-catch:适用于同步和异步错误处理。
- 错误边界:捕获组件渲染错误,防止应用崩溃。
- 全局错误处理:使用
react-error-boundary
实现统一错误管理。 - 用户友好提示:设计清晰、友好的错误页面。
进阶建议
- 探索 React 18 的
useErrorBoundary
Hook(实验性)。 - 学习如何在服务器端渲染(SSR)中处理错误。
希望本文能为你提供坚实的指导,让你在 React 应用中自信地处理各种错误!
以下是完整的 React 应用示例,包含所有功能:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>React 错误处理示例</title><script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js"></script><script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js"></script><script src="https://cdn.jsdelivr.net/npm/react-router-dom@6.3.0/dist/umd/react-router-dom.min.js"></script><script src="https://cdn.jsdelivr.net/npm/react-error-boundary@4.0.11/dist/react-error-boundary.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.22.9/babel.min.js"></script><style>.error-page {padding: 20px;text-align: center;background-color: #f8d7da;color: #721c24;border: 1px solid #f5c6cb;border-radius: 5px;max-width: 600px;margin: 20px auto;}.error-page button {padding: 10px 20px;background-color: #721c24;color: white;border: none;border-radius: 5px;cursor: pointer;}.error-page button:hover {background-color: #501115;}</style>
</head>
<body><div id="root"></div><script type="text/babel">const { useState, useEffect } = React;const { BrowserRouter, Routes, Route } = ReactRouterDOM;const { ErrorBoundary } = ReactErrorBoundary;// 错误回退组件function ErrorFallback({ error, resetErrorBoundary }) {return (<div className="error-page"><h1>抱歉,发生了一个错误</h1><p>{error.message}</p><button onClick={resetErrorBoundary}>重试</button><p>或联系客服: support@example.com</p></div>);}// 数据加载组件function DataLoader() {const [data, setData] = useState(null);const [error, setError] = useState(null);const [loading, setLoading] = useState(true);useEffect(() => {const fetchData = async () => {try {const response = await fetch('https://api.example.com/data');if (!response.ok) throw new Error('网络请求失败');const result = await response.json();setData(result);} catch (err) {setError(err.message);} finally {setLoading(false);}};fetchData();}, []);if (loading) return <p>加载中...</p>;if (error) return <p>加载失败: {error}</p>;return <div>数据: {JSON.stringify(data)}</div>;}// 页面组件function Home() {return (<div><h2>首页</h2><DataLoader /></div>);}function About() {throw new Error('关于页面错误');return <h2>关于</h2>;}// 主应用组件function App() {return (<ErrorBoundary FallbackComponent={ErrorFallback}><BrowserRouter><Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} /></Routes></BrowserRouter></ErrorBoundary>);}// 渲染应用ReactDOM.render(<App />, document.getElementById('root'));</script>
</body>
</html>
这篇文章和示例代码提供了全面的错误处理指南,涵盖理论、实践和优雅性要求。希望它能帮助你在 React 开发中构建更加稳定和用户友好的应用!
相关文章:
React从基础入门到高级实战:React 核心技术 - 错误处理与错误边界:构建稳定的应用
React 错误处理与错误边界:构建稳定的应用 在开发 React 应用时,错误处理是确保应用稳定性和用户体验的重要环节。无论是运行时错误、API 请求失败还是用户操作失误,合理的错误处理机制都能防止应用崩溃,并为用户提供清晰友好的反…...
页面输入数据的表格字段(如 Web 表单或表格控件)与后台数据库进行交互时常用的两种方式
“从页面输入数据的表格字段(如 Web 表单或表格控件)在与后台数据库进行交互时,常用的有两种方式:” 🎯 两种方式(操作调用数据库、绑定数据) 🚀 方式1:前端代码提交数据到后端,再由后端调用数据库 💡 原理和逻辑: 用户在页面上(比如输入表单、表格)输入数据…...

碰一碰发视频-源码系统开发技术分享
#碰一碰营销系统# #碰一碰系统# #碰一碰发视频# 架构设计哲学:近场通信的优雅平衡 一、核心通信技术选型 1. 双模协同传输引擎 技术协议栈延迟控制适用场景NFCISO 14443-A<100ms精准触发场景BLE 5.0GATT Profile300-500ms中距传输场景 工程决策依据&…...

C++学习过程分享
空指针:int *p NULL; 空指针:指针变量指向内存中编号为0的空间;用途:初始化指针变量注意:空指针指向的内存不允许访问注意:内存编号为0-255为系统占用空间,不允许用户访问 野指针:…...

C语言 — 动态内存管理
目录 1.malloc和free函数1.1 malloc函数1.2 free函数1.3 malloc函数的使用 2.calloc函数2.1 calloc函数2.2 calloc函数的使用 3.realloc函数3.1 realloc函数3.2 realloc函数的使用 4.动态内存管理笔试题4.1 笔试题(1)4.2 笔试题(2)…...

《TCP/IP 详解 卷1:协议》第5章:Internet协议
IPv4和IPv6头部 IP是TCP/IP协议族中的核心协议。所有TCP、UDP、ICMP和IGMP 数据都通过IP数据报传输。IP提供了一种尽力而为、无连接的数据报交付服务。 IP头部字段 IPv4 头部通常为 20 字节(无选项时),而 IPv6 头部固定为 40 字节。IPv6 不…...
C#面向对象实践项目--贪吃蛇
目录 一、项目整体架构与核心逻辑 二、关键类的功能与关系 1. 游戏核心管理类:Game 2. 场景接口与基类 3. 具体场景类 4. 游戏元素类 5. 基础结构体与接口 三.类图 四、核心流程解析 五、项目可优化部分 一、项目整体架构与核心逻辑 该项目运用场景管理模…...

学习STC51单片机26(芯片为STC89C52RCRC)
每日一言 真正的强者,不是没有眼泪,而是含着泪依然奔跑。 硬件:4G模块 这个是接线原理,我们也只要知道这个4根线的连接就好了,我们也是连接到USB转TTL的模块上 要插卡哈......... 随后我们下载一个叫做亿佰特的调试助…...
Web前端为什么要打包?Webpack 和 Vite 如何助力现代开发?
一. 为什么要使用框架库? 1.1 传统网页与现代前端的差异 在最早期的网页开发中,我们只需要写几个.html文件,配上.css和.js文件,浏览器直接加载就能展现页面,每个文件都是独立的静态资源,简单且直观 但现在网站越来越复杂了: 需要用到最新的js语法(比如ES6)使用框架(Vue…...

Nginx详解(三):ngx_http_rewrite_module模块核心指令详解
概要: 在 Nginx 的众多功能模块中,ngx_http_rewrite_module是实现请求动态处理的核心组件,它通过一系列指令实现 URI 重写、条件判断、响应返回等功能。本文将以 CentOS 7.9 环境为例(主机名www.a.com,IP 172.25.0.10…...
C++ 建造者模式:简单易懂的设计模式解析
一、引言 在软件开发中,我们经常会遇到一些复杂对象的创建过程,这些对象通常由多个部分组成,并且每个部分的构建过程可能非常复杂。建造者模式(Builder Pattern)就是为了解决这类问题而诞生的一种创建型设计模式。本文将以简单易懂的方式介绍C++中的建造者模式,帮助你理…...

【笔记】在 MSYS2(MINGW64)中正确安装 Poetry 的指南
#工作记录 在 MSYS2(MINGW64)中正确安装 Poetry 的指南 一、背景说明 在 MSYS2(MINGW64)环境中,即使已经安装了 pip,也不建议直接使用 pip install poetry 来安装 Poetry。 这是因为 MSYS2 使用自己的包…...

IDEA项目推送到远程仓库
打开IDEA——>VCS——>Creat Git 选择项目 push提交到本地 创建远程仓库 复制地址 定义远程仓库 推送 推送成功...
DeepSeek 赋能 NFT:数字艺术创作与交易的革新密码
目录 一、NFT:数字世界的独特资产1.1 NFT 的定义与本质1.2 NFT 的价值支撑1.3 NFT 的丰富类型 二、DeepSeek:AI 领域的创新力量2.1 DeepSeek 的发展历程与成就2.2 DeepSeek 的核心技术与能力 三、DeepSeek 在 NFT 创作中的神奇应用3.1 高效生成数字艺术作…...

【后端架构师的发展路线】
后端架构师的发展路线是从基础开发到技术领导的系统性进阶过程,需融合技术深度、架构思维和业务洞察力。以下是基于行业实践的职业发展路径和关键能力模型: 一、职业发展阶梯 初级工程师(1-3年) 核心能力:掌…...

matlab/simulink TLC语法基础练习实例
一、基本语法测试方法 1.新建一个脚本,保存扩展名为tlc,本例中是tst.tlc,设置当前工作路径为保存的tlc文件路径,在tlc文件里面输入下面的代码,然后保存: %warning test 2.在MATLAB的命令窗口输入: tlc …...
MAU算法流程理解
参考文献:湘江船闸的过闸调度算法研究(李 楠,李桂华,尹剑平) (湖南湘江航运建设开发有限公司,湖南 长沙 410011) MAU算法流程 图4展示的是一种船舶排档算法(MAU算法),它…...

蓝桥杯国赛训练 day1
目录 k倍区间 舞狮 交换瓶子 k倍区间 取模后算组合数就行 import java.util.HashMap; import java.util.Map; import java.util.Scanner;public class Main {static Scanner sc new Scanner(System.in);public static void main(String[] args) {solve();}public static vo…...

ESP32之Linux编译环境搭建流程
背景:为了解决 “windows环境中编译ESP32代码速度慢” 的问题,现搭建一个Linux环境,让windows下的VScode连接到Linux环境,VSCode负责编辑代码,虚拟机用于编译代码。 目录 一、安装VMware 1.1 获取VMware安装包 1.2…...
Linux 软件安装方式全解(适用于 CentOS/RHEL 系统)
🐧 Linux 软件安装方式全解(适用于 CentOS/RHEL 系统) 在 Linux 系统中,软件安装方式丰富多样,常见于以下几种方式: 安装方式命令/工具说明软件包管理器(推荐)yum, dnf, apt, zypp…...
QT- QML Layout+anchors 布局+锚点实现窗口部件权重比例分配
布局管理 简单比较两种界面管理锚点布局实现比例布局布局管理实现比例布局循环依赖问题简谈 在日常打螺丝中,我们偶尔会需要实现界面各组件能按比例放置,自适应各种分辨率的需求。我用锚点和布局都实现过相关界面,记录下来两种方式实现的差异…...

UE5打包项目设置Project Settings(打包widows exe安装包)
UE5打包项目Project Settings Edit-Project Settings- Packaging-Ini Section Denylist-Advanced 1:打包 2:高级设置 3:勾选创建压缩包 4:添加要打包地图Map的数量 5:选择要打包的地图Maps 6:Project-Bui…...
Python中os模块详解
Python os 模块详解 os 模块提供了丰富的文件和目录操作、环境变量访问、进程管理等功能,是与操作系统交互的核心模块之一。 基本导入方式 import os常用目录与文件操作 1️⃣ 获取/设置当前工作目录 os.getcwd() # 获取当前工作目录 os.chdir(/tmp) …...

便捷高效能源服务触手可及,能耗监测系统赋能智能建筑与智慧城市
在建筑行业迈向智能化、精细化管理的进程中,传统建筑管理模式因信息割裂、数据利用不足等问题,逐渐难以满足现代建筑复杂的运营需求。楼宇自控系统实现了建筑设备的智能调控,BIM技术则构建了建筑的三维数字化模型,当两者相遇&…...
Kotlin List 操作全面指南
在传统 Java 开发 List 相关的 API 中,有着样板代码冗长、缺乏链式调用、空安全等问题。 Kotlin 这门语言 为 List 提供了丰富的扩展函数,这些函数大大简化了集合操作,解决了传统 Java 集合 API 中的许多痛点。 一、基础操作 1. 创建 List …...
C++--范围for循环详解
范围 for 循环是 C11 引入的语法特性,用于简化遍历容器或数组元素的过程。它比传统 for 循环更简洁安全,特别适合初学者。以下是详细讲解: 基本语法 for (元素类型 变量名 : 容器/数组) {// 循环体(使用变量名访问当前元素&#…...

ISO18436-2 CATII级振动分析师能力矩阵
ISO18436-2021是当前针对针对分析师的一个标准,它对振动分析师的能力和知识体系做了4级分类,这里给出的是一家公司响应ISO18436的CATII级标准,做的一个专题培训的教学大纲。摘自: 【振動噪音產學技術聯盟】04/19-23 ISO 18436-2…...
deepseek问答:torch.full() 函数详解
torch.full() 是 PyTorch 中用于创建指定形状、所有元素值都相同的新张量的核心函数。它在深度学习中有广泛应用,尤其是在初始化张量和创建特殊数据结构时。 函数签名 torch.full(size, fill_value, *, dtypeNone, layouttorch.strided, deviceNone, requires_gra…...

dvwa4——File Inclusion
LOW: 先随便点开一个文件,可以观察到url栏变成这样,说明?page是dvwa当前关卡用来加载文件的参数 http://10.24.8.35/DVWA/vulnerabilities/fi/?pagefile1.php 我们查看源码 ,没有什么过滤,直接尝试访问其他文件 在url栏的pag…...
MYSQL 高级 SQL 技巧
高级 SQL 技巧 以下是一些高级 SQL 技巧,可以帮助优化查询、提高性能并解决复杂的数据处理问题。 使用窗口函数 窗口函数允许在查询结果的行上进行计算,而不会减少行数。常见的窗口函数包括 ROW_NUMBER()、RANK()、DENSE_RANK() 和聚合函数如 SUM() 与…...