跳至主要內容
PostgreSQL进阶特性实战:窗口函数、CTE与JSONB

前言

PostgreSQL 被称为"最先进的开源数据库",它的强大不止于基础 CRUD。窗口函数、CTE 递归查询和 JSONB 是 PG 中最让我印象深刻的三个进阶特性。学会它们,你的 SQL 能力将上升一个台阶——很多原本需要在 Java 代码里写几十行循环的逻辑,一句 SQL 就能优雅搞定。

本文通过大量实战案例,带你深入掌握这些特性,并展示如何在 Java/MyBatis 中灵活使用。


一、窗口函数:数据分析的瑞士军刀

1.1 什么是窗口函数

窗口函数(Window Function)在不折叠行的前提下进行聚合计算。与 GROUP BY 不同,窗口函数保留了每一行的独立性,同时可以引用"窗口"内的其他行。


郑天祺大约 17 分钟数据库MySQLPostgreSQL数据库
PostgreSQL vs MySQL:一个 Java 后端的视角

PostgreSQL vs MySQL:一个 Java 后端的视角

前言

作为一个 Java 后端开发者,数据库选型几乎是每个项目启动时都要面对的灵魂拷问。PostgreSQL 和 MySQL 作为开源关系型数据库的双雄,各自拥有庞大的用户群体和生态系统。本文从 Java 后端的视角出发,深入对比两者的核心差异,帮助你在实际项目中做出更明智的选型决策。

一、历史与定位

1.1 MySQL 的发展历程

MySQL 诞生于 1995 年,由瑞典公司 MySQL AB 开发。其设计初衷是追求简单、快速、易用,最早定位为中小型 Web 应用的数据库解决方案。2008 年被 Sun Microsystems 收购,2009 年随 Sun 一起归入 Oracle 旗下。


郑天祺大约 17 分钟数据库MySQLPostgreSQL数据库
深入理解 SELECT ... FOR UPDATE:确保数据库并发操作的一致性

引言

在多用户、高并发的Web应用和分布式系统中,确保数据库操作的一致性和完整性是至关重要的。当多个事务同时尝试修改同一数据时,可能会导致数据不一致、脏读、不可重复读或幻读等问题。为了应对这些挑战,SQL 提供了 SELECT ... FOR UPDATE 语句,它可以在查询的同时锁定所选的行,防止其他事务对其进行修改,直到当前事务提交或回滚。
本文将深入探讨 SELECT ... FOR UPDATE 的工作原理、使用场景、最佳实践以及潜在的风险,并通过实际案例帮助读者更好地理解和应用这一功能。


郑天祺大约 14 分钟数据库MySQL并发控制数据库
BigKey问题

BigKey 问题是指在 Redis 中某些键包含的数据量过大,导致这些键的操作(如读取、写入、删除等)消耗过多的内存和CPU资源,进而影响整个Redis实例的性能。解决 BigKey 问题的关键在于识别并优化这些大键,以提高系统的稳定性和响应速度。以下是几种常见的解决方法:

1. 识别 BigKey

使用 redis-cli 工具

  • MEMORY USAGE 命令:可以用来查看某个键占用的内存量。
    redis-cli --raw MEMORY USAGE <key>
    
  • SCAN 命令:结合 MEMORY USAGE 可以批量扫描并检查多个键的大小。
    redis-cli --bigkeys
    

郑天祺大约 4 分钟数据库Redis性能优化数据库
mysql回滚日志(undo log)

mysql的回滚日志(Undo Log)是InnoDB存储引擎中用于支持事务的ACID特性、实现多版本并发控制(MVCC)以及提供回滚功能的重要组成部分。以下是关于mysql回滚日志的关键点总结:

1. 作用

  • 事务回滚:如果一个事务在执行过程中遇到错误或被用户显式地回滚,Undo Log可以用来撤销该事务对数据库所做的所有更改。
  • 多版本并发控制(MVCC):通过保存旧版本的数据,Undo Log允许不同事务看到数据的不同快照,从而实现非锁定读取(例如SELECT语句不会被写操作阻塞),提高并发性能。

郑天祺大约 4 分钟数据库MySQLundo log数据库
mysql的死锁

1. 死锁的概念

死锁是指两个或多个事务互相等待对方释放资源,导致所有事务都无法继续执行的情况。每个事务都在等待其他事务持有的锁,形成一个循环依赖,从而导致系统无法继续前进。

2. 死锁的原因

死锁通常发生在并发事务之间争夺资源时,特别是在以下情况下:

  • 多个事务以不同的顺序锁定相同的资源:例如,事务A先锁定了表T1,然后尝试锁定表T2;而事务B先锁定了表T2,然后尝试锁定表T1。如果两个事务同时进行,可能会形成死锁。

  • 长时间持有锁:如果一个事务长时间持有锁而不释放,可能会导致其他事务等待过久,增加死锁的可能性。

  • 嵌套锁:当一个事务在一个事务内部又启动了另一个事务(嵌套事务),并且这两个事务都持有了不同的锁,可能会导致死锁。

  • 索引覆盖不全:如果查询没有使用合适的索引,可能会导致更多的行被锁定,增加了死锁的风险。

  • 隐式锁:某些操作(如SELECT ... FOR UPDATE)会隐式地获取行级锁,如果没有正确管理这些锁,可能会引发死锁。


郑天祺大约 7 分钟数据库MySQL死锁数据库
mysql重做日志(redo log)

mysql的重做日志(Redo Log)是InnoDB存储引擎中用于实现事务持久性和崩溃恢复的重要机制。以下是关于mysql重做日志的关键点总结:

1. 作用

  • 事务持久性:确保即使在系统崩溃的情况下,已经提交的事务也不会丢失。通过记录事务对数据库所做的物理更改,重做日志使得这些更改可以在系统重启时被重新应用。
  • 崩溃恢复:当mysql实例非正常关闭后重启时,可以通过重做日志恢复未完成的事务,保证数据的一致性和完整性。

郑天祺大约 4 分钟数据库MySQLredo log数据库
联合索引问题

联合索引(Composite Index)是数据库中一种重要的索引类型,它允许基于多个列的组合来加速查询。理解联合索引的实现原理有助于优化查询性能和设计高效的数据库结构。以下是关于联合索引实现原理的详细解释:

1. 联合索引的结构

联合索引本质上是一个B+树(或类似的平衡树结构),其中每个节点存储的是多个列的组合值。假设你有一个联合索引 ABC,那么索引树的结构是基于列 ABC 的组合值来排序的。


郑天祺大约 9 分钟数据库MySQL索引数据库
跳表

跳表(Skip List)是一种数据结构,旨在提供高效的插入、删除和查找操作,同时保持相对简单的实现。它结合了链表和二叉搜索树的优点,通过引入多级索引来加速查找过程。跳表最早由William Pugh在1989年提出,并因其高效性和易于实现而被广泛应用于各种场景,尤其是在分布式系统和内存数据库中。

1. 基本概念

跳表本质上是一个多层链表,每一层都是对下一层的“抽样”或“稀疏表示”。最底层(通常称为第0层)包含所有元素,按升序排列。每一层之上的层则只包含一部分元素,形成一个稀疏的索引。随着层数的增加,每一层的元素数量逐渐减少,直到最顶层可能只有少数几个元素。


郑天祺大约 5 分钟数据库数据结构数据库索引
分库分表概念篇

一、分库分表来历

当硬件达到瓶颈无法提升,通过把数据分散到不同的数据库中,使得单一数据库的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的。
比如:将电商数据库拆分为若干独立的数据库,并且对于大表来说也拆分为若干小表,通过这种数据库拆分的方法来解决数据库的性能问题。
分库分表的目的就是为了解决由于数据量过而导致数据库性能降低的问题,将原来独立的数据库拆分为若干数据库组成,将数据大表拆分成若干数据表,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。

二、 方式

分库分表的方式在生产中通常包括:垂直分库、垂直分表、水平分库和水平分表四种。


郑天祺大约 6 分钟数据库分库分表数据库架构
2