Mastering Postgres
Introduction
Introduction to the course
Overview of course structure
Postgres vs. everyone
The psql CLI
Data Types
Introduction to schema
Integers
Numeric
Floating point
Storing money
NaNs and infinity
Casting types
Characters types
Check constraints
Domain types
Charsets and collations
Binary data
UUIDs
Boolean
Enums
Timestamps
Timezones
Dates and times
Advanced Data Types
Intervals
Serial type
Sequences
Identity
Network and mac addresses
JSON
Arrays
Generated columns
Text search types
Bit string
Ranges
Composite types
Nulls
Unique constraints
Exclusion constraints
Foreign key constraints
Indexing
Introduction to indexes
Heaps and CTIDs
B-Tree overview
Primary keys vs. secondary indexes
Primary key types
Where to add indexes
Index selectivity
Composite indexes
Composite range
Combining multiple indexes
Covering indexes
Partial indexes
Index ordering
Ordering nulls in indexes
Advanced Indexing
Functional indexes
Duplicate indexes
Hash indexes
Naming indexes
Understanding Query Plans
Introduction to explain
Explain structure
Scan nodes
Costs and rows
Explain analyze
Generating Results
Introduction to queries
Cross joins
Inner joins
Outer joins
Subqueries
Lateral joins
ROWS FROM
Filling gaps in sequences
Subquery elimination
Combining queries
Set generating functions
Indexing joins
Advanced SQL
Introduction to advanced SQL
Grouping
Grouping sets, rollups, cubes
Window functions
CTEs
CTEs with window functions
Recursive CTE
Hierarchical recursive CTE
Handling nulls
Row value syntax
Views
Materialized views
Removing duplicate rows
Upsert
Returning keyword
COALESCE + generated column
Full Text Search
Introduction to full text search
Searching with LIKE
Vectors, queries, and ranks
Websearch
Ranking
Indexing full text search
Highlighting
Advanced JSON
Intro to JSON
JSON vs JSONB
Validating JSON
Creating JSON objects + arrays
JSON extraction
JSON containment
JSON existence
JSON recordset
Updating JSON
Indexing JSON parts
GIN index
Vectors (pgvector)
Intro to pgvector
Vector embedding columns
Find related articles
Upsert vector embedding
Semantic search
Other operators
Vector indexes
Outro
Thank you
Bonus interviews
Heroku's glory days & Postgres vs the world (with Craig Kerstiens)
Creating a Postgres platform with Monica & Tudor from Xata.io
Bootstrapping an email service provider (with Jesse Hanley)
Watch for free

Enter your email below to watch this video

Video thumbnail
Data Types
UUIDs

Full Course

$
349
$399
USD, one-time fee
The course "Mastering Postgres" helped me practice query commands and understand why they're important. Inspiring me to explore the 'why' and 'how' behind each one. Truly a great course!
Nakolus
Nakolus

PostgreSQL database platform

Shorten dev cycles with branching and zero-downtime schema migrations.

Test Data

I've made my test data available for you to use and follow along.

Download
or
Use on Xata

Summary

Learn how to use UUIDs as a data type, focusing on their compact storage and efficiency compared to storing them as text. The video explores how UUIDs can be generated and their usefulness for creating unique IDs across systems. You’ll also get an introduction to using UUIDs as primary keys, with a particular emphasis on UUID version 7 for its timestamp feature.

Video Transcript

We ended the discussion about binary data types. Talking about MD5, shot 256 UUIDs. This video, we're going to talk about UUIDs as a data type. What we're not going to talk about is using UUIDs as a primary key. We will talk about that, we have a little bit of groundwork to lay first.

First, we're going to talk about UUIDs as a data type then we need to talk about indexes bee trees. Then we need to talk about secondary keys then we can talk about big ends versus UUIDs. If you don't care, just choose a big end. There's a good reason behind that. It has to do with fracturing the bee trees we don't even know what a bee tree is yet. Let's talk about UUIDs as a data type. The data type here is just simply UUID. You would potentially have a bunch of other columns. You'd probably have an ID. You may have noticed I've been skipping the IDs that's 'cause we haven't gotten to primary keys yet. I just want to save that.

Usually you would have maybe like some data or name or value or whatever. It doesn't matter for this example, UUID, universally unique ID. It's a strong claim. In fact, I think it's a fair claim because I think you're more likely to get hit by lightning like 40 times than have a UUID collision. UUIDs are very, very helpful when you're generating IDs without coordination. That could be in separate systems, on separate machines, microservices, different services. They don't even have to be micro or generating them on the client. Maybe you're doing some sort of optimistic UI you generate something on the client it needs a unique ID. You generate a UUID out there. Totally legit. Perfectly good reason to use them.

Let's go ahead did we already run? Did we already create this table? We created this table then what I'm going to do is I'm just going to insert this as if I've been given this string from the outside world. Either some other system or the client has given this to me it looks like a string. If we read this back, we do select * from UUID example, we will see that it's still looks like a string. Let's take, let's do two things here. Let's do UUID value, let's do three things. PG type of UUID value, we get UUID. It's not a string, it's not text, although you could, you could cast it to text if you wanted, you don't need to. A display is just fine. It's a type of UUID. Then let's do PG column size, UUID value. That's the good stuff. That's the good stuff that we're after, 16 bytes. This entire string here, in fact, let's do this again. Let's do select PG column size of, let's just take, let's just take that string.

Actually let's do it this way. Let's do cast it to text then we'll copy it do it again, not cast to text from UUID example. If we run that, that is why you UUID is such a great data type for UUIDs, because it is efficiently stored, it's stored better on disc, much more compact. It is faster to operate against. This is what I'm talking about. If you think all, how many videos have we done? If you think all the way back to the beginning of this module you think about where I was telling you, pick the data type that is most representative of reality. That is most compact. That is the simplest. This is a great example.

You could store your UUIDs as text. It's better to store 'em as UUIDs. It's just, it's just better. That is what you want to do. Anytime you do have a UUID, you can also generate your own. You can have Postgres generate UUIDs for you. Let me show you how to do that. The only type of UUID that Postgres can generate out of the box without an extension is a random UUID. This is going to lead us nicely into the discussion about primary keys data types later on. There are, I think at the time of recording eight versions of UUID they don't supersede each other. They are just simply different versions.

Each part of a UUID is representative of some type of data, whether that is a timestamp, random bits, machines, whatever, some sort of entropy. Each piece has its own kind of domain that it's responsible for. Versions one through seven or eight, whatever it is currently all do it a little bit differently. The good thing about UU at version seven, which is not in Postgres by default you can get an extension for it. The good thing about UUID V7 is this first part is a timestamp. What that means is that it's always going to go lexographically sorted. It's always going to go at the end. If you needed to, you could extract the timestamp out of the UUID. While the, while UUID V7 is not available by default, you can find extensions for it. Or if you're using a hosted provider, they might have already built it with a V7 extension.

Just to talk about indexes one more time, V7 could make a very fine primary key. However, this gen random UUID would be a terrible primary key. There's a little primer on UUIDs. If you're already using them to generate stuff in the outside world, this is a great way to store them. If you're going to try to use 'em for primary keys, I implore you to get a V7 or wait until the video where we talk about primary keys. Regardless of where the UUIDs come from, please store them as a UUID type you'll get a compact 16 bytes instead of, I think it was like 40 bytes if you store it as a string. 'cause you have the 36 bytes of the string four bytes of overhead.