Skip to content

Commit 98dcadd

Browse files
authored
docs: add sdl multi-file format docs (#938)
* docs: add sdl multi-file format docs * chore: update * chore: update docs
1 parent 792cc33 commit 98dcadd

File tree

1 file changed

+173
-31
lines changed

1 file changed

+173
-31
lines changed

mintlify/gitops/state-based-workflow/develop.mdx

Lines changed: 173 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,145 @@ Create SDL files that define your complete database schema in a declarative form
66

77
## Getting Started
88

9-
When starting with state-based workflow:
10-
11-
1. **Export Current Schema** - In Bytebase database detail page, click `Export Schema` to download your current database schema
12-
2. **Organize Schema Files** - Edit and organize the exported schema into manageable files
13-
3. **Commit to Repository** - Add SDL files to version control
14-
4. **Make Changes** - Update the desired state and commit
9+
To use state-based workflow, you must start by exporting your database schema. Bytebase provides a built-in export feature that generates SDL files in the multi-file format, ready to commit to your Git repository.
10+
11+
### Quick Start Workflow
12+
13+
1. **Export** - Click `Export Schema``Multi-File (ZIP)` in Bytebase database detail page
14+
2. **Extract** - Unzip the downloaded file to your Git repository
15+
3. **Verify** - Check the exported structure follows the [multi-file format](#file-organization)
16+
4. **Commit** - Add files to Git and push to your repository
17+
5. **Make Changes** - Edit the SDL files to modify your schema
18+
6. **Deploy** - Commit changes to trigger deployment via GitOps
19+
20+
<Tip>
21+
The exported ZIP contains a complete, ready-to-use schema structure. You can immediately commit it to Git without any manual organization.
22+
</Tip>
23+
24+
### How to Export Schema
25+
26+
1. **Navigate to Database Detail Page** - Go to your database in Bytebase
27+
2. **Click "Export Schema" Button** - Find it in the action buttons at the top
28+
3. **Choose Export Format**:
29+
- **Multi-File (ZIP)** - Recommended for GitOps workflow
30+
- Downloads organized schema as a ZIP file
31+
- Each object in its own file (e.g., `schemas/public/tables/users.sql`)
32+
- Ready to extract and commit to Git
33+
- **Single File** - All objects in one SQL file
34+
- Useful for quick review or legacy workflows
35+
- Requires manual splitting if you want multi-file format
36+
37+
### What Gets Exported
38+
39+
The multi-file export automatically includes:
40+
- **Tables** - With inline indexes, comments, and owned sequences
41+
- **Views** - Regular views with their definitions
42+
- **Materialized Views** - With their indexes and refresh settings
43+
- **Functions & Procedures** - User-defined functions and stored procedures
44+
- **Sequences** - Independent sequences consolidated per schema
45+
- **Comments** - All object and column comments
1546

1647
## File Organization
1748

18-
Organize SDL files by schema or module:
49+
Bytebase uses a **multi-file format** where each database object is stored in a separate file, organized by schema and object type. This structure provides clear organization and makes code reviews easier.
50+
51+
### Directory Structure
1952

2053
```
21-
schema/
22-
├── public.sql # Public schema objects
23-
├── analytics.sql # Analytics schema
24-
└── internal.sql # Internal schema
54+
schemas/
55+
├── public/
56+
│ ├── tables/
57+
│ │ ├── users.sql
58+
│ │ ├── orders.sql
59+
│ │ └── products.sql
60+
│ ├── views/
61+
│ │ ├── active_users.sql
62+
│ │ └── order_summary.sql
63+
│ ├── materialized_views/
64+
│ │ └── sales_summary.sql
65+
│ ├── functions/
66+
│ │ └── get_user_count.sql
67+
│ ├── procedures/
68+
│ │ └── update_user_status.sql
69+
│ └── sequences.sql
70+
├── analytics/
71+
│ ├── tables/
72+
│ │ └── events.sql
73+
│ └── views/
74+
│ └── daily_stats.sql
75+
└── internal/
76+
└── tables/
77+
└── audit_logs.sql
2578
```
2679

27-
Or split by object type:
80+
### Organization Rules
81+
82+
- **One object per file** - Each table, view, function, etc. has its own file
83+
- **Schema-based grouping** - Objects are organized under their schema directory
84+
- **Type-based subdirectories** - Within each schema, objects are grouped by type (`tables/`, `views/`, etc.)
85+
- **Sequences consolidated** - Independent sequences are grouped in a single `sequences.sql` file per schema
86+
- **Related objects bundled** - Table files include their indexes, comments, and owned sequences
87+
88+
### File Naming
89+
90+
Files are named after the database object they define:
91+
- Tables: `schemas/{schema}/tables/{table_name}.sql`
92+
- Views: `schemas/{schema}/views/{view_name}.sql`
93+
- Materialized Views: `schemas/{schema}/materialized_views/{materialized_view_name}.sql`
94+
- Functions: `schemas/{schema}/functions/{function_name}.sql`
95+
- Procedures: `schemas/{schema}/procedures/{procedure_name}.sql`
96+
- Sequences: `schemas/{schema}/sequences.sql` (consolidated)
97+
98+
### Example: Table File Content
99+
100+
A table file includes the table definition and all related objects:
101+
102+
```sql
103+
-- schemas/public/tables/users.sql
28104

105+
CREATE TABLE public.users (
106+
id INTEGER NOT NULL DEFAULT nextval('public.users_id_seq'::regclass),
107+
username TEXT NOT NULL,
108+
email TEXT NOT NULL,
109+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
110+
CONSTRAINT users_pkey PRIMARY KEY (id),
111+
CONSTRAINT users_username_key UNIQUE (username),
112+
CONSTRAINT users_email_key UNIQUE (email)
113+
);
114+
115+
COMMENT ON TABLE public.users IS 'Application users';
116+
COMMENT ON COLUMN public.users.username IS 'Unique username for login';
117+
118+
CREATE INDEX idx_users_email ON public.users(email);
119+
CREATE INDEX idx_users_created_at ON public.users(created_at);
120+
121+
COMMENT ON INDEX idx_users_email IS 'Index for email lookups';
122+
123+
-- Owned sequence
124+
CREATE SEQUENCE public.users_id_seq;
125+
ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id;
29126
```
30-
schema/
31-
├── 01_tables.sql
32-
├── 02_indexes.sql
33-
├── 03_views.sql
34-
├── 04_functions.sql
35-
└── 05_sequences.sql
127+
128+
### Example: Materialized View File Content
129+
130+
Materialized view files include the view definition and its indexes:
131+
132+
```sql
133+
-- schemas/public/materialized_views/sales_summary.sql
134+
135+
CREATE MATERIALIZED VIEW public.sales_summary AS
136+
SELECT
137+
DATE_TRUNC('day', created_at) AS sale_date,
138+
COUNT(*) AS total_orders,
139+
SUM(amount) AS total_amount
140+
FROM public.orders
141+
GROUP BY sale_date;
142+
143+
COMMENT ON MATERIALIZED VIEW public.sales_summary IS 'Daily sales aggregation';
144+
145+
CREATE INDEX idx_sales_summary_date ON public.sales_summary(sale_date);
146+
147+
COMMENT ON INDEX idx_sales_summary_date IS 'Index on sale date for fast lookups';
36148
```
37149

38150
## SDL Syntax Requirements
@@ -163,15 +275,11 @@ SDL files support these PostgreSQL statements:
163275
- `INSERT`, `UPDATE`, `DELETE` (use migration-based workflow)
164276
- Transaction control (`BEGIN`, `COMMIT`)
165277

166-
## Complete SDL Example
167-
168-
```sql
169-
-- schema/public.sql
278+
## Complete Multi-File SDL Example
170279

171-
-- Sequences
172-
CREATE SEQUENCE public.users_id_seq;
280+
### schemas/public/tables/users.sql
173281

174-
-- Tables
282+
```sql
175283
CREATE TABLE public.users (
176284
id INTEGER NOT NULL DEFAULT nextval('public.users_id_seq'::regclass),
177285
username TEXT NOT NULL,
@@ -185,8 +293,21 @@ CREATE TABLE public.users (
185293
CONSTRAINT check_status_values CHECK (status IN ('active', 'inactive', 'suspended'))
186294
);
187295

296+
COMMENT ON TABLE public.users IS 'Application users';
297+
COMMENT ON COLUMN public.users.email IS 'User email address (unique)';
298+
299+
CREATE INDEX idx_users_email ON public.users(email);
300+
CREATE INDEX idx_users_created_at ON public.users(created_at);
301+
CREATE INDEX idx_users_status ON public.users(status) WHERE status != 'inactive';
302+
303+
-- Owned sequence for id column
304+
CREATE SEQUENCE public.users_id_seq;
188305
ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id;
306+
```
307+
308+
### schemas/public/tables/user_profiles.sql
189309

310+
```sql
190311
CREATE TABLE public.user_profiles (
191312
user_id INTEGER NOT NULL,
192313
bio TEXT,
@@ -195,24 +316,45 @@ CREATE TABLE public.user_profiles (
195316
CONSTRAINT fk_user_profiles_users FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE
196317
);
197318

198-
-- Indexes
199-
CREATE INDEX idx_users_email ON public.users(email);
200-
CREATE INDEX idx_users_created_at ON public.users(created_at);
201-
CREATE INDEX idx_users_status ON public.users(status) WHERE status != 'inactive';
319+
COMMENT ON TABLE public.user_profiles IS 'Extended user profile information';
320+
```
202321

203-
-- Views
322+
### schemas/public/views/active_users.sql
323+
324+
```sql
204325
CREATE VIEW public.active_users AS
205326
SELECT id, username, email, created_at
206327
FROM public.users
207328
WHERE status = 'active';
208329

209-
-- Functions
330+
COMMENT ON VIEW public.active_users IS 'View of all active users';
331+
```
332+
333+
### schemas/public/functions/get_user_count.sql
334+
335+
```sql
210336
CREATE FUNCTION public.get_user_count()
211337
RETURNS INTEGER
212338
LANGUAGE sql
213339
AS $$
214340
SELECT COUNT(*) FROM public.users;
215341
$$;
342+
343+
COMMENT ON FUNCTION public.get_user_count() IS 'Returns total count of users';
344+
```
345+
346+
### schemas/public/sequences.sql
347+
348+
```sql
349+
-- Independent sequences (not owned by any table column)
350+
CREATE SEQUENCE public.custom_id_seq
351+
START WITH 1000
352+
INCREMENT BY 1
353+
NO MINVALUE
354+
NO MAXVALUE
355+
CACHE 1;
356+
357+
COMMENT ON SEQUENCE public.custom_id_seq IS 'Custom sequence for special IDs';
216358
```
217359

218360
---

0 commit comments

Comments
 (0)