Exercise 1: What Makes GIN Structurally Different From B-Tree — Possible Solution ==================================================================== THE STRUCTURAL DIFFERENCE ------------------------------ Per this chapter, "GIN stores a mapping from each individual component of a value — a JSONB key, an array element, a tsvector lexeme — to the list of rows containing it. This is a structurally different approach from a B-tree, which is built around ordering a single value per row; GIN is built for 'does this composite value contain X' queries instead." A B-tree treats each row's indexed value as ONE atomic thing to be sorted and searched by ordering. GIN instead breaks a single row's value apart into its individual COMPONENTS (each key inside a JSON object, each element inside an array, each lexeme inside a tsvector), and indexes each of those components separately, pointing back to the row(s) that contain them. WHY THIS FITS JSONB CONTAINMENT ------------------------------ A JSONB containment query (per postgres1-4's own @> operator) asks "does this JSONB value contain this specific key/value pair somewhere inside it?" A B-tree, built to compare and order whole values, has no efficient way to answer "does this document contain X somewhere inside its structure" — it would have to inspect the full value of every row. GIN, having already broken each JSONB document down into its individual keys/values at index-build time, can look up "which rows contain this specific component" directly and quickly, which is exactly the containment question being asked. WHY THIS FITS FULL-TEXT SEARCH ------------------------------ A full-text search query (per postgres1-6's own tsvector/tsquery material) asks "which documents contain these specific lexemes?" A tsvector is, by nature, a collection of individual lexemes, not one atomic value — the natural indexing question is "for each lexeme, which documents contain it," which is precisely the component-to-row mapping GIN maintains. A B-tree, again built for ordering single whole values, has no natural way to answer a "which rows contain any of these several component words" question efficiently. WHY THIS WORKS AS AN ANSWER ------------------------------ It explains the core structural distinction (component-to-row mapping vs. whole-value ordering) using the chapter's own wording, and applies that distinction specifically to both named use cases (JSONB containment, full-text search) to show why each one is naturally a "does this contain X" question GIN is built to answer.