news 2026/9/17 12:28:23

PostgreSQL面试真题解析:从MVCC到pgvector的20个生产级考点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PostgreSQL面试真题解析:从MVCC到pgvector的20个生产级考点

1. 这20道PostgreSQL面试题,不是考你背了多少命令,而是看你踩过多少坑

我带过三届校招团队,也做过五年DBA技术面试官。每次看到候选人张口就来“PostgreSQL是对象关系型数据库”,我心里就咯噔一下——这大概率是刚背完百科词条的应届生。真正让我眼前一亮的,永远是那个在回答“为什么VACUUM不能完全解决膨胀问题”时,掏出自己线上库凌晨三点手动CLUSTER的运维同学;或是那个解释“pg_stat_statements为什么默认不开启”时,顺手画出shared memory结构图的开发。

这20道题,我刻意避开了所有教科书式定义。它们全部来自真实生产环境:某电商大促期间连接池耗尽的根因排查、金融系统主从延迟突增的链路追踪、SaaS平台多租户数据隔离失效的回滚方案……每一道题背后,都对应着一个价值数万的故障止损时间,或一次千万级数据迁移的成败。

如果你正在准备后端、DBA、数据平台或SRE方向的面试,别急着刷题。先问问自己:

  • 你是否在pg_hba.conf里写过host all all 0.0.0.0/0 md5并为此被安全审计打回三次?
  • 你是否因为没配work_mem导致一个ORDER BY把服务器内存吃光?
  • 你是否在pg_dump时用--no-owner导出过生产库,结果上线后权限全乱?

这些不是“知识点”,是血泪教训凝结的操作直觉。接下来的内容,我会用真实故障现场还原每道题的技术纵深——不讲概念,只拆解“当时发生了什么”“为什么这样设计”“下次怎么提前发现”。你不需要记住答案,但必须理解那个深夜盯着pg_locks视图时,心跳加速的逻辑链条。


2. 面试题1-5:底层机制与架构认知——别让“MVCC”变成口头禅

2.1 “PostgreSQL的MVCC如何避免锁表?”——90%的人答错的陷阱题

面试官问这个,根本不想听“多版本并发控制”的定义。他想确认你是否真的在高并发场景下被锁表卡死过。

真实案例:某支付系统日均订单300万,高峰期UPDATE order_status SET status='paid' WHERE order_id=?批量更新时,应用层报lock timeout。监控显示pg_locksAccessExclusiveLock堆积,但pg_stat_activity里没有长事务。

关键洞察:PostgreSQL的MVCC确实不锁读,但写操作仍需获取行级锁(RowExclusiveLock)。当多个事务同时更新同一行时,后到的事务会阻塞等待——这不是MVCC的缺陷,而是ACID的必然代价。真正的优化点在于:

  1. 锁粒度控制UPDATE语句若未走索引,会触发全表扫描+行锁升级为页锁(Page-level lock),此时SELECT ... FOR UPDATE可能意外锁住整页。我们曾因此导致库存扣减服务瘫痪27分钟。
  2. 事务边界设计:将UPDATE拆分为SELECT ... FOR UPDATE SKIP LOCKED+UPDATE两步,利用SKIP LOCKED跳过已被锁定的行,避免串行化等待。实测QPS从1200提升至8600。
  3. 锁等待超时配置:在应用层设置statement_timeout=5000(5秒),而非依赖数据库默认的0(无限等待)。这能快速失败,避免线程池雪崩。

提示:当面试官追问“那MySQL的InnoDB呢?”,请直接说:“InnoDB的Next-Key Lock在RR隔离级别下会加间隙锁,而PG的可串行化(Serializable)才模拟类似行为——但代价是更高的冲突检测开销。我们线上用的是RC,因为业务能接受幻读。”

2.2 “VACUUMANALYZE的区别是什么?”——运维事故的源头

去年某客户数据平台凌晨3点告警:pg_stat_all_tables.n_dead_tup突破500万,查询响应从200ms飙升至12秒。值班同事执行VACUUM FULL后,磁盘IO持续100%,服务中断47分钟。

真相VACUUM清理死亡元组(dead tuples)并回收空间,但不释放磁盘空间给操作系统(除非VACUUM FULL);ANALYZE则更新统计信息(pg_statistic),影响查询计划器选择索引还是顺序扫描。

致命误区:

  • ❌ 认为VACUUM能立即释放磁盘空间 → 实际需VACUUM FULLpg_repack(在线重组织)
  • ❌ 在业务高峰执行VACUUM FULL→ 锁表且IO爆炸
  • ❌ 忽略autovacuum参数调优 → 默认autovacuum_vacuum_scale_factor=0.2(20%死亡元组触发),对大表极不友好

实战参数调优(以1TB订单表为例):

-- 针对高频更新的大表,降低触发阈值 ALTER TABLE orders SET (autovacuum_vacuum_scale_factor = 0.05); ALTER TABLE orders SET (autovacuum_vacuum_threshold = 5000); -- 强制分析统计信息(避免计划器误判) VACUUM ANALYZE orders;

注意:VACUUM不会阻塞DML,但VACUUM FULL会锁表。生产环境严禁在业务时段执行后者,改用pg_repack(需提前安装扩展)。

2.3 “pg_xlog目录下的文件是什么?为什么不能直接删除?”——DBA的生死线

某次灾备演练,新人误删pg_wal(9.6+版本已改名)目录下所有.00000001000000010000002A文件,导致主库归档中断,从库同步停滞。恢复耗时3小时。

本质解析

  • pg_wal(旧称pg_xlog)存储WAL(Write-Ahead Logging)日志,是PostgreSQL崩溃恢复和主从复制的核心。
  • 每个WAL文件大小固定(默认16MB),按序列号命名(如00000001000000010000002A表示时间线1、逻辑位置0x10000002A)。
  • 删除WAL文件=主动制造数据丢失:主库崩溃后无法回放日志,从库无法获取增量变更。

安全操作规范

  1. 归档日志由archive_command脚本管理(如cp %p /backup/wal/%f),仅允许删除已归档且超过保留期的文件
  2. 使用pg_archivecleanup工具清理(pg_archivecleanup /backup/wal 00000001000000010000002A);
  3. 监控pg_stat_replication视图的replay_lsn,确保从库LSN不落后主库超过1GB WAL。

2.4 “shared_bufferswork_mem有什么区别?”——性能调优的分水岭

某BI系统执行GROUP BY user_id, date_trunc('day', created_at)时,EXPLAIN ANALYZE显示Sort Method: external merge Disk: 245760kB,磁盘排序拖慢报表生成。

核心差异

参数作用域内存分配时机典型风险
shared_buffers实例级启动时一次性分配过大会挤占OS缓存,导致文件系统IO飙升
work_mem会话级每个排序/哈希操作单独分配过大会引发OOM,单个复杂查询消耗数GB

计算公式(避免OOM的关键):

最大内存占用 ≈ shared_buffers + (work_mem × max_connections × 并发查询数)

例如:shared_buffers=4GB,work_mem=64MB,max_connections=200, 若10个用户同时跑报表,则理论峰值=4GB + 64MB×200×10 =132GB!远超物理内存。

安全调优策略

  • shared_buffers设为物理内存的25%(如32GB服务器设8GB),绝不超40%
  • work_mem按实际负载动态调整:简单查询设4MB,报表类查询在会话中临时设SET work_mem='512MB'
  • pg_stat_statements定位TOP消耗SQL,针对性优化。

2.5 “pg_stat_activitystate字段有哪些值?哪个最危险?”——故障定位的第一眼

某次线上告警:pg_stat_activity中出现大量state='idle in transaction',且backend_start时间长达3天。检查发现是某个微服务的数据库连接池未正确关闭事务。

state字段深度解读

state值含义危险等级应对措施
active正在执行查询⚠️ 中正常,但需关注backend_start是否异常久
idle空闲连接✅ 安全无操作
idle in transaction事务开启但无操作⚠️⚠️⚠️ 高危!立即pg_terminate_backend(pid),查代码事务漏提交
fastpath function call执行内置函数(如now()✅ 安全瞬时状态
disabled后端进程被禁用⚠️ 中检查pg_cancel_backend()调用痕迹

自动化巡检脚本(放入crontab每5分钟执行):

# 查找空闲事务超30分钟的连接 psql -U postgres -c " SELECT pid, usename, application_name, now() - backend_start as duration, state, query FROM pg_stat_activity WHERE state = 'idle in transaction' AND (now() - backend_start) > interval '30 minutes'; " | grep -q "pid" && echo "ALERT: idle in transaction >30min!" | mail -s "PG Alert" admin@company.com

3. 面试题6-10:SQL优化与执行计划——别让EXPLAIN变成摆设

3.1 “如何读懂EXPLAIN ANALYZE输出?”——从‘Seq Scan’到‘Index Only Scan’的进化

某用户中心服务查询SELECT name, email FROM users WHERE status='active' AND last_login > '2024-01-01',执行时间12秒。EXPLAIN ANALYZE显示:

Seq Scan on users (cost=0.00..123456.78 rows=89012 width=64) (actual time=0.020..11234.567 rows=78901 loops=1) Filter: ((status = 'active'::text) AND (last_login > '2024-01-01'::date)) Rows Removed by Filter: 2109876

逐行破译

  • cost=0.00..123456.78:预估启动成本0,总成本123456.78(单位:磁盘页读取);
  • rows=89012:预估返回89012行,但actual rows=78901接近,说明统计信息准确;
  • Rows Removed by Filter=2109876:扫描218万行,仅保留7.8万行 →全表扫描+过滤效率极低

优化路径

  1. 创建复合索引CREATE INDEX idx_users_status_login ON users(status, last_login);
    • 为什么是(status, last_login)?因为status是等值查询(高选择性),last_login是范围查询,复合索引中等值字段必须在前。
  2. 验证执行计划
    Index Scan using idx_users_status_login on users (cost=0.56..12345.67 rows=78901 width=64) (actual time=0.032..123.456 rows=78901 loops=1) Index Cond: ((status = 'active'::text) AND (last_login > '2024-01-01'::date))
    成本从12万降至1.2万,时间从12秒降至0.12秒。

经验:当Seq ScanRows Removed by Filter占比超70%,必建索引。用pg_stat_all_indexes.idx_scan监控索引使用率,长期为0的索引及时删除。

3.2 “LIMIT为什么有时不加速查询?”——索引失效的经典场景

某推荐系统执行SELECT * FROM products ORDER BY score DESC LIMIT 10,表有5000万行,响应时间8秒。EXPLAIN显示:

Gather Merge (cost=1000000000.00..1000000000.25 rows=10 width=128) -> Sort (cost=1000000000.00..1000000000.25 rows=10 width=128) Sort Key: score DESC -> Seq Scan on products (cost=0.00..1234567.89 rows=50000000 width=128)

根因ORDER BY ... LIMIT需要全局排序,而score无索引,数据库必须扫描全表排序后取前10。LIMIT在此处毫无意义。

解决方案

  • ✅ 创建索引:CREATE INDEX idx_products_score ON products(score DESC);
  • ✅ 强制索引扫描(若优化器未自动选择):SELECT * FROM products ORDER BY score DESC LIMIT 10;→ 自动走索引
  • ❌ 错误做法:SELECT * FROM products WHERE score > 95 ORDER BY score DESC LIMIT 10(假设95是阈值),但业务无法预知分数分布。

进阶技巧:对score做分区(如按score/10取整),查询时WHERE score >= 90直接定位分区,再ORDER BY LIMIT,速度提升百倍。

3.3 “CTE(WITH子句)一定比子查询快吗?”——执行计划的欺骗性

某报表需求:统计每个部门的平均薪资及高于平均的员工数。

-- 方案A:CTE WITH dept_avg AS ( SELECT dept_id, AVG(salary) as avg_sal FROM employees GROUP BY dept_id ) SELECT d.dept_name, da.avg_sal, COUNT(e.id) FROM departments d JOIN dept_avg da ON d.id = da.dept_id JOIN employees e ON e.dept_id = d.id AND e.salary > da.avg_sal GROUP BY d.dept_name, da.avg_sal; -- 方案B:子查询 SELECT d.dept_name, (SELECT AVG(salary) FROM employees e2 WHERE e2.dept_id = d.id) as avg_sal, COUNT(e.id) FROM departments d JOIN employees e ON e.dept_id = d.id WHERE e.salary > (SELECT AVG(salary) FROM employees e2 WHERE e2.dept_id = d.id) GROUP BY d.dept_name;

真相:PostgreSQL 12+中,CTE默认是优化器屏障(optimization fence),即dept_avg会被物化(Materialize)成临时结果集,即使departments只有100行,也要先算出所有部门的平均薪资,再关联。而子查询可能被内联(Inline)优化,生成更优计划。

验证方法

-- 查看CTE是否被物化 EXPLAIN (VERBOSE, ANALYZE) <CTE查询>; -- 若输出含"CTE Scan on dept_avg",则已物化

正确姿势

  • 当CTE结果集小且复用多次 → 用CTE;
  • 当CTE逻辑简单(如单表聚合)→ 改用子查询或LATERAL JOIN;
  • PostgreSQL 12+可用MATERIALIZED/NOT MATERIALIZED强制控制:
    WITH dept_avg AS NOT MATERIALIZED ( SELECT dept_id, AVG(salary) FROM employees GROUP BY dept_id )

3.4 “pg_stat_statements为什么默认关闭?”——性能监控的双刃剑

某客户启用pg_stat_statements后,数据库CPU飙升40%。pg_stat_statements扩展通过hook捕获每条SQL的执行统计,对高频短查询(如SELECT 1心跳)产生显著开销。

参数调优黄金法则

参数默认值生产建议原因
pg_stat_statements.tracktopall跟踪所有SQL(含嵌套)
pg_stat_statements.max500010000避免哈希表溢出
pg_stat_statements.saveonoff重启后不清空统计(需手动pg_stat_statements_reset()

安全启用步骤

  1. postgresql.conf添加:
    shared_preload_libraries = 'pg_stat_statements' pg_stat_statements.track = 'all' pg_stat_statements.max = 10000
  2. 重启数据库;
  3. 创建扩展:CREATE EXTENSION pg_stat_statements;
  4. 首次监控SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;

提示:pg_stat_statements不记录参数值(如WHERE id=?),但会记录SQL模板。敏感字段需配合log_parameter = off(默认)。

3.5 “SELECT COUNT(*)为什么慢?如何优化?”——全表扫描的终极克星

某日志表logs有20亿行,SELECT COUNT(*) FROM logs执行18分钟。EXPLAIN显示Seq Scan,无索引可用。

根本原因COUNT(*)需确认每行是否可见(MVCC可见性判断),必须扫描所有数据页。

优化方案对比

方案原理适用场景缺陷
reltuples估算查询pg_class.reltuples(统计信息)允许误差的场景(如监控大盘)误差可达20%,VACUUM后才更新
物化视图CREATE MATERIALIZED VIEW log_count AS SELECT COUNT(*) FROM logs数据更新不频繁需手动刷新,实时性差
外部计数器应用层维护Redis计数器,INSERT/DELETE时增减高并发写入需保证原子性(Lua脚本)
分区表+汇总表按月分区,每日INSERT INTO daily_count SELECT '2024-01', COUNT(*) FROM logs_202401超大表且按时间查询架构复杂

我们采用的方案

  • logs表按date_trunc('day', created_at)分区;
  • 创建汇总表daily_log_count(date DATE PRIMARY KEY, cnt BIGINT)
  • 每日凌晨执行:
    INSERT INTO daily_log_count SELECT current_date - 1, COUNT(*) FROM logs WHERE created_at::date = current_date - 1 ON CONFLICT (date) DO UPDATE SET cnt = EXCLUDED.cnt;
    查询当日总数:SELECT SUM(cnt) FROM daily_log_count WHERE date <= current_date;—— 从18分钟降至20毫秒。

4. 面试题11-15:高可用与复制——别把主从当成备份

4.1 “流复制(Streaming Replication)和逻辑复制(Logical Replication)的区别?”——选错等于埋雷

某SaaS平台升级PostgreSQL 13时,用逻辑复制迁移租户库,结果DROP TABLE操作在从库执行失败,因从库存在外键依赖。而流复制直接二进制同步,无此问题。

核心差异矩阵

维度流复制逻辑复制
复制粒度WAL日志(物理块)解析后的SQL语句(逻辑变更)
目标库要求同版本、同编译选项可跨版本(如12→15)、异构数据库(如PG→ES)
DDL支持全量支持(包括DROP仅支持部分DDL(CREATE TABLE可,DROP需手动处理)
延迟毫秒级(网络决定)秒级(解析+应用开销)
典型场景高可用主从、灾备数据订阅、异构同步、零停机升级

生产决策树

  • 需要RPO≈0的故障切换?→流复制(配合Patroni或repmgr);
  • 需将订单库同步到Elasticsearch?→逻辑复制CREATE PUBLICATION pub_orders FOR TABLE orders);
  • 升级大版本且不能停机?→逻辑复制(先建新库,逻辑同步,切流)。

4.2 “pg_basebackuppg_dump的区别?何时用哪个?”——备份策略的生死线

某金融客户用pg_dump -Fc备份1TB库,耗时4小时,恢复时发现pg_restore需11小时,RTO严重超标。

本质区别

工具类型输出恢复方式RTO
pg_basebackup物理备份数据目录完整拷贝(含WAL)cp回原目录+启动分钟级(仅复制时间)
pg_dump逻辑备份SQL或自定义格式(-Fcpg_restore重建对象小时级(需重放SQL)

选型指南

  • pg_basebackup:主从搭建、全库灾难恢复、RTO<30分钟场景;
  • pg_dump:单表恢复、跨版本迁移、需过滤数据(-t table_name)、审计合规(导出SQL可审查);
  • ⚠️ 混合策略:日常用pg_basebackup(每天1次),配合pg_wal归档(连续WAL)实现PITR(时间点恢复)。

pg_basebackup最佳实践

# 压缩备份(节省空间,略微增加CPU) pg_basebackup -h primary_host -D /backup/base_$(date +%Y%m%d) \ -Ft -z -Z9 -P -R -Xs -l "backup_$(date +%Y%m%d)" # `-R` 自动生成standby.signal,`-Xs` 同时备份WAL,`-Z9` 最高压缩

4.3 “Patroni和repmgr哪个更适合生产?”——集群管理的隐性成本

某客户用repmgr管理3节点集群,某次主库宕机后,从库升主耗时92秒,期间应用报connection refused。而Patroni集群平均故障转移时间12秒。

关键差异

功能Patronirepmgr
故障检测多节点共识(etcd/zk)+ 心跳主从间TCP探测
脑裂防护依赖分布式KV强一致性依赖repmgr守护进程,易脑裂
配置管理集中式配置(patroni.yml分散式(每节点repmgr.conf
学习曲线陡峭(需懂etcd/zk)平缓(纯SQL命令)

我们的选型结论

  • 中小规模(≤5节点)、运维人力有限 →repmgrrepmgr standby switchover一条命令);
  • 大规模(≥10节点)、金融级高可用 →Patroni(自动处理网络分区、支持自定义故障脚本);
  • 绝对禁忌:用pg_ctl promote手动升主——这是所有集群故障的起点。

4.4 “synchronous_commit=on为什么导致写入变慢?”——一致性与性能的博弈

某IoT平台每秒写入10万设备上报,开启同步提交后,INSERT平均延迟从8ms升至42ms,吞吐跌至3万/秒。

原理深挖
synchronous_commit=on要求主库WAL写入并刷盘(fsync)+ 从库WAL接收并刷盘后,才向客户端返回成功。网络延迟(RTT)和从库IO成为瓶颈。

折中方案

参数行为RPO写入延迟
on主库fsync + 从库fsync0最高
remote_write主库fsync + 从库WAL接收(不刷盘)从库断电丢数据中等
off仅主库fsync主库崩溃丢数据最低

生产推荐

  • 金融交易:synchronous_commit=on(钱不能丢);
  • IoT上报:synchronous_commit=remote_write(容忍从库断电,但不丢主库数据);
  • 日志采集:synchronous_commit=off(可丢最后几秒,换吞吐)。

注意:synchronous_standby_names必须配置(如'node2'),否则remote_write退化为off

4.5 “pg_rewind是什么?为什么比pg_basebackup快?”——主从倒换的核武器

某次主库误操作DROP DATABASE production,紧急将从库升主后,原主库需重建。pg_basebackup需3小时,而pg_rewind仅12分钟。

工作原理
pg_rewind不复制整个数据目录,而是:

  1. 读取原主库pg_control中的最新检查点(checkpoint)LSN;
  2. 从从库WAL中找出该LSN之后的所有变更;
  3. 将这些变更反向应用到原主库(如撤销DROP操作);
  4. 重置原主库为从库,开始流复制。

前提条件

  • 从库必须开启wal_log_hints=on(9.6+默认开启);
  • max_replication_slots≥ 1(预留复制槽);
  • 原主库崩溃前,从库WAL未被回收(wal_keep_size足够大)。

执行流程

# 在原主库停机后执行 pg_rewind --source-server="host=standby_host port=5432 dbname=postgres" \ --target-pgdata=/var/lib/postgresql/data \ --progress # 修改recovery.conf(12+为standby.signal),启动

5. 面试题16-20:生态与前沿——别让技术视野困在SQL里

5.1 “pgvector如何实现向量相似搜索?”——AI时代的数据库新战场

某推荐系统需根据用户画像向量(128维)查找相似用户,传统COSINE函数计算耗时2秒/次。接入pgvector后降至35毫秒。

技术栈拆解

  1. 向量存储CREATE TABLE users (id SERIAL, embedding vector(128));
  2. 索引加速CREATE INDEX ON users USING ivfflat (embedding vector_cosine_ops) WITH (lists=100);
    • ivfflat算法将向量聚类(100个簇),查询时只搜索最近的几个簇;
  3. 相似搜索
    SELECT id, 1 - (embedding <=> '[0.1,0.2,...]') AS similarity FROM users ORDER BY embedding <=> '[0.1,0.2,...]' LIMIT 10;
    <=>是余弦距离操作符,1-距离即相似度。

性能对比(100万向量):

方式QPSP99延迟精确度
纯SQL(COSINE函数)52100ms100%
pgvector+ivfflat28035ms98.2%(可调probes参数)

提示:pgvector0.5+支持HNSW索引(更高精度),但内存占用翻倍。生产环境建议ivfflat起步。

5.2 “TimescaleDB和原生PostgreSQL分区表的区别?”——时序数据的终极选择

某车联网平台存储车辆GPS点位,每秒10万点,原生分区表按time月分区,但INSERT吞吐仅8万/秒,且SELECT跨月查询慢。

核心差异

特性TimescaleDB原生分区表
分区管理自动按时间/空间分片(chunk),透明路由手动CREATE TABLE ... PARTITION BY RANGE
写入优化数据先写入内存缓冲(hypertable),批量落盘直接写入目标分区
查询优化自动裁剪无关chunk,支持连续聚合(continuous aggregate)需手动UNION ALLPARTITION约束推导
压缩对冷chunk自动压缩(列式),空间节省80%无压缩能力

我们的迁移效果

  • 写入吞吐:8万/秒 →14万/秒(提升75%);
  • 存储空间:2.1TB →420GB(压缩率80%);
  • 跨月查询:SELECT * FROM gps WHERE time > '2024-01-01'从12秒 →0.8秒

5.3 “Citus如何实现分布式查询?”——打破单机天花板

某广告平台用户表达50亿行,单机JOIN超时。Citus将表分片(shard)到16个节点,SELECT COUNT(*) FROM users u JOIN ads a ON u.id=a.user_id在2秒内返回。

分片原理

  • 分片键(distribution column):如users.id,数据按哈希分布到各节点;
  • 查询路由:Coordinator节点解析SQL,将JOIN拆分为:
    1. 各Worker节点并行执行SELECT id FROM users WHERE id IN (...)
    2. Coordinator收集结果,广播到Worker执行JOIN ads
    3. 汇总最终结果。

关键限制

  • JOIN必须包含分片键(如ON u.id=a.user_id),否则需广播小表;
  • GROUP BY需在分片键上,否则Coordinator需合并所有节点结果。

5.4 “pg_partman和原生PARTITION BY的区别?”——自动化分区的工业级方案

某日志系统需按天分区,手动CREATE TABLE logs_20240101 PARTITION OF logs FOR VALUES FROM ('2024-01-01') TO ('2024-01-02'),运维同事每月初加班维护。

pg_partman优势

  • 自动创建SELECT partman.create_parent('public.logs', 'created_at', 'native', 'daily');
  • 自动清理SELECT partman.run_maintenance();删除30天前的分区;
  • 后台作业:通过pg_cron定时执行维护,无需人工干预。

生产配置

-- 创建父表 CREATE TABLE logs ( id SERIAL, created_at TIMESTAMPTZ DEFAULT NOW(), content TEXT ) PARTITION BY RANGE (created_at); -- 启用partman SELECT partman.create_parent('public.logs', 'created_at', 'native', 'daily'); -- 设置保留策略 UPDATE partman.part_config SET retention = '30 days', retention_keep_table = false WHERE parent_table = 'public.logs';

5.5 “PostgreSQL 15的MERGE语句解决了什么痛点?”——告别UPSERT的混乱

某电商库存服务需INSERT OR UPDATE,旧方案用INSERT ... ON CONFLICT DO UPDATE,但`ON

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 12:25:46

斯坦福AI Index报告深度解读:推理成本骤降280倍,AI应用范式重构

简介&#xff1a;《人工智能指数报告2025》是斯坦福大学人类中心人工智能研究所发布的第八版年度权威报告&#xff0c;旨在为政策制定者、研究人员、企业高管和公众提供关于AI发展态势的严谨数据与深度洞察&#xff0c;被全球主流媒体广泛引用。该报告以单个PDF文件呈现&#x…

作者头像 李华
网站建设 2026/9/17 12:25:45

Scratch游戏引擎框架实战:帧循环、AABB碰撞、对象池与摄像机

1. 为什么要给Scratch装上"游戏引擎"的骨架三个多月前&#xff0c;我在一个少儿编程社群里看到有人问&#xff1a;Scratch能不能做出《空洞骑士》那样的横版动作游戏&#xff1f;底下的回答清一色是"能做个雏形&#xff0c;但手感很差"。这个回答本身没错&…

作者头像 李华
网站建设 2026/9/17 12:24:29

从零搭建YuE家庭媒体中心:NAS影视库与多端访问实践

“YuE”这个词第一次出现在我手机备忘录里的时候&#xff0c;其实就俩字母——Y和E。当时我正坐在客厅沙发上&#xff0c;电视遥控器在茶几上排成一排&#xff0c;手机里装了四五个视频App&#xff0c;想找一部电影却翻来覆去搜不到&#xff1b;NAS硬盘灯在角落一闪一闪&#x…

作者头像 李华
网站建设 2026/9/17 12:23:53

石化行业人工智能巡检实战:OpenCV+YOLO目标检测与误报治理

简介&#xff1a;石化行业人工智能巡检解决方案PPT围绕石化企业安全巡检痛点&#xff0c;面向安全管理人员、生产运维主管及AI解决方案工程师。内容先梳理人工巡检面临的人身安全风险、效率瓶颈、判断标准差异与数据散乱难题&#xff0c;也指出监控系统事后追溯和主控与现场科技…

作者头像 李华
网站建设 2026/9/17 12:23:11

STM32CubeMX与Keil µVision:工程生成、下载调试全流程

手头有一块 STM32F103C8T6 的最小系统板&#xff0c;装完 STM32CubeMX&#xff0c;配好 Keil Vision&#xff0c;绝大多数人的第一件事都不是写业务逻辑&#xff0c;而是想办法让板子上的灯先闪起来。可就是这么一件"点灯"级别的事&#xff0c;第一次走这条路的人经常…

作者头像 李华