#Database

38 posts

PostgreSQL Basics #5 Reading EXPLAIN: Diagnosing Queries with Execution Plans
4 min read

PostgreSQL Basics #5 Reading EXPLAIN: Diagnosing Queries with Execution Plans

How to confirm why a query is slow with the execution plan instead of guesswork. The difference between EXPLAIN and EXPLAIN ANALYZE (the latter actually executes), reading the plan tree from the innermost node outward, what Seq Scan, Index Scan, Index Only Scan, and Bitmap Scan mean, comparing cost and actual time and estimated vs actual rows, the remedy when estimates are badly off (ANALYZE), and the habit of checking read volume with BUFFERS.

SQLAlchemy 2.0 #4 The Session: Change Tracking, flush vs commit, and the Four Object States
5 min read

SQLAlchemy 2.0 #4 The Session: Change Tracking, flush vs commit, and the Four Object States

The heart of the ORM, the Session: how it batches changes as a unit of work and emits them as SQL, the difference between flush and commit, the four object states — transient, pending, persistent, detached — the identity map that returns the same object for the same row, why attribute access after commit triggers a new query, and the one-session-per-request scoping rule for web applications.

PostgreSQL Basics #4 Index Fundamentals: When Indexes Get Used and When They Don't
4 min read

PostgreSQL Basics #4 Index Fundamentals: When Indexes Get Used and When They Don't

Indexes are a reliable way to make reads fast, and this chapter grounds them in PostgreSQL specifics. How a B-tree index changes lookups, the classic reasons an index you created is not being used (leading-column mismatch, functions applied to the column, type mismatch, low selectivity), the cost in write performance and storage, and the working order of "build from the WHERE, JOIN, and ORDER BY of actually slow queries."

SQLAlchemy 2.0 #3 Defining ORM Models: DeclarativeBase, Mapped, mapped_column
4 min read

SQLAlchemy 2.0 #3 Defining ORM Models: DeclarativeBase, Mapped, mapped_column

The 2.0-style way of declaring tables as Python classes: the DeclarativeBase inheritance structure, how Mapped type hints and mapped_column divide the work, the rules mapping Python types to database types, how Optional drives nullable, declaring defaults, unique constraints, and indexes, and the naming convention that gives constraints predictable names from day one.

PostgreSQL Basics #3 Joins and Aggregation: Working Instincts for Read Queries
4 min read

PostgreSQL Basics #3 Joins and Aggregation: Working Instincts for Read Queries

Joins and aggregation make up most of real-world read queries, and this chapter builds the instincts. Choosing between INNER and LEFT JOIN and the classic mistake of filtering LEFT JOIN results in WHERE (turning them back into INNER), the division of labor between GROUP BY and HAVING, the double-counting trap when joins meet aggregation, the fork between subqueries and joins, and the PostgreSQL-native way to get the latest row per group (DISTINCT ON).

SQLAlchemy 2.0 #2 Engines and Transactions: Connection Pools and the Two Commit Patterns
5 min read

SQLAlchemy 2.0 #2 Engines and Transactions: Connection Pools and the Two Commit Patterns

The foundation of SQLAlchemy: engines and transactions. Why connection pools exist and how they behave, what pool_size and max_overflow actually limit, the commit-as-you-go and begin-once patterns split between connect() and begin(), why transactions never auto-commit, defining tables with MetaData and Table, and running CRUD with Core expressions.

PostgreSQL Basics #2 Data Types and Table Design: What to Store Things As
5 min read

PostgreSQL Basics #2 Data Types and Table Design: What to Store Things As

Half of PostgreSQL design is choosing data types. Why text alone is enough for strings, why numeric is mandatory for money, timestamptz as the standard for points in time and the timestamp trap, primary key strategy (bigint IDENTITY vs UUID, and uuidv7), enforcing data integrity at the database layer with NOT NULL, CHECK, and foreign keys, and where enums and arrays belong.

SQLAlchemy 2.0 #1 The Big Picture: Core, ORM, and the 2.0 Style
5 min read

SQLAlchemy 2.0 #1 The Big Picture: Core, ORM, and the 2.0 Style

First post in a series covering SQLAlchemy, the de facto standard database library for Python, from the ground up: the two-layer structure of Core and ORM, why 1.x-era code and 2.0-style code look different, the unified select()-centric query style and type hint support, installation and the first connection, and running raw SQL with text().

PostgreSQL Basics #1 What PostgreSQL Is: Why It Became the Default, Installation and First psql Session
4 min read

PostgreSQL Basics #1 What PostgreSQL Is: Why It Became the Default, Installation and First psql Session

Starting from why PostgreSQL became the default database for new projects: standards compliance, a rich set of data types, the extension ecosystem (pgvector, PostGIS), and a permissive license. Then the fastest local setup with Docker, connecting with psql and the essential meta-commands (\l, \dt, \d), a first cycle of creating a table, inserting, and querying, and a map of the whole course.

Why Redis Is Fast — Memory, a Single Thread, and Data Structures
4 min read

Why Redis Is Fast — Memory, a Single Thread, and Data Structures

The structural reasons Redis handles hundreds of thousands of requests per second: memory access with no disk in the path, a lock-free single-threaded event loop, and purpose-built data structures — plus the single-thread trap (one slow command stalls everything) and the cases where Redis gets slow.

What a Database Index Actually Does — B-trees, Lookup Cost, and the Price of Writes
4 min read

What a Database Index Actually Does — B-trees, Lookup Cost, and the Price of Writes

How indexes make lookups fast, from the B-tree up: the cost gap versus full scans, composite indexes and column order, why indexes are not free (write cost, storage), and the working rules for what to index and what to leave alone.

Why Your Server Is Slow #5: When the Database Slows Down — Indexes, Locks, Connection Pools
6 min read

Why Your Server Is Slow #5: When the Database Slows Down — Indexes, Locks, Connection Pools

Tracking down why a database that ran fine is getting slower. Covers full scans collapsing the day data growth crosses a threshold, indexes that exist but never get used, lock wait chains rooted in long transactions, telling pool exhaustion from database saturation, and a diagnostic order built on EXPLAIN and the statistics views.