4.7 Domain Types: Adding Constraints to Base Types

Alright, let’s talk about making your database actually useful. You’ve got your standard-issue data types: INTEGER, TEXT, VARCHAR. They’re the raw lumber. Powerful, but if you build a house with just planks and nails, you’ll end up with doors that are seven feet tall and windows that let in the rain. This is where domain types come in. Think of them as custom molds or jigs. They let you take a base type and slap on constraints and a more meaningful name, ensuring the data that goes in actually makes sense for your specific problem.

4.6 Composite Types: Creating and Querying Row Types

Right, so you’ve mastered the basic scalar types – integers, text, booleans, the usual suspects. They’re the solo artists. But data is rarely about lone values; it’s about relationships. A person has a first name and a last name. A point on a graph has an x-coordinate and a y-coordinate. Enter the Row Type, PostgreSQL’s brilliantly simple way to keep these related values bundled together. Think of it as a single-column table, a structured record you can pass around as a single unit. It’s the database’s way of saying, “These things belong together, so let’s treat them that way.”

4.5 pg_lsn: Log Sequence Numbers for WAL Positions

Right, so you’ve decided to get serious about PostgreSQL’s Write-Ahead Log (WAL). Good for you. It’s the secret sauce behind almost every “how does Postgres do that?!” feature, from crash recovery to replication. And to understand the WAL, you need to understand its address system: the Log Sequence Number, or pg_lsn. This isn’t your average integer; it’s a data type specifically designed to talk about points in the transaction log, and it’s far more elegant than just throwing a BIGINT at the problem.

4.4 UUID: Storage, Generation, and pg_crypto

Right, let’s talk about UUIDs. You’ve probably seen these 36-character monstrosities (a0eebc99-9c0b-4d8b-b654-9b1f7d4e8b66) lurking in your database. They look like someone fell asleep on their keyboard, but I promise there’s a method to the hexadecimal madness. We use them when we need a unique identifier that can be generated anywhere—on your client, in your API, in ten different microservices at once—without anyone having to call a central “id-issuing authority” (like a database sequence) and risk a bottleneck or a collision.

4.3 Network Address Types: inet, cidr, macaddr, and macaddr8

Right, let’s talk about the various ways PostgreSQL can remember where things live and how to talk to them. We’re not just storing ‘www.example.com’ here; we’re dealing with the raw, structured numbers that actually make the network work. This is for when you need to know if an IP is within a range, validate a MAC address, or just store this stuff without losing your mind trying to do it in a string.

4.2 Geometric Types: point, line, lseg, box, circle, polygon

Alright, let’s talk about shapes. No, not the ones you failed to cut out in kindergarten. We’re dealing with Postgres’s geometric types, a wonderfully useful and occasionally maddening set of tools for when you need to store more than just numbers and text. They live in their own little coordinate-based universe, and while they’re powerful, they have a few quirks that will make you want to gently headbutt your monitor. I’m here to guide you through that.

4.1 Categories of Built-in Types: Primitive, Composite, and Domain

Right, let’s talk about the building blocks. Before you can build anything clever, you need to know your bricks, mortar, and the occasional weird, custom-shaped brick that some previous architect decided was a good idea. In PostgreSQL, your data types are your bricks, and they fall into three main categories: Primitive, Composite, and Domain. Think of them as Lego bricks, pre-built Lego sets, and official Lego sets you’ve modified with a marker.

— joke —

...