mirror of
https://github.com/supabase/supabase.git
synced 2026-10-12 21:05:06 +03:00
Add db and auth pages
This commit is contained in:
1 parent
697d457f1d
commit
b2497cefb8
9 files changed
+786
-38
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import Link from 'next/link'
|
||||
|
||||
import NavigationItem from '@/components/side-navigation-item'
|
||||
import { gettingStarted } from '@/config/docs'
|
||||
import { courses } from '@/config/docs'
|
||||
import { CommandMenu } from './command-menu'
|
||||
import { ThemeSwitcherDropdown } from './theme-switcher-dropdown'
|
||||
|
||||
@@ -68,10 +68,10 @@ function SideNavigation() {
|
||||
</div>
|
||||
<div className="pb-6 px-6">
|
||||
<h3 className="text-xs font-semibold text-foreground-lighter/75 uppercase tracking-wider mb-3">
|
||||
{gettingStarted.title}
|
||||
{courses.title}
|
||||
</h3>
|
||||
<ul className="space-y-1">
|
||||
{gettingStarted.items.map((item, i) => (
|
||||
{courses.items.map((item, i) => (
|
||||
<NavigationItem item={item} key={`${item.href}-${i}`} />
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { SidebarNavGroup } from 'types/nav'
|
||||
|
||||
export const gettingStarted: SidebarNavGroup = {
|
||||
export const courses: SidebarNavGroup = {
|
||||
title: 'Courses',
|
||||
items: [
|
||||
{
|
||||
@@ -23,6 +23,22 @@ export const gettingStarted: SidebarNavGroup = {
|
||||
title: 'Authentication',
|
||||
href: '/foundations/authentication',
|
||||
},
|
||||
{
|
||||
title: 'Security',
|
||||
href: '/foundations/security',
|
||||
},
|
||||
{
|
||||
title: 'Storage',
|
||||
href: '/foundations/storage',
|
||||
},
|
||||
{
|
||||
title: 'Edge Functions',
|
||||
href: '/foundations/edge-functions',
|
||||
},
|
||||
{
|
||||
title: 'Vector Search',
|
||||
href: '/foundations/vector-search',
|
||||
},
|
||||
],
|
||||
commandItemLabel: 'Foundations',
|
||||
},
|
||||
@@ -45,7 +61,7 @@ export const gettingStarted: SidebarNavGroup = {
|
||||
}
|
||||
|
||||
export const COMMAND_ITEMS = [
|
||||
...gettingStarted.items.map((item) => ({
|
||||
...courses.items.map((item) => ({
|
||||
label: item.commandItemLabel,
|
||||
href: item.href,
|
||||
})),
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Authentication
|
||||
description: Learn how Supabase manages users and how signed-in requests connect to the database.
|
||||
chapterNumber: 3
|
||||
---
|
||||
|
||||
Most applications need to know who is using them. Authentication is how we identify
|
||||
a user and attach their actions to their own data. Supabase includes an
|
||||
authentication system that works directly with the database, so user identity
|
||||
flows naturally into queries and permissions.
|
||||
|
||||
Authentication in Supabase is handled by Supabase Auth. It manages creating
|
||||
accounts, signing in, and issuing tokens that represent the current user.
|
||||
|
||||
---
|
||||
|
||||
## Users
|
||||
|
||||
A user in Supabase has an id and some optional profile information (such as
|
||||
email). When someone signs up, Supabase creates a new user record and assigns
|
||||
them a unique identifier.
|
||||
|
||||
You do not need to create or manage the users table yourself. Supabase stores it
|
||||
internally and keeps it updated.
|
||||
|
||||
Example of the kind of data Supabase stores for a user:
|
||||
|
||||
```text
|
||||
id: 74d2...af1
|
||||
email: maria@example.com
|
||||
created: 2025-01-12 09:44:21
|
||||
```
|
||||
|
||||
You can reference this user id in your tables when you want to link data to a
|
||||
specific user.
|
||||
|
||||
---
|
||||
|
||||
## Tokens and identity
|
||||
|
||||
When a user signs in, Supabase returns a token. This token proves who the user
|
||||
is. Your application includes this token in each API request.
|
||||
|
||||
Inside the database, this token becomes the value returned by `auth.uid()`.
|
||||
This lets policies decide which data belongs to which user.
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
select auth.uid();
|
||||
```
|
||||
|
||||
returns the id of the signed-in user who made the request.
|
||||
|
||||
---
|
||||
|
||||
## Sign up and sign in
|
||||
|
||||
Supabase Auth supports several sign-in methods:
|
||||
|
||||
- Email and password
|
||||
- Magic links (sign in by clicking a link in an email)
|
||||
- OAuth providers (Google, GitHub, etc.)
|
||||
- Phone number (SMS)
|
||||
|
||||
For now, we will use email and password, since it is the simplest starting point.
|
||||
|
||||
---
|
||||
|
||||
## Where authentication connects to data
|
||||
|
||||
Authentication by itself only identifies a user. It does not control access.
|
||||
The next step is **Row Level Security (RLS)**. RLS uses the user id from the
|
||||
token to decide which rows the user can read or write.
|
||||
|
||||
So the flow looks like this:
|
||||
|
||||
```text
|
||||
User signs in
|
||||
↓
|
||||
Supabase gives the client a user token
|
||||
↓
|
||||
Client sends token with API requests
|
||||
↓
|
||||
Postgres receives token and sets auth.uid()
|
||||
↓
|
||||
RLS policies use auth.uid() to enforce access rules
|
||||
```
|
||||
|
||||
Authentication says who the user is.
|
||||
RLS decides what they are allowed to do.
|
||||
|
||||
---
|
||||
|
||||
## What we learned
|
||||
|
||||
- Supabase Auth manages user accounts and sign-in.
|
||||
- Each user has a unique id that you can reference in your tables.
|
||||
- When a user signs in, Supabase provides a token.
|
||||
- The token tells the database who the user is through `auth.uid()`.
|
||||
- Authentication by itself does not control access. RLS does that part.
|
||||
|
||||
Understanding this identity flow is important before we begin writing policies.
|
||||
@@ -1,52 +1,136 @@
|
||||
---
|
||||
title: Data Fundamentals
|
||||
description: Learn the foundations of Supabase, the Postgres development platform.
|
||||
description: 'Learn how data is structured in Postgres: tables, rows, columns, and keys.'
|
||||
chapterNumber: 2
|
||||
---
|
||||
|
||||
In this chapter, you'll learn how to create a table in Supabase, insert data into it, and query it using the REST API.
|
||||
Before we store any information in Supabase, we need to understand how data is
|
||||
organized in Postgres. Supabase uses Postgres as its database, which means data
|
||||
is arranged in a structured and predictable way. This helps keep your app
|
||||
organized, consistent, and easy to query.
|
||||
|
||||
## What you'll learn
|
||||
|
||||
- **Data fundamentals**: create tables, insert and retrieve data, and explore our generated APIs.
|
||||
The core ideas are simple: you create tables to hold related data, and each
|
||||
table has rows (records) and columns (fields). Once you understand that pattern,
|
||||
you can model almost anything.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
## Tables, rows, and columns
|
||||
|
||||
- A [Supabase account](https://supabase.com/) (free)
|
||||
- Basic familiarity with a terminal to run queries.
|
||||
A table is like a spreadsheet. It has:
|
||||
|
||||
- **Columns**: the fields that define what kind of data the table stores
|
||||
- **Rows**: the individual entries in the table
|
||||
|
||||
Imagine a table for storing notes:
|
||||
|
||||
```text
|
||||
| id | content | created_at |
|
||||
|----|------------------|----------------------|
|
||||
| 1 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
- Each **row** is a single note.
|
||||
- Each **column** represents one piece of information about the note.
|
||||
|
||||
---
|
||||
|
||||
## Course outline
|
||||
## Data types
|
||||
|
||||
The course is split into 7 chapters, each approximately 10 minutes long.
|
||||
Every column has a data type. This describes the kind of value that can be
|
||||
stored there.
|
||||
|
||||
1. **What is Supabase?**
|
||||
Get an overview of Supabase's architecture and core products. Create your first project and make a simple API call.
|
||||
2. **Your First Table**
|
||||
Create a Postgres table in Supabase, insert data, and query it through the REST API.
|
||||
3. **Authentication Basics**
|
||||
Add users, sign them in, and understand how Supabase secures your APIs with JWTs.
|
||||
4. **Secure Your Data with Row-Level Security**
|
||||
Enable Row-Level Security and write policies to ensure users only access their own data.
|
||||
5. **Storage**
|
||||
Store files in Supabase Storage and upload and serve files from your buckets.
|
||||
6. **Edge Functions**
|
||||
Deploy simple functions to run backend logic close to your users using Deno.
|
||||
7. **Vector Search**
|
||||
Store and query embeddings for AI-powered search and recommendations using Supabase Vector.
|
||||
Some common data types:
|
||||
|
||||
```text
|
||||
| Data type | Example value | Meaning |
|
||||
| ----------- | ---------------- | ----------------------------- |
|
||||
| text | Hello world | A string of characters |
|
||||
| integer | 42 | A number without decimals |
|
||||
| boolean | true | Yes/no or on/off values |
|
||||
| timestamptz | 2025-01-10 14:22 | Date and time (with timezone) |
|
||||
| json | {"name": "John"} | A JSON object |
|
||||
```
|
||||
|
||||
Choosing correct types makes your data easier to work with and protects you from
|
||||
unexpected values.
|
||||
|
||||
---
|
||||
|
||||
## Before you begin
|
||||
## Primary keys
|
||||
|
||||
Create a new project at [supabase.com](https://supabase.com), open the **Supabase Dashboard**, and grab your **API URL** and **anon key** from the [Connect dialog](https://supabase.com/dashboard/project/_/settings/api?showConnect=true&connectTab=frameworks).
|
||||
You'll use them throughout the course to send real requests to your database and APIs.
|
||||
Most tables include a primary key. This is a column that uniquely identifies each
|
||||
row. In many Supabase projects, this column is named `id` and uses a type called
|
||||
`uuid`, which automatically generates a unique value.
|
||||
|
||||
You create this column in the table definition like this:
|
||||
|
||||
```text
|
||||
id uuid primary key default gen_random_uuid()
|
||||
```
|
||||
|
||||
You generally don't need to think about it after setting it up. It simply gives
|
||||
each record a stable identity.
|
||||
|
||||
---
|
||||
|
||||
## Duration
|
||||
## Relationships between tables
|
||||
|
||||
Approx. **1 hour** — a fast, hands-on introduction to the Supabase platform.
|
||||
You can link tables together using foreign keys. This is how you express things
|
||||
like:
|
||||
|
||||
- A user has many notes
|
||||
- A project has many tasks
|
||||
- A team has many members
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
| id | user_id | content | created_at |
|
||||
|----|--------------------------------------|------------------|----------------------|
|
||||
| 1 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
Here, `user_id` refers to a row in a `users` table. This means the note belongs
|
||||
to that user, and we can see that this user has two notes.
|
||||
|
||||
Relationships let you organize data without repeating information.
|
||||
|
||||
---
|
||||
|
||||
## Why relational data is useful in practice
|
||||
|
||||
Relational data is really useful in practice because it allows you to:
|
||||
|
||||
- Keep data valid with constraints <br />
|
||||
_Example: no duplicate emails._
|
||||
|
||||
- Link records safely with foreign keys <br />
|
||||
_Example: delete a user and their notes in one action._
|
||||
|
||||
- Express real permissions with RLS <br />
|
||||
_Example: users can read their own notes; admins can read all._
|
||||
|
||||
- Query exactly what you need with table joins <br />
|
||||
_Example: fetch notes with the author's email._
|
||||
|
||||
---
|
||||
|
||||
## What we learned
|
||||
|
||||
A database in Supabase is made up of tables.
|
||||
Each table has:
|
||||
|
||||
- columns (which describe the type of information stored)
|
||||
- rows (the individual pieces of data in that table)
|
||||
|
||||
You can relate tables to each other using foreign keys.
|
||||
This lets you model real situations, such as:
|
||||
|
||||
- a user has many notes
|
||||
- a team has many members
|
||||
- a project has many tasks
|
||||
|
||||
Thinking in tables, rows, and relationships is the foundation of working with data in Supabase.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: Data Fundamentals
|
||||
description: 'Learn how data is structured in Postgres: tables, rows, columns, and keys.'
|
||||
chapterNumber: 2
|
||||
---
|
||||
|
||||
Before we store any information in Supabase, we need to understand how data is
|
||||
organized in Postgres. Supabase uses Postgres as its database, which means data
|
||||
is arranged in a structured and predictable way. This helps keep your app
|
||||
organized, consistent, and easy to query.
|
||||
|
||||
The core ideas are simple: you create tables to hold related data, and each
|
||||
table has rows (records) and columns (fields). Once you understand that pattern,
|
||||
you can model almost anything.
|
||||
|
||||
---
|
||||
|
||||
## Tables, rows, and columns
|
||||
|
||||
A table is like a spreadsheet. It has:
|
||||
|
||||
- **Columns**: the fields that define what kind of data the table stores
|
||||
- **Rows**: the individual entries in the table
|
||||
|
||||
Imagine a table for storing notes:
|
||||
|
||||
```text
|
||||
| id | content | created_at |
|
||||
|----|------------------|----------------------|
|
||||
| 1 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
- Each **row** is a single note.
|
||||
- Each **column** represents one piece of information about the note.
|
||||
|
||||
---
|
||||
|
||||
## Data types
|
||||
|
||||
Every column has a data type. This describes the kind of value that can be
|
||||
stored there.
|
||||
|
||||
Some common data types:
|
||||
|
||||
```text
|
||||
| Data type | Example value | Meaning |
|
||||
| ----------- | ---------------- | ----------------------------- |
|
||||
| text | Hello world | A string of characters |
|
||||
| integer | 42 | A number without decimals |
|
||||
| boolean | true | Yes/no or on/off values |
|
||||
| timestamptz | 2025-01-10 14:22 | Date and time (with timezone) |
|
||||
| json | {"name": "John"} | A JSON object |
|
||||
```
|
||||
|
||||
Choosing correct types makes your data easier to work with and protects you from
|
||||
unexpected values.
|
||||
|
||||
---
|
||||
|
||||
## Primary keys
|
||||
|
||||
Most tables include a primary key. This is a column that uniquely identifies each
|
||||
row. In many Supabase projects, this column is named `id` and uses a type called
|
||||
`uuid`, which automatically generates a unique value.
|
||||
|
||||
You create this column in the table definition like this:
|
||||
|
||||
```text
|
||||
id uuid primary key default gen_random_uuid()
|
||||
```
|
||||
|
||||
You generally don't need to think about it after setting it up. It simply gives
|
||||
each record a stable identity.
|
||||
|
||||
---
|
||||
|
||||
## Relationships between tables
|
||||
|
||||
You can link tables together using foreign keys. This is how you express things
|
||||
like:
|
||||
|
||||
- A user has many notes
|
||||
- A project has many tasks
|
||||
- A team has many members
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
| id | user_id | content | created_at |
|
||||
|----|--------------------------------------|------------------|----------------------|
|
||||
| 1 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
Here, `user_id` refers to a row in a `users` table. This means the note belongs
|
||||
to that user, and we can see that this user has two notes.
|
||||
|
||||
Relationships let you organize data without repeating information.
|
||||
|
||||
---
|
||||
|
||||
## Why relational data is useful in practice
|
||||
|
||||
Relational data is really useful in practice because it allows you to:
|
||||
|
||||
- Keep data valid with constraints <br />
|
||||
_Example: no duplicate emails._
|
||||
|
||||
- Link records safely with foreign keys <br />
|
||||
_Example: delete a user and their notes in one action._
|
||||
|
||||
- Express real permissions with RLS <br />
|
||||
_Example: users can read their own notes; admins can read all._
|
||||
|
||||
- Query exactly what you need with table joins <br />
|
||||
_Example: fetch notes with the author's email._
|
||||
|
||||
---
|
||||
|
||||
## What we learned
|
||||
|
||||
A database in Supabase is made up of tables.
|
||||
Each table has:
|
||||
|
||||
- columns (which describe the type of information stored)
|
||||
- rows (the individual pieces of data in that table)
|
||||
|
||||
You can relate tables to each other using foreign keys.
|
||||
This lets you model real situations, such as:
|
||||
|
||||
- a user has many notes
|
||||
- a team has many members
|
||||
- a project has many tasks
|
||||
|
||||
Thinking in tables, rows, and relationships is the foundation of working with data in Supabase.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: Data Fundamentals
|
||||
description: 'Learn how data is structured in Postgres: tables, rows, columns, and keys.'
|
||||
chapterNumber: 2
|
||||
---
|
||||
|
||||
Before we store any information in Supabase, we need to understand how data is
|
||||
organized in Postgres. Supabase uses Postgres as its database, which means data
|
||||
is arranged in a structured and predictable way. This helps keep your app
|
||||
organized, consistent, and easy to query.
|
||||
|
||||
The core ideas are simple: you create tables to hold related data, and each
|
||||
table has rows (records) and columns (fields). Once you understand that pattern,
|
||||
you can model almost anything.
|
||||
|
||||
---
|
||||
|
||||
## Tables, rows, and columns
|
||||
|
||||
A table is like a spreadsheet. It has:
|
||||
|
||||
- **Columns**: the fields that define what kind of data the table stores
|
||||
- **Rows**: the individual entries in the table
|
||||
|
||||
Imagine a table for storing notes:
|
||||
|
||||
```text
|
||||
| id | content | created_at |
|
||||
|----|------------------|----------------------|
|
||||
| 1 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
- Each **row** is a single note.
|
||||
- Each **column** represents one piece of information about the note.
|
||||
|
||||
---
|
||||
|
||||
## Data types
|
||||
|
||||
Every column has a data type. This describes the kind of value that can be
|
||||
stored there.
|
||||
|
||||
Some common data types:
|
||||
|
||||
```text
|
||||
| Data type | Example value | Meaning |
|
||||
| ----------- | ---------------- | ----------------------------- |
|
||||
| text | Hello world | A string of characters |
|
||||
| integer | 42 | A number without decimals |
|
||||
| boolean | true | Yes/no or on/off values |
|
||||
| timestamptz | 2025-01-10 14:22 | Date and time (with timezone) |
|
||||
| json | {"name": "John"} | A JSON object |
|
||||
```
|
||||
|
||||
Choosing correct types makes your data easier to work with and protects you from
|
||||
unexpected values.
|
||||
|
||||
---
|
||||
|
||||
## Primary keys
|
||||
|
||||
Most tables include a primary key. This is a column that uniquely identifies each
|
||||
row. In many Supabase projects, this column is named `id` and uses a type called
|
||||
`uuid`, which automatically generates a unique value.
|
||||
|
||||
You create this column in the table definition like this:
|
||||
|
||||
```text
|
||||
id uuid primary key default gen_random_uuid()
|
||||
```
|
||||
|
||||
You generally don't need to think about it after setting it up. It simply gives
|
||||
each record a stable identity.
|
||||
|
||||
---
|
||||
|
||||
## Relationships between tables
|
||||
|
||||
You can link tables together using foreign keys. This is how you express things
|
||||
like:
|
||||
|
||||
- A user has many notes
|
||||
- A project has many tasks
|
||||
- A team has many members
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
| id | user_id | content | created_at |
|
||||
|----|--------------------------------------|------------------|----------------------|
|
||||
| 1 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
Here, `user_id` refers to a row in a `users` table. This means the note belongs
|
||||
to that user, and we can see that this user has two notes.
|
||||
|
||||
Relationships let you organize data without repeating information.
|
||||
|
||||
---
|
||||
|
||||
## Why relational data is useful in practice
|
||||
|
||||
Relational data is really useful in practice because it allows you to:
|
||||
|
||||
- Keep data valid with constraints <br />
|
||||
_Example: no duplicate emails._
|
||||
|
||||
- Link records safely with foreign keys <br />
|
||||
_Example: delete a user and their notes in one action._
|
||||
|
||||
- Express real permissions with RLS <br />
|
||||
_Example: users can read their own notes; admins can read all._
|
||||
|
||||
- Query exactly what you need with table joins <br />
|
||||
_Example: fetch notes with the author's email._
|
||||
|
||||
---
|
||||
|
||||
## What we learned
|
||||
|
||||
A database in Supabase is made up of tables.
|
||||
Each table has:
|
||||
|
||||
- columns (which describe the type of information stored)
|
||||
- rows (the individual pieces of data in that table)
|
||||
|
||||
You can relate tables to each other using foreign keys.
|
||||
This lets you model real situations, such as:
|
||||
|
||||
- a user has many notes
|
||||
- a team has many members
|
||||
- a project has many tasks
|
||||
|
||||
Thinking in tables, rows, and relationships is the foundation of working with data in Supabase.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: Data Fundamentals
|
||||
description: 'Learn how data is structured in Postgres: tables, rows, columns, and keys.'
|
||||
chapterNumber: 2
|
||||
---
|
||||
|
||||
Before we store any information in Supabase, we need to understand how data is
|
||||
organized in Postgres. Supabase uses Postgres as its database, which means data
|
||||
is arranged in a structured and predictable way. This helps keep your app
|
||||
organized, consistent, and easy to query.
|
||||
|
||||
The core ideas are simple: you create tables to hold related data, and each
|
||||
table has rows (records) and columns (fields). Once you understand that pattern,
|
||||
you can model almost anything.
|
||||
|
||||
---
|
||||
|
||||
## Tables, rows, and columns
|
||||
|
||||
A table is like a spreadsheet. It has:
|
||||
|
||||
- **Columns**: the fields that define what kind of data the table stores
|
||||
- **Rows**: the individual entries in the table
|
||||
|
||||
Imagine a table for storing notes:
|
||||
|
||||
```text
|
||||
| id | content | created_at |
|
||||
|----|------------------|----------------------|
|
||||
| 1 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
- Each **row** is a single note.
|
||||
- Each **column** represents one piece of information about the note.
|
||||
|
||||
---
|
||||
|
||||
## Data types
|
||||
|
||||
Every column has a data type. This describes the kind of value that can be
|
||||
stored there.
|
||||
|
||||
Some common data types:
|
||||
|
||||
```text
|
||||
| Data type | Example value | Meaning |
|
||||
| ----------- | ---------------- | ----------------------------- |
|
||||
| text | Hello world | A string of characters |
|
||||
| integer | 42 | A number without decimals |
|
||||
| boolean | true | Yes/no or on/off values |
|
||||
| timestamptz | 2025-01-10 14:22 | Date and time (with timezone) |
|
||||
| json | {"name": "John"} | A JSON object |
|
||||
```
|
||||
|
||||
Choosing correct types makes your data easier to work with and protects you from
|
||||
unexpected values.
|
||||
|
||||
---
|
||||
|
||||
## Primary keys
|
||||
|
||||
Most tables include a primary key. This is a column that uniquely identifies each
|
||||
row. In many Supabase projects, this column is named `id` and uses a type called
|
||||
`uuid`, which automatically generates a unique value.
|
||||
|
||||
You create this column in the table definition like this:
|
||||
|
||||
```text
|
||||
id uuid primary key default gen_random_uuid()
|
||||
```
|
||||
|
||||
You generally don't need to think about it after setting it up. It simply gives
|
||||
each record a stable identity.
|
||||
|
||||
---
|
||||
|
||||
## Relationships between tables
|
||||
|
||||
You can link tables together using foreign keys. This is how you express things
|
||||
like:
|
||||
|
||||
- A user has many notes
|
||||
- A project has many tasks
|
||||
- A team has many members
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
| id | user_id | content | created_at |
|
||||
|----|--------------------------------------|------------------|----------------------|
|
||||
| 1 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
Here, `user_id` refers to a row in a `users` table. This means the note belongs
|
||||
to that user, and we can see that this user has two notes.
|
||||
|
||||
Relationships let you organize data without repeating information.
|
||||
|
||||
---
|
||||
|
||||
## Why relational data is useful in practice
|
||||
|
||||
Relational data is really useful in practice because it allows you to:
|
||||
|
||||
- Keep data valid with constraints <br />
|
||||
_Example: no duplicate emails._
|
||||
|
||||
- Link records safely with foreign keys <br />
|
||||
_Example: delete a user and their notes in one action._
|
||||
|
||||
- Express real permissions with RLS <br />
|
||||
_Example: users can read their own notes; admins can read all._
|
||||
|
||||
- Query exactly what you need with table joins <br />
|
||||
_Example: fetch notes with the author's email._
|
||||
|
||||
---
|
||||
|
||||
## What we learned
|
||||
|
||||
A database in Supabase is made up of tables.
|
||||
Each table has:
|
||||
|
||||
- columns (which describe the type of information stored)
|
||||
- rows (the individual pieces of data in that table)
|
||||
|
||||
You can relate tables to each other using foreign keys.
|
||||
This lets you model real situations, such as:
|
||||
|
||||
- a user has many notes
|
||||
- a team has many members
|
||||
- a project has many tasks
|
||||
|
||||
Thinking in tables, rows, and relationships is the foundation of working with data in Supabase.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: Data Fundamentals
|
||||
description: 'Learn how data is structured in Postgres: tables, rows, columns, and keys.'
|
||||
chapterNumber: 2
|
||||
---
|
||||
|
||||
Before we store any information in Supabase, we need to understand how data is
|
||||
organized in Postgres. Supabase uses Postgres as its database, which means data
|
||||
is arranged in a structured and predictable way. This helps keep your app
|
||||
organized, consistent, and easy to query.
|
||||
|
||||
The core ideas are simple: you create tables to hold related data, and each
|
||||
table has rows (records) and columns (fields). Once you understand that pattern,
|
||||
you can model almost anything.
|
||||
|
||||
---
|
||||
|
||||
## Tables, rows, and columns
|
||||
|
||||
A table is like a spreadsheet. It has:
|
||||
|
||||
- **Columns**: the fields that define what kind of data the table stores
|
||||
- **Rows**: the individual entries in the table
|
||||
|
||||
Imagine a table for storing notes:
|
||||
|
||||
```text
|
||||
| id | content | created_at |
|
||||
|----|------------------|----------------------|
|
||||
| 1 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
- Each **row** is a single note.
|
||||
- Each **column** represents one piece of information about the note.
|
||||
|
||||
---
|
||||
|
||||
## Data types
|
||||
|
||||
Every column has a data type. This describes the kind of value that can be
|
||||
stored there.
|
||||
|
||||
Some common data types:
|
||||
|
||||
```text
|
||||
| Data type | Example value | Meaning |
|
||||
| ----------- | ---------------- | ----------------------------- |
|
||||
| text | Hello world | A string of characters |
|
||||
| integer | 42 | A number without decimals |
|
||||
| boolean | true | Yes/no or on/off values |
|
||||
| timestamptz | 2025-01-10 14:22 | Date and time (with timezone) |
|
||||
| json | {"name": "John"} | A JSON object |
|
||||
```
|
||||
|
||||
Choosing correct types makes your data easier to work with and protects you from
|
||||
unexpected values.
|
||||
|
||||
---
|
||||
|
||||
## Primary keys
|
||||
|
||||
Most tables include a primary key. This is a column that uniquely identifies each
|
||||
row. In many Supabase projects, this column is named `id` and uses a type called
|
||||
`uuid`, which automatically generates a unique value.
|
||||
|
||||
You create this column in the table definition like this:
|
||||
|
||||
```text
|
||||
id uuid primary key default gen_random_uuid()
|
||||
```
|
||||
|
||||
You generally don't need to think about it after setting it up. It simply gives
|
||||
each record a stable identity.
|
||||
|
||||
---
|
||||
|
||||
## Relationships between tables
|
||||
|
||||
You can link tables together using foreign keys. This is how you express things
|
||||
like:
|
||||
|
||||
- A user has many notes
|
||||
- A project has many tasks
|
||||
- A team has many members
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
| id | user_id | content | created_at |
|
||||
|----|--------------------------------------|------------------|----------------------|
|
||||
| 1 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Buy groceries | 2025-01-10 14:22:11 |
|
||||
| 2 | 9f1b1c94-3e7b-4d6a-9fa7-1e2a3c4ba987 | Call the dentist | 2025-01-10 15:08:54 |
|
||||
```
|
||||
|
||||
Here, `user_id` refers to a row in a `users` table. This means the note belongs
|
||||
to that user, and we can see that this user has two notes.
|
||||
|
||||
Relationships let you organize data without repeating information.
|
||||
|
||||
---
|
||||
|
||||
## Why relational data is useful in practice
|
||||
|
||||
Relational data is really useful in practice because it allows you to:
|
||||
|
||||
- Keep data valid with constraints <br />
|
||||
_Example: no duplicate emails._
|
||||
|
||||
- Link records safely with foreign keys <br />
|
||||
_Example: delete a user and their notes in one action._
|
||||
|
||||
- Express real permissions with RLS <br />
|
||||
_Example: users can read their own notes; admins can read all._
|
||||
|
||||
- Query exactly what you need with table joins <br />
|
||||
_Example: fetch notes with the author's email._
|
||||
|
||||
---
|
||||
|
||||
## What we learned
|
||||
|
||||
A database in Supabase is made up of tables.
|
||||
Each table has:
|
||||
|
||||
- columns (which describe the type of information stored)
|
||||
- rows (the individual pieces of data in that table)
|
||||
|
||||
You can relate tables to each other using foreign keys.
|
||||
This lets you model real situations, such as:
|
||||
|
||||
- a user has many notes
|
||||
- a team has many members
|
||||
- a project has many tasks
|
||||
|
||||
Thinking in tables, rows, and relationships is the foundation of working with data in Supabase.
|
||||
@@ -1,5 +1,5 @@
|
||||
import { allDocs } from 'contentlayer/generated'
|
||||
import { gettingStarted } from '@/config/docs'
|
||||
import { courses } from '@/config/docs'
|
||||
import { SidebarNavItem } from '@/types/nav'
|
||||
|
||||
/**
|
||||
@@ -32,9 +32,11 @@ export function normalizeSlug(slug: string): string {
|
||||
/**
|
||||
* Gets the next page in the navigation structure based on the current page slug
|
||||
*/
|
||||
export function getNextPage(currentSlug: string): { title: string; href: string; description?: string; chapterNumber?: number } | null {
|
||||
export function getNextPage(
|
||||
currentSlug: string
|
||||
): { title: string; href: string; description?: string; chapterNumber?: number } | null {
|
||||
// Flatten all navigation items
|
||||
const allPages = flattenNavItems(gettingStarted.items)
|
||||
const allPages = flattenNavItems(courses.items)
|
||||
|
||||
// Normalize the current slug for comparison
|
||||
const normalizedCurrentSlug = normalizeSlug(currentSlug)
|
||||
@@ -78,4 +80,3 @@ export function getNextPage(currentSlug: string): { title: string; href: string;
|
||||
chapterNumber,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user