MySQL 8 的窗口函数:分组取第 N 条的三种写法
「每个分类取最新一条」是 SQL 里的经典难题。MySQL 8 之前只能靠自连接或者变量,写法别扭还有性能问题。有了窗口函数之后,这件事变得很自然。 数据准备 CREATE TABLE article ( id INT PRIMARY KEY, cat…
「每个分类取最新一条」是 SQL 里的经典难题。MySQL 8 之前只能靠自连接或者变量,写法别扭还有性能问题。有了窗口函数之后,这件事变得很自然。 数据准备 CREATE TABLE article ( id INT PRIMARY KEY, cat…
演练比事故便宜。这篇记录一次「假设有人执行了不带 WHERE 的 DELETE」的完整恢复过程,全程在测试库做。 场景设定 凌晨 2 点,有人执行: DELETE FROM orders; -- 忘了 WHERE 3 万条订单消失。备份是每天 3 点…
连接池配小了报「获取连接超时」,配大了数据库 CPU 打满。这两个极端我都遇到过,最后发现参数得按公式算,不能凭感觉。 先理解连接数不是免费的 每个 MySQL 连接在服务端对应一个线程,占内存(默认约 256KB 起,…
MySQL 5.7 也有 JSON 类型,但 PostgreSQL 的 JSONB 更成熟:支持索引、有丰富的操作符、能部分更新。这篇记一下实际用法和边界。 JSON vs JSONB json 保存原始文本,保留空格和键顺序;jsonb 保存解析后的二进制,…
“先更新数据库还是先删缓存”这个问题,面试常问,实际项目里也真的会出错。这篇把几种方案摊开说,重点是各自的失败场景。 方案一:先更新 DB,再删缓存 最常用的 Cache Aside。 def update(id, data): db.upda…
“数据量大了要分库分表”这句话害了不少项目。分片带来的复杂度是长期的:跨库 join 没了、事务要改成最终一致、扩容要迁移数据、运维要管更多实例。动手之前先算几个数。 第一步:现在到底多大 SELECT table_name, …
读写分离之后最常见的抱怨是“刚提交的数据查不到”。多数情况就是主从延迟。 先确认是不是延迟 SHOW SLAVE STATUS\G 关注三行: Slave_IO_Running: Yes Slave_SQL_Running: Yes Seconds_Behind_Master: 12 前两个…
联合索引的规则说起来就一句“最左前缀”,但为什么是这样、什么情况下会失效、覆盖索引又怎么省掉回表,值得用具体的例子走一遍。 B+ 树里到底按什么排序 CREATE INDEX idx_abc ON t (a, b, c); 这棵索引树按 a 排…
隔离级别这四个字背了很多年,但真正理解 RR(可重复读)是怎么“看起来”解决幻读的,还是自己开两个会话做实验之后。 准备 CREATE TABLE t (id INT PRIMARY KEY, v INT, KEY idx_v(v)) ENGINE=InnoDB; INSERT INTO …
有天下午开始,列表页偶尔要等五六秒才出来。不是一直慢,是“偶尔”,这种最难查。 先打开慢日志 SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1; SHOW VARIABLES LIKE 'slow_query_log_file'; …
建了索引却还在全表扫描,是日常开发里最常见的困惑。这篇把线上真实遇到过的几种情况整理一下,都不是玄学,都有明确原因。 一、列上套了函数或运算 -- 走不了索引 SELECT * FROM orders WHERE DATE(created_at) =…