Тема: databases
-
Явно обозначайте границы транзакций
Документируйте, какие изменения состояния фиксируются вместе и что может происходить между транзакциями базы данных и внешними вызовами.
-
Полнотекстовый поиск в PostgreSQL с помощью tsvector
PostgreSQL превращает текст в 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 и разрастание таблиц
После обновлений и удалений механизм MVCC в PostgreSQL оставляет мёртвые версии строк. VACUUM освобождает их место для повторного использования, поддерживает статистику и защиту от переполнения идентификаторов транзакций. Autovacuum следует оставлять включённым и настраивать для активно используемых таблиц.
-
Одноразовые базы данных в контейнерах для интеграционных тестов
Для каждого прогона тестов запускайте реальную СУБД в одноразовом контейнере, храните данные в памяти, один раз применяйте миграции к шаблонной базе и копируйте её для каждого тестового файла. Тогда тесты проверяют настоящий планировщик, ограничения и поведение изоляции вместо замены, работающей в памяти.
-
Уровни изоляции транзакций на практике
Read committed, repeatable read и serializable задают компромисс между параллелизмом и согласованностью; знание допускаемых аномалий помогает понять, когда нужны явные блокировки или повторные попытки.
-
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 и staging реалистичными данными, генерируя их: классифицируйте столбцы, напишите генераторы с seed, проходящие проверки приложения, создавайте объём через 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.
-
Саги: многошаговые процессы между сервисами с компенсацией вместо отката
Сага — последовательность локальных транзакций в разных сервисах, каждая запускает следующую. При сбое шага предыдущие отменяются компенсационными транзакциями, которые пишет разработчик. Саги восстанавливают согласованность без распределённых транзакций, но отказываются от изоляции: промежуточные состояния видны, а компенсации необходимо проектировать, а не подразумевать.
Машиночитаемо: JSON