主题: databases
-
明确标示事务边界
记录哪些状态变更会一并提交,以及数据库事务与外部调用之间可能发生什么。
-
在 PostgreSQL 中使用 tsvector 实现全文搜索
PostgreSQL 会借助语言配置,把文本转换成由归一化词位(lexeme)组成的 tsvector,再用 tsquery 进行匹配、用 ts_rank 评分排序,并通过 GIN 索引加速;它开箱即用地处理词干提取和停用词,但不处理拼写错误或同义词。
-
Event sourcing and CQRS: what they buy and what they cost
Event sourcing stores every state change as an immutable event and derives current state by replay; CQRS separates the write model from read models. Both add auditability and flexibility at the price of complexity and eventual consistency.
-
Managing PostgreSQL extensions: installing, versioning, updating and dumping them
An extension packages SQL objects and often a shared library under one name with a control file and versioned scripts; CREATE EXTENSION installs it per database, ALTER EXTENSION UPDATE applies the author's update scripts, and pg_dump emits only the CREATE EXTENSION line. Keep the installed files, the catalog version and the loaded library in step, especially across package upgrades and pg_upgrade.
-
本地数据库的种子数据与固定数据集:小规模、幂等,并与模式一同版本化
区分所有环境都需要的参考数据、开发和演示用的示例数据,以及由测试创建的测试数据。将种子脚本写成基于自然键执行 upsert 的幂等代码,保持示例集小而有名,在安装脚本和 CI 中都于迁移后运行,绝不直接用未经处理的生产数据填充开发机。
-
在 PostgreSQL 中设计仅追加的时间序列表
将测量值存入按时间范围分区的表,使用 timestamptz、由序列与时间组成的复合键,以及匹配查询方式的索引:单序列查询使用 B-tree,全表时间扫描使用 BRIN。保留期通过分离并删除分区实现,而不是 DELETE。这些选择源于数据按时间顺序到达,并按完整时间片移除。
-
在 PostgreSQL 中存储派生数据:生成列与物化视图
生成列仅根据本行数据为每行派生一个值,可采用虚拟形式(读取时计算)或存储形式(写入时计算),且只能使用不可变表达式;物化视图存储任意查询的结果,其新鲜度仅截至上次 REFRESH。需要索引的逐行规范化适合存储生成列,允许滞后的昂贵聚合适合物化视图,两者都不合适时则维护汇总表。
-
VACUUM、autovacuum 与表膨胀
PostgreSQL 的 MVCC 在更新和删除后会留下失效的行版本;VACUUM 回收这些版本,维护统计信息,并防止事务 ID 回卷。应保持 autovacuum 启用,并针对繁忙表进行调优。
-
使用容器中的临时数据库进行集成测试
每次测试运行都在一次性容器中启动真实数据库引擎,将数据保存在内存中,只对模板数据库执行一次迁移,再为每个测试文件复制模板。这样测试检查的就是真实的规划器、约束和隔离行为,而不是内存替代品。
-
事务隔离级别的实际应用
读已提交、可重复读和可串行化在并发性与一致性之间作出权衡;了解各级别允许哪些异常,才能决定何时需要显式加锁或重试。
-
Datenbankänderungen ohne Ausfall: Expand und Contract
Ein Schema in drei einzeln auslieferbaren Schritten ändern: erweitern (neue Spalte oder Tabelle anlegen, alte behalten), migrieren (doppelt schreiben und in Häppchen nachfüllen), zusammenziehen (Altes entfernen, sobald aller Code das Neue nutzt); lange Sperren vermeiden, indem keine Tabelle in einem Statement umgeschrieben wird und lock_timeout jede Wartezeit begrenzt.
-
不使用生产环境个人数据的测试数据
通过生成数据,为开发、CI 和预发布环境提供真实感:分类各列,编写带固定种子且能通过应用校验的生成器,用 generate_series 生成足够的数据量,只从生产环境复制分布信息,为生成记录加上可识别标记,并移除直接导出生产数据库的捷径。
-
NULL in SQL: three-valued logic and its traps
NULL means unknown, so comparisons with NULL yield unknown rather than true or false; WHERE filters drop unknown rows, NOT IN with a NULL matches nothing, and aggregates skip NULLs. Use IS NULL, IS DISTINCT FROM and COALESCE deliberately.
-
Read-only maintenance mode: serving reads while writes are paused
For storage moves, failovers and long migrations, a service can keep serving reads and refuse writes with a clear message instead of going dark; PostgreSQL's default_transaction_read_only makes new transactions read-only at the database as a backstop, and HTTP 503 with Retry-After tells clients when to try again. The mode needs one switch, a user-facing message and a rehearsal.
-
使用 WITH 编写公共表表达式与递归查询
WITH 为子查询命名,供语句的其余部分引用。WITH RECURSIVE 先计算非递归项,再重复计算递归项,直到不再产生新行,从而用一次查询遍历任意深度的树和图。只引用一次且无副作用的 CTE 会折叠进外层查询,除非指定 MATERIALIZED;SEARCH 和 CYCLE 子句负责排序与循环处理。
-
JSONB columns: what they are good for and when a column is better
jsonb stores parsed JSON in a binary form that can be indexed with GIN and queried with containment and path operators; it suits sparse, externally defined or genuinely variable attributes. Data with a fixed shape, data that needs constraints, foreign keys or per-field updates, and large frequently changed documents belong in ordinary columns.
-
Preventing SQL injection with parameterised queries
Never build SQL by concatenating untrusted strings; pass values as parameters so the driver sends them separately from the statement, and allow-list any identifiers that must be dynamic.
-
数据库连接池及其限制
每个 PostgreSQL 连接都是一个消耗内存的进程。应用应根据实际并发量保持较小的连接池,设置获取连接的超时,并禁止请求处理程序临时自行打开连接。
-
Measured PostgreSQL SKIP LOCKED claims with four concurrent queue consumers
Four concurrent transactions each claimed 25 synthetic jobs in PostgreSQL 16.15. The returned 100 IDs were unique and no jobs remained unclaimed; this verifies one bounded claim phase, not exactly-once processing or broker replacement.
-
Saga:跨服务的多步骤工作流,以补偿代替回滚
Saga 是不同服务中一系列本地事务,每个事务触发下一个;若某步失败,开发者编写的补偿事务会撤销此前步骤。Saga 无需分布式事务即可恢复一致性,但放弃隔离性,因此中间状态可见,补偿必须明确设计,不能想当然。
机器可读: JSON