Leanpub Header

Skip to main content

Topics

Databases and SQL

From Codd's relational model to B+trees, PostgreSQL internals, NoSQL and vector stores, the subject as told through the free samples of the Leanpub books about databases and SQL.

Created from the free samples of 19 Leanpub books and the descriptions and tables of contents of 22 more, with every source cited.

Databases are organised collections of data together with the software that stores, retrieves and protects them. For most of computing's history that software has meant a relational database management system: data in tables, a declarative query language, SQL, and transactions that make a group of changes succeed or fail as one. MySQL, PostgreSQL, SQLite, Oracle and SQL Server are the systems most programs talk to, and SQL, first implemented in the 1970s, remains the most widely used language for asking a computer for data.

The field today is wider than the relational model. Key-value stores, document databases, column-family systems such as Cassandra, graph databases, in-memory data grids, embedded analytical engines such as DuckDB and, since the arrival of large language models, vector databases all answer needs the classical systems were not built for, while PostgreSQL in particular has absorbed many of them. Under all of them lie the same few problems: durability, indexing, query planning and concurrent access.

This article covers the relational model and SQL, how a database engine works inside, running a database in production, the systems beyond the relational model, data engineering, and the uses databases have found in AI. Its sources are the free samples of the Leanpub books listed at the end: where a sample states something, the sentence cites it; the rest is general knowledge of the field.

Where to start

The sources divide by what the reader wants from a database: to use one, to run one or to build one. A reader with no background can begin with MySQL Explained (2016), written for people outside IT, which starts from what a database is before installing MySQL, designing a model, normalising it and writing SQL,[14] or with Getting Started with Data (2020), an onboarding text for business readers with one chapter on how data is stored.[29] For practising SQL, Top 30 SQL Interview Coding Tasks (2018) sets thirty tasks against one small e-commerce schema,[12] and SQL Problem Solving sets eighty-four problems in seven volumes, each with sample data, expected output and a solution, from a first SELECT to window functions and recursive queries.[13]

A working developer who wants to know what the database does with their statements can go to High-Performance Java Persistence, which measures JDBC, Hibernate and jOOQ against four database systems,[15] to Deep dive into a SQL query, which follows one query through PostgreSQL 18 stage by stage,[7] or to Northwind Elixir Traders, which rebuilds the Northwind schema in Ecto and SQLite over seventeen chapters.[23] Someone who runs PostgreSQL has Lift the Elephant, a scaling playbook by the CTO of Hubstaff,[10] and, arriving from MySQL, Thinking in PostgreSQL.[11]

The reader who learns by building has an unusual choice. Build Your Own Database in Go From Scratch codes a crash-safe key-value store on a B+tree and a relational layer above it in about 3,000 lines of Go,[1] Build a SQL Database Engine in C++ does the same in C++20 over fourteen units with a benchmark for every design claim,[2] Build a Database Server lets the reader pick any language and drives the build with a test suite of more than two hundred cases,[3] and How Query Engines Work builds the query side alone, in Kotlin, from Apache Arrow to distributed execution.[6]

History

Early computers did arithmetic. As applications grew they had to store data, first on tape, where sequential access made retrieving one record impossible, then on disks, where random access made online transaction processing possible, and every application wrote its own storage code until database management systems took the job over.[16] One source divides what followed into three eras: the navigational databases of the 1960s and early 1970s, which found data by following pointers on mainframes; the relational era; and the post-relational era driven by big data.[16]

The relational era began with E. F. Codd's 1970 paper "A Relational Model of Data for Large Shared Data Banks", which argued that the navigational systems were too hard to use and lacked a theoretical foundation, and proposed finding data by its content rather than by following links, with the model concerned with how data is presented to users rather than its layout on disk.[16] Codd said nothing about concurrent modification; Jim Gray's transaction concept supplied that in the late 1970s, and Andreas Reuter and Theo Härder later coined ACID for his properties.[16] IBM's System R, begun in 1974, was the first relational database and the first implementation of SQL; Sybase, SQL Server, Informix, MySQL and DB2 followed, all resting on the relational model, SQL and ACID transactions.[16] SQL became an international standard, ISO/IEC 9075, a history that Build a Database Server opens with.[3]

Relational databases were the default choice for application storage until the late 2000s.[16] What changed was scale. Google met its storage and processing needs with clusters of commodity servers and three pieces of infrastructure, the Google File System, MapReduce and Bigtable; Hadoop reimplemented them in the open; and the Bigtable and Dynamo papers from Google and Amazon inspired the NoSQL movement.[16] Before that, web companies had stretched MySQL with read replicas, Memcache and sharding, a shared-nothing approach whose complexity, one source argues, is what gave birth to NoSQL.[16] The years since have run in two directions at once: specialised systems for documents, graphs, analytics and vectors, and the classic engines, PostgreSQL above all, absorbing the same features.

The relational model and SQL

A relational database stores data in tables of rows and columns, relates tables by keys, and is queried in SQL, a declarative language in which the user says what result is wanted and the system decides how to compute it.

Designing a schema

Design comes before SQL. MySQL Explained spends as long on modelling and normalisation as on MySQL itself: a chapter on creating a model and defining tables, a chapter taking a design through first, second, third and Boyce-Codd normal forms, and two complete worked designs, a human resources and training database and a recipe database, each with review questions and exercises.[14] A beginner's .NET tutorial does the same at smaller scale, choosing SQL Server, drawing the schema on paper, creating a first database and adding test data before any C# is written.[35]

Two Elixir books treat modelling as their subject. Northwind Elixir Traders rebuilds the Northwind Traders database with Ecto migrations, changesets, constraints and associations, choosing SQLite over Ecto's default PostgreSQL on purpose so that SQLite's limits on constraints and foreign keys become the teaching material; a chapter on associations introduces the N+1 query problem and preloading, and later chapters add window functions and work around SQLite's missing INTERVAL.[23] Its sequel, Phoenix Product Codex, models suppliers, brands, categories, families, variants and bundles for a real industrial-equipment trader, with the business reasoning behind each decision, such as storing discounts as integers to avoid floating-point error; the author's earlier prototype, with no foreign keys or joins and integrity enforced in a script, is described as work best left to the database.[28] At the warehouse end, Design Driven Data Engineering puts conceptual, canonical, dimensional and event models before any platform choice.[31]

Writing queries

The SQL most people write is SELECT with WHERE, ORDER BY, GROUP BY and joins, and the two practice books teach it by example. Top 30 SQL Interview Coding Tasks runs thirty tasks against five tables, customers, products, suppliers, orders and order items, because a recruiter reuses one dataset across interviews; its sample covers retrieval, conditions, the IN operator with a list and with a subquery, INSERT, and UPDATE for all rows, one row and a subset.[12] SQL Problem Solving gives each problem a prompt, an input table, the expected output, a solution and a short explanation, and the explanations name real traps: NOT IN with a NULL in the list returns no rows, a LIKE pattern that starts with a wildcard cannot use an ordinary index, and LIMIT is spelt TOP in SQL Server and FETCH FIRST in Oracle.[13] Its expert volume treats pivoting as conditional aggregation, a SUM over a CASE per column, and ends on sargability, whether a predicate can use an index at all.[13]

A DuckDB book reaches the same material from the other side, teaching SELECT, WHERE, LIKE, IN, BETWEEN, joins, aggregation and query plans in its second chapter as the foundation for spatial analysis,[18] and the Ecto book arrives at window functions with partitions and frames by its fifteenth.[23]

Databases from application code

Application code reaches a relational database through a driver, and the driver's behaviour matters. High-Performance Java Persistence opens with JDBC batching and finds that the MySQL driver does not send batched statements in one request unless a connection property rewrites them, and that the Oracle driver ignores batching for anything but prepared statements; it recommends a modest batch size of ten to thirty and shows a bulk UPDATE running an order of magnitude faster than batched updates.[15] It also explains why sequences suit batch inserts better than identity columns: the key can be fetched before the insert, so nothing depends on the driver returning generated keys.[15]

Above the driver sits the object-relational mapper. The impedance mismatch between tables and object graphs is what Hibernate and JPA exist to bridge; the persistence context acts as a transactional write-behind cache that flushes entity state changes as SQL at the last moment, and the book's position is that the schema belongs to the database and must be migrated incrementally under version control.[15] The same layering appears elsewhere: Ecto in Elixir,[23] Sequel in Ruby, which Ruby on Roda pairs with the Roda routing framework for a JSON API,[36] Entity Framework and LINQ to Entities in .NET, one chapter of an interview compendium beside SQL Server and T-SQL,[41] and the Mongoose document mapper in Node.js.[26]

Inside a database engine

A database engine is a stack of layers: pages on disk, a tree to index them, a pool to cache them, a parser and planner to turn SQL into a plan, and an executor to run it. Several of the sources build such a stack from an empty directory.

Durability, pages and B-trees

The first problem is persistence. Build Your Own Database in Go From Scratch counts as a database only what persists to disk, handles data larger than memory and is built from scratch, which rules in MySQL, PostgreSQL and SQLite and rules out caches and spreadsheets.[1] Ordinary file writes give no durability guarantee, so making files durable means implementing half a database: the fsync system call confirms that written data has reached the medium, and a database answers its client only after it, while atomicity requires that a crash mid-write loses the latest data entirely or not at all.[1] Overwriting a file in place fails both tests, atomic rename fails on power loss unless the directory is also synced, and an append-only log with a checksum on each entry survives a torn write because the corrupt last entry can be detected and ignored on recovery.[1]

The second problem is indexing, and the disk decides it. Solid-state latency is three orders of magnitude above RAM, so only two structures work on disk: the B+tree and the log-structured merge tree.[1] A B+tree is a balanced n-ary tree, short so that a lookup costs few disk reads, with internal nodes holding only keys and nodes sized in pages because disk input and output happens in pages; an LSM-tree instead buffers updates in a small structure and merges them down through exponentially larger levels, trading write amplification against query cost.[1] For crash safety the book chooses a copy-on-write B+tree, in which an update copies the path from leaf to root and leaves the old tree intact, which also gives snapshot isolation and effortless recovery, and it explains the alternative that MySQL calls double-write: save full copies of the updated pages, sync them, then update in place, so that recovery can blindly reapply the copies.[1]

Build a SQL Database Engine in C++ starts in the same place with a different temperament. Its first unit builds a 4,096-byte page with a twenty-byte self-describing header; the slotted layout, in which a directory of four-byte slots grows from one end while variable-length records grow from the other, so a record's slot id survives the movement of its neighbours; erase, fragmentation and compaction; a pager that moves pages between memory and one file, with the torn write as the unit's reproduced bug; and a free list.[2] Every claim is measured: the safe memcpy accessors compile to the same instruction as an unsafe pointer cast, and a table of records per page shows a 25 per cent slot tax on sixteen-byte records and space lost to quantisation on kilobyte ones, the arithmetic that later decides B+tree height.[2] Thirteen further units add the B+tree, a buffer pool, records and a catalog, a parser, an executor, joins, aggregation, indexes and a planner, vectorised execution, a write-ahead log with a kill-9 recovery harness, and a capstone checked against PostgreSQL and timed against SQLite; concurrency, MVCC and a wire protocol are out of scope by design.[2]

The same storage questions recur in PostgreSQL's own terms: Database Engine Level Thinking covers heap pages, TOAST, the visibility and free-space maps, the buffer pool, WAL and full-page writes, then B-trees, HOT updates, index-only scans and hash indexes, written by a backend engineer alongside their own learning as a living draft,[8] and PostgreSQL Internals Mastery: A Comprehensive Guide gives two chapters to the 8 kB page, the ctid, fillfactor, and the buffer cache's clock-sweep eviction and checkpoints.[9] Code a database in 45 steps (Go) breaks the whole build, storage engine, LSM-tree indexes, SQL, transactions and ACID, into forty-five test-driven puzzles of under fifty lines each.[4]

From SQL text to a result

Deep dive into a SQL query follows one query through PostgreSQL 18. The postmaster accepts a connection, authenticates it and starts a dedicated backend process, one per connection, which isolates sessions but limits how far connections scale and makes pooling essential; background processes handle vacuuming, dirty pages and the write-ahead log.[7] The query then passes through the pipeline the book counts as six stages, connection included: the parser builds a parse tree without knowing whether the tables exist; the analyser resolves names, types and permissions; the rewriter expands views and adds row-level security as WHERE conditions; the planner weighs indexes, statistics and join orders to choose a plan; and the executor runs it in a pull-based model, each operator producing a row only when the one above asks.[7] Memory is managed in hierarchical contexts, so destroying a query's context frees everything under it even after an error, and a shared buffer pool caches pages for every process.[7]

The from-scratch books build the same pipeline. Build a Database Server has the reader write a recursive-descent parser, a type checker that finds errors before a statement runs, NULL semantics, query plans as iterators, joins, grouping and aggregates, comparing each piece with PostgreSQL, MySQL, SQLite and DuckDB.[3] How Query Engines Work, by a committer on Apache Arrow and DataFusion, keeps to the query side: a columnar type system on Arrow, logical and physical plans, a DataFrame API, SQL parsing with a Pratt parser, hash joins, subquery decorrelation, predicate push-down and cost-based optimisation, then parallel and distributed execution.[6] The Go book ends with a SQL-like language whose parser and interpreter are written with nothing but recursion.[1]

Transactions and concurrency

A transaction is a group of changes that takes effect entirely or not at all. The ACID properties describe what a database promises about it, and one source is careful about each: atomicity is about all-or-nothing state changes, not concurrency; consistency means conformance to the database's own rules; isolation is the most configurable and most relaxed of the four, with serialisable rarely the default because it is too slow for most applications; durability means that completed work is permanent.[16] The same source separates isolation levels, which apply to transactions, from the consistency models of distributed systems, which apply to single values.[16]

Most engines implement isolation with multi-version concurrency control, keeping old row versions so that readers never block writers. PostgreSQL's version is the subject of a chapter in PostgreSQL Internals Mastery: A Comprehensive Guide: transaction identifiers, the xmin and xmax fields on every tuple, the visibility algorithm, and the vacuum that reclaims old versions, after a chapter on isolation levels with a payment-system case study.[9] Thinking in PostgreSQL frames the same mechanism as the shift an InnoDB engineer must make, from a clustered primary key to a heap plus separate indexes and real MVCC tuples, and from purge to autovacuum, freezing and transaction age.[11] From the application side, the Java book notes that under two-phase locking or MVCC alike writers block conflicting writers, so a large batch should be broken into pieces that release locks promptly, and that no isolation level prevents lost updates across a multi-request conversation, which is why JPA offers optimistic locking.[15] Distributed transactions across regions, sagas against two-phase commit, and CQRS with event sourcing are the ground of System Design Mastery - Advanced.[40]

Running PostgreSQL in production

Query tuning is where most optimisation starts, and Lift the Elephant is about what comes after it: parameter tuning, monitoring, maintenance, connection pooling, replication topologies and partitioning, drawn from scaling Hubstaff.[10] Its sampled chapter takes one parameter. Every transaction is written to the write-ahead log, and synchronous_commit decides when it counts as complete: ON waits for the WAL to reach disk on the primary and be acknowledged by a synchronous standby; REMOTE_WRITE waits for the standby to receive it but not flush it; LOCAL waits only for the primary's disk; OFF acknowledges as soon as the record is in memory, risking the most recent transactions in a crash; and REMOTE_APPLY waits until the standby has applied it, so a read on either server sees the same data.[10] The setting can be chosen globally, per database or per transaction, so payment processing can run with full durability while telemetry runs with none, and pg_stat_replication shows the lag that results.[10] Its other chapters cover the memory and checkpoint parameters, autovacuum and bloat, transaction ID wraparound, the PgBouncer, Pgpool-II and PgCat poolers, replicas, active-active setups and partitioning.[10] Its closing advice is to measure before tuning, to treat every setting as a trade-off, and to design for the next order of magnitude, since decisions made at 100 GB will not hold at a terabyte.[10]

Thinking in PostgreSQL covers the same ground for engineers arriving from MySQL: one process per connection and mandatory pooling, autovacuum, sequences and ON CONFLICT in place of AUTO_INCREMENT and REPLACE INTO, EXPLAIN with BUFFERS and the pg_stat views in place of the slow query log, partial, expression, GIN and BRIN indexes, replication slots and point-in-time recovery.[11] A performance guide that works tier by tier gives the database one chapter of nine, on bottlenecks, SQL tuning and the HammerDB benchmark tool, beside the web, application and JVM tiers.[34] And the process model that makes pooling necessary is the first thing PostgreSQL Internals Mastery: A Comprehensive Guide explains, with the split between shared buffers and per-process memory such as work_mem and the asynchronous I/O subsystem new in PostgreSQL 18.[9]

Beyond the relational model

NoSQL is the name that stuck for the databases that gave up the relational model to scale horizontally. One source sets out their shared traits, shared-nothing distributed design, commodity hardware and a flexible schema, and their characteristic trade: ACID's pessimistic consistency at the end of each transaction gives way to BASE, basic availability, soft state and eventual consistency, so that a cluster keeps answering while its replicas converge.[16] It also unpicks the CAP theorem, Brewer's conjecture of 2000 proved in 2002: partitions are a fact of life, so the choice between consistency and availability arises only during one, and Abadi's PACELC adds the latency trade-off that holds the rest of the time; it groups NoSQL systems by data model into key-value, document, column-family and graph databases.[16]

Key-value and document stores

A key-value store has the simplest interface, get, set and delete by key, and the Go book argues that it is also the layer beneath SQL: relational databases are built on key-value-like storage engines, and SQL is a user interface rather than anything fundamental.[1] Redis is the production example, and two books rebuild it. Build Your Own Redis with C/C++ goes from socket programming and a request-response protocol through an event loop, hashtables, a balanced binary tree, sorted sets, TTL expiration and a thread pool in C and C++,[5] and Rust Projects - Write a Redis Clone follows the CodeCrafters challenge in Rust and Tokio, binding a port, parsing the RESP protocol, implementing GET and SET and active and passive key expiry, and arriving at the actor model for concurrency.[27]

A document database stores JSON-like documents in collections without a fixed schema. MongoDB is the one the application books use: the MEAN tutorial installs it on three operating systems and inserts and finds a first document from the shell,[25] and the Keystone.js book, whose framework creates a MongoDB collection for every model and queries it through Mongoose, explains the 24-character object id that identifies a document across collections.[26] The Angular Firebase Survival Guide (2018) gives the clearest short account of modelling in such a system, for Google's Firestore: a collection is an array and a document an object; documents should stay small, under the one-megabyte limit, so a post's comments go in a subcollection fetched separately; a document reference is the counterpart of a foreign key; and a many-to-many relationship, such as users starring films, belongs in a root collection of its own so that both sides can be queried.[24] Its rule is to use Firestore over Firebase's older Realtime Database unless the dataset is small, the queries simple and there are no relationships to model.[24]

Distributed and in-memory databases

Scaling means a bigger machine or more machines, and the hardware architecture decides which. One source lays out three: shared memory, many cores on one machine, which scales vertically and suits the traditional relational engine; shared disk, independent nodes over a storage network, which Oracle and SQL Server use until the central disk becomes the bottleneck; and shared nothing, machines sharing neither, which scales linearly and is what horizontally scaled databases use.[16] Cassandra, begun at Facebook for inbox search and open-sourced in 2009, is a peer-to-peer shared-nothing store with no special nodes, linearly scalable in Netflix's benchmarks and suited to time series such as events and sensor readings; it is not suited to strong consistency, to ad hoc queries, since the data model must be designed around the queries, or to small loads, and because it has no transactions its atomicity holds only for one write at the row level on each node.[16]

The Apache Ignite book describes a memory-centric platform that serves as a cache, a compute grid or a database with SQL and ACID transactions. Its architecture chapter explains a shared-nothing topology of identical nodes with no master, and how data is partitioned: because a plain hash table fixes the number of nodes, Ignite maps keys to one of 1,024 partitions and partitions to nodes by rendezvous hashing, so that a topology change moves the least data.[17] Its durable memory keeps data off the Java heap in fixed-size pages with the same layout in memory and on disk, each with a type, version, checksum and id in its header, and its data pages pack items from the front and values from the back, the slotted layout once more; the database chapter covers SQL and scan queries, collocated distributed joins and native persistence.[17]

Analytical and embedded engines

Transactional and analytical work want different engines. The Go book draws the line by latency and cost: OLTP touches small amounts of data through indexes and needs immediate answers, which is what B+trees and LSM-trees serve, while OLAP scans large amounts for aggregations and joins, indexes little, stores by column and tolerates latency, which is why ClickHouse, DuckDB and the big-data systems are analytical only.[1] A business primer describes the same split as operational relational databases feeding a column-store warehouse that analysts and business-intelligence tools read.[29]

DuckDB is the embedded analytical engine, a single file with no server, and Spatial Data Management with DuckDB uses it as a geographic information system: after what makes it different and when not to use it, the book teaches SQL, then loads Shapefile, GeoJSON and GeoParquet through the spatial extension, runs geometry operations and spatial joins, and maps the results from Python.[18] SQLite is the embedded transactional counterpart, and the two Elixir books show it carrying real applications, with its type affinity, limited constraints and missing INTERVAL as the price.[23][28] Beyond one machine, Spark reads from JDBC databases such as MySQL and from HBase, Hive and Cassandra as well as files, keeps its resilient distributed datasets in memory for speed over Hadoop's disk-based MapReduce, and offers Spark SQL beside streaming and machine learning.[33]

Graph databases

A graph database stores entities and the relationships between them and is queried by matching patterns. Cypher is the common language, and Cypher 103 with ladybugdb teaches it on LadybugDB, an embedded graph engine that installs in one line, through one evolving project of AI agents, their owners, tools and agreements, from schema definition and pattern matching to recursive queries, shortest paths, subqueries and transactions, with exercises in every chapter and Neo4j as the comparison point.[20] GraphDuck : duckdb for embedded Ai agents and graphs argues the opposite case, that graph thinking belongs inside the database one already has: it builds adjacency-list graphs, PageRank with recursive CTEs and shortest paths in plain SQL on DuckDB, then property graphs, triple stores, hypergraphs and metagraphs, with the DuckPGQ extension for the SQL:2023 standard's SQL/PGQ pattern matching.[19] Metagraph for AI Agents takes the modelling further, from the observation that a triple is not enough, through hypergraphs, whose edges join sets of nodes but cannot themselves be referenced, to metagraphs, where an edge can be a node, implemented side by side in a relational schema, in Cypher and in TypeDB's TypeQL.[38]

Data engineering and pipelines

Data engineering is the work of making data repeatable and available: one source defines the data engineer as the person who takes a data scientist's one-off model and automates it into a data product. A Data Engineer's Manual (2016) lays out a hierarchy of knowledge for that work, from the trouble with files and the definition of a database, through interchange formats, data models and logical design, the query optimiser and MapReduce inside the database, to REST APIs and an analytics workflow.[30] Design Driven Data Engineering starts further back, with business decisions and domain language, and moves through canonical and dimensional models and semantic layers to warehouse and lakehouse architectures, ingestion and transformation, governance and lineage, and CI/CD for data.[31] The business primer covers the same territory for non-specialists, with a glossary that defines OLTP, row and column stores, document, key-value and graph systems, data lakes and warehouses, and batch and stream processing.[29]

Pipelines fail differently from programs. Modern Data Pipelines Testing Techniques opens with their transitive failure modes: a silent data bug in a source system trickles into every downstream dataset without an alarm, a code bug in one job stops the jobs that depend on it, and the first alert usually comes from a stakeholder asking why the dashboard is stale.[32] Its contents go on to test types for SQL queries and data quality, test data, characterisation tests for legacy pipelines, design for testability, and deployment with schema versioning and the hidden things a migration needs tested.[32]

Databases and AI

The newest demand on databases comes from language models, which need stores for embeddings and for structured memory. Vector Databases explains the shift from exact-match queries to searching by meaning: embeddings and the curse of dimensionality, the choice of similarity metric, the approximate nearest-neighbour indexes, IVF, HNSW and product quantisation, that make billion-vector search practical, a comparison of Pinecone, Milvus, Weaviate, Qdrant and Chroma, and when to run managed, self-hosted or local.[21] The vector index is also arriving inside general-purpose engines: GraphDuck combines HNSW similarity search with graph traversal in a single DuckDB query for hybrid retrieval,[19] and Edge AI : Pocket Knowledge Graphs on user device runs vector search and graph queries in libSQL, an embeddable SQLite derivative, on the user's own device, so that an agent's memory never leaves it.[39]

Agent memory is the use case behind several of these books. The edge book models knowledge graphs, hypergraphs and metagraphs in a relational schema rather than a dedicated graph database, and holds that an agent needs tools, memory and reasoning together.[39] TypeDB for Edge AI Agents makes the case for a typed graph database: it begins with Russell's paradox and the type theory that keeps a schema from collapsing, explains the PERA model and dependent types, teaches TypeQL, and ends with ontologies, metagraphs and multi-agent coordination, with TypeDB 3.0's Rust rewrite making on-device deployment feasible.[22] The relationship can also run the other way, with the model as the database's client: the closing chapter of Creating AI Agents with MCP - Model Context Protocol connects Claude Desktop to PostgreSQL through a Model Context Protocol server, builds a shoe-store schema, asks it questions in plain language, and examines the tools behind the answers, the security considerations and the economics of not building a reporting application at all.[37]

Sources

Every source is a Leanpub book or course. The note after each says which part of it was read; where no sample was available, only the public description and table of contents were used.

  1. 1.
    Build Your Own Database in Go From Scratch, build-your-own.org: From B+tree to SQL in 3000 lines Free sample: the introduction (what counts as a database, durability and atomicity, OLTP versus OLAP, the key-value layer), chapter 1 on files, atomic rename and append-only logs, chapter 2 on B+trees and LSM-trees, chapter 3 on copy-on-write and double-write recovery, and the start of the B+tree node format. 2026. Free sample: EPUB
  2. 2.
    Build a SQL Database Engine in C++, Hatem M.: Through Challenges --- Storage, Query Processing, Joins, Indexes, Vectorized Execution, and Crash Recovery (Complete, Units 1-14) Free sample: what the book is and its fourteen-unit path, the scope exclusions, the reference machine, and Unit 1 on 4 KiB pages, the slotted layout, erase and compaction, with its benchmarks. 2026. Free sample: PDF
  3. 3.
    Build a Database Server, Chris Zetter: Learn how real databases work by following this practical guide to building your own No sample: from the description and table of contents, which run from the TCP server and tableless SELECT through parsing, type checking, NULL, query plans, joins, grouping and aggregates. 2025.
  4. 4.
    Code a database in 45 steps (Go), Lowram Eepson: a series of test-driven small coding puzzles No sample: from the description only, which names key-value storage engines, LSM-tree indexes, SQL, concurrent transactions and ACID; the table of contents is empty. 2025.
  5. 5.
    Build Your Own Redis with C/C++, build-your-own.org: Network programming, data structures, and low-level C. No sample: from the description and table of contents, from socket programming and the protocol to hashtables, a balanced tree, sorted sets, TTL expiration and a thread pool. 2025.
  6. 6.
    How Query Engines Work, Andy Grove: An Introductory Guide No sample: from the description and the seventeen-chapter table of contents, from Apache Arrow and the type system to the planner, joins, optimisation, parallel and distributed execution, testing and benchmarks. 2026.
  7. 7.
    Deep dive into a SQL query, Jesús Espino: A Journey Through PostgreSQL's Query Processing Free sample: chapter 1, the journey of a query through PostgreSQL 18: the process-per-connection architecture, memory contexts, the pagila setup, the wire protocol and the six pipeline stages. 2026. Free sample: PDF · EPUB
  8. 8.
    Database Engine Level Thinking, Kareem Ashraf: Building a mental model of PostgreSQL internals — written while learning No sample: from the description and table of contents, two chapters on PostgreSQL storage and memory and on indexing. 2026.
  9. 9.
    PostgreSQL Internals Mastery: A Comprehensive Guide, Giovanni Martinez: Volume I: Foundations & Core Concepts No sample: from the description and table of contents of Volume I, on the process model, memory, transactions and ACID, isolation levels, MVCC, pages and the buffer cache. 2026.
  10. 10.
    Lift the Elephant, Alex Yarotsky: Scaling PostgreSQL Beyond Query Optimization Free sample: the table of contents, the introduction, the chapter on synchronous_commit and its modes, and the closing thoughts. 2026. Free sample: PDF
  11. 11.
    Thinking in PostgreSQL, Nick Vyzas: A field guide to PostgreSQL for MySQL engineers No sample: from the description only, which sets out the MySQL-to-PostgreSQL shifts in architecture, MVCC, indexing, monitoring and configuration; the table of contents is empty. 2025.
  12. 12.
    Top 30 SQL Interview Coding Tasks, Matthew Urban Free sample: preface, the five-table e-commerce dataset, and tasks 1 to 5 on SELECT, WHERE, IN, INSERT and UPDATE. 2018. Free sample: PDF · EPUB
  13. 13.
    SQL Problem Solving, Hatem M.: A Hands-On Workbook with 84 Real SQL Challenges Free sample: how to use the book, all twelve problems of Volume 1, and the introduction to Volume 6 with its first problem, a monthly sales pivot. 2026. Free sample: PDF
  14. 14.
    MySQL Explained, OSTraining, Andrew Comeau: Your step-by-step guide to database design Description and table of contents (the sample PDF yielded no text): ten chapters from what a database is through installing MySQL, modelling, normalisation, tables and indexes, SQL, two worked designs and user interfaces. 2016. Free sample: PDF
  15. 15.
    High-Performance Java Persistence, Vlad Mihalcea: Get the most out of your persistence layer Free sample: chapter 1 on JDBC batch updates, batch size, bulk operations and auto-generated keys across Oracle, SQL Server, PostgreSQL and MySQL; chapter 2 on why JPA and Hibernate matter; the opening of the jOOQ chapter. 2024. Free sample: PDF · EPUB
  16. 16.
    Apache Cassandra From The Ground Up, Akhil Mehra Free sample: chapter 1, an introduction to NoSQL and Cassandra: database history, scaling and hardware architectures, Google and Hadoop, scaling MySQL, NoSQL categories, ACID, consistency models, BASE, CAP, PACELC, and Cassandra's features and use cases. 2023. Free sample: PDF · EPUB
  17. 17.
    The Apache Ignite book, Shamim Bhuiyan: The next phase of the distributed systems Free sample: preface and chapter map, author biographies, and chapter 4 on architecture: shared-nothing topology, client and server nodes, deployment options, partitioning, distributed hash tables, rendezvous hashing and durable memory pages. 2025. Free sample: PDF · EPUB
  18. 18.
    Spatial Data Management with DuckDB, Qiusheng Wu: From SQL Basics to Advanced Geospatial Analytics Free sample: the front matter and the full table of contents; chapters 1 and 2 on getting started and essential SQL are known from their headings. 2026. Free sample: PDF
  19. 19.
    GraphDuck : duckdb for embedded Ai agents and graphs, Volodymyr Pavlyshyn No sample: from the description and table of contents. 2026.
  20. 20.
    Cypher 103 with ladybugdb, Volodymyr Pavlyshyn No sample: from the description and the twenty-seven-chapter table of contents. 2026.
  21. 21.
    Vector Databases, Jitin Kayyala: powering modern AI applications No sample: from the description only; the table of contents is empty. 2026.
  22. 22.
    TypeDB for Edge AI Agents, Volodymyr Pavlyshyn No sample: from the description and table of contents, twenty-one chapters in five parts. 2026.
  23. 23.
    Northwind Elixir Traders, Isaak Tsalicoglou: Learn Elixir and database modeling with Ecto and SQLite, all in one project Free sample: about the book, prerequisites, why SQLite, a chapter-by-chapter outline of all seventeen chapters, software versions, the foreword, and the first part of chapter 5 on changesets in schema modules. 2025. Free sample: PDF · EPUB
  24. 24.
    The Angular Firebase Survival Guide, Jeff Delaney: Build Angular Apps on a Solid Foundation with Firebase Free sample: introduction and package versions, chapter 1 on best practices and setup, chapter 2 on Firestore versus the Realtime Database, data structuring and collection retrieval, and the lesson pointers of chapter 7. 2018. Free sample: PDF · EPUB
  25. 25.
    Getting MEAN with MEMEs, Nikola Brežnjak: Deploying MEAN TODO application to production Free sample: the first of four posts, on the MEAN stack against LAMP and installing MongoDB, Node.js, Express and AngularJS, with a first insert and find in the MongoDB shell. 2015. Free sample: PDF · EPUB
  26. 26.
    Practical Keystone.js, Manikanta Panati: A Hands On Introduction To Keystone.js Using a Real-World Project Free sample: introduction, chapter 1 on installing MongoDB and Node.js, Visual Studio Code and Robomongo, and the start of chapter 2 on creating the project and its first model. 2016. Free sample: PDF · EPUB
  27. 27.
    Rust Projects - Write a Redis Clone, Leonardo Giordani: Explore asynchronous programming with the actor model using Rust and Tokio No sample: from the description only; the table of contents is empty. 2026.
  28. 28.
    Phoenix Product Codex, Isaak Tsalicoglou: Develop and deploy a REST API for Product Data Management with Elixir and Phoenix Free sample: front matter, software versions, a chapter-by-chapter outline of the ten released chapters, and the preface on the business and the NocoDB prototype that preceded the API. 2025. Free sample: PDF · EPUB
  29. 29.
    Getting Started with Data, Simbiose Ventures Team: The first book you should read to successfully get along with data. Free sample: preface, the introductions to Parts I and II, chapter 9's paper-company walkthrough from data types and relational tables to a column-store warehouse, and the glossary. 2020. Free sample: PDF · EPUB
  30. 30.
    A Data Engineer's Manual, Joseph W. Clark, Ph.D. No sample: from the description and table of contents. 2016.
  31. 31.
    Design Driven Data Engineering, Kevin Languedoc: Design-Driven Data Engineering: From Business Domain Models to Production Data Systems No sample: from the description and table of contents. 2026.
  32. 32.
    Modern Data Pipelines Testing Techniques, Moussa Taifi: A Visual Guide Free sample: the table of contents and the opening of chapter 1 on transitive failure modes. 2023. Free sample: PDF
  33. 33.
    Spark Tutorials with Scala, Todd McGrath: The Beginner's Guide Free sample: objectives and assumptions, what Spark is and how it relates to Hadoop, RDDs, and the first spark-shell tutorial. 2016. Free sample: PDF
  34. 34.
    The Art Of Performance Engineering, Vineeta Vashistha & Amit Vashistha: Learn Performance Optimization techniques to ensure high performance of your application. No sample: from the description and table of contents. 2021.
  35. 35.
    From A Non-Programmer To Full Stack .NET Developer, Ion Cosmin Grigore: Step-by-step guide for your first web application (includes setup tutorials for the tools you need) No sample: from the description and table of contents. 2019.
  36. 36.
    Ruby on Roda, Mateusz Urbański: REST APIs with Roda & Sequel No sample: from the description and table of contents. 2021.
  37. 37.
    Creating AI Agents with MCP - Model Context Protocol, Lydia Evelyn and Bruce Hopkins: Part of the series, "The Only Book You'll Need On..." No sample: from the description and table of contents, whose chapter 7 connects an AI client to PostgreSQL. 2025.
  38. 38.
    Metagraph for AI Agents, Volodymyr Pavlyshyn No sample: from the description and table of contents. 2026.
  39. 39.
    Edge AI : Pocket Knowledge Graphs on user device, Volodymyr Pavlyshyn No sample: from the description and table of contents. 2025.
  40. 40.
    System Design Mastery - Advanced, Sameer Paradkar: Case Studies, Trade-offs & Scenarios No sample: from the description only; the table of contents is empty. 2026.
  41. 41.
    The C# and .NET Interview Compendium – Second Edition, Yohan J. Rodríguez: Interview Questions and Answers for C# and .NET Developers Free sample: preface and the C# basics questions, which contain no database material; chapter 8 on SQL Server, T-SQL, Entity Framework and LINQ to Entities is known from the table of contents. 2026. Free sample: PDF

Further reading

Other books in the library on the same ground, not cited above.

  • Objection.js and Knex.js Guidebook, Advena: A step-by-step guide to build basic REST API’s with Objection.js, Knex.js, Express.js, NodeJS and relational databases using best practices. A guide to REST APIs with the Objection.js mapper and the Knex.js query builder over relational databases, known only from its subtitle. 2020.

This is an article created from the free samples of 19 Leanpub books and the descriptions and tables of contents of 22 more. We're building these articles to provide you, the Leanpub reader, with a good jumping-off point to discover more Leanpub books that are interesting and relevant to you. We never use material which is paid-only when building these articles: we only use material which is already free on Leanpub. However, Leanpub authors can opt out from inclusion in articles from their book settings page.

Updated November 2026.

In the Leanpub store: 266 books · 5 courses in the Databases category · also filed under SQL, PostgreSQL, MySQL, MongoDB, SQL Server, Oracle, Embedded Database, Enterprise Data Modelling

All topics