Proper file organization is crucial for maintainable GitOps workflows. This guide covers repository structures and directory layouts that scale with your team.
Repository Structure
Monorepo Approach
Database migrations alongside application code:
my-app/
├── src/ # Application code
├── migrations/ # Database migrations
│ ├── versioned/
│ │ ├── 001__init.sql
│ │ └── 002__add_users.sql
│ └── schema/
│ └── public.sql # SDL if using declarative
├── .github/workflows/
│ └── bytebase-gitops.yml # CI/CD integration
└── README.md
Benefits:
Migrations versioned with application code
Atomic commits for schema + code changes
Single source of truth
Best for:
Small to medium teams
Tight schema-code coupling
Monolithic or modular monolith architectures
Separate Repository
Dedicated database repository:
database-schemas/
├── app-db/
│ ├── migrations/
│ └── schema/
├── analytics-db/
│ └── migrations/
└── .gitlab-ci.yml
Benefits:
Separation of concerns
Independent deployment cycles
Multiple teams/databases
Best for:
Larger organizations
Dedicated database teams
Microservices with shared databases
Choose based on your team structure. Co-located migrations work well for small teams with tight schema-code coupling. Separate repos fit larger organizations with dedicated database teams.
Directory Layout
For Migration-Based Workflow
Option 1: Organized by Category
migrations/
├── baseline/
│ └── 000__initial_schema.sql # Initial baseline
├── features/
│ ├── 001__users.sql
│ ├── 002__products.sql
│ └── 003__orders.sql
└── hotfixes/
└── 004__fix_index.sql
Benefits:
Clear organization by purpose
Easy to navigate
Separates routine changes from emergencies
Option 2: Flat Structure
migrations/
├── 001__initial_schema.sql
├── 002__add_users.sql
├── 003__add_products_dml.sql
└── 004__add_indexes.sql
Benefits:
Simple and straightforward
Chronological ordering
Easy to understand
For State-Based Workflow (SDL)
Option 1: Organized by Schema
schema/
├── public.sql # Main schema
├── analytics.sql # Analytics schema
└── internal.sql # Internal schema
Benefits:
Clear schema separation
Matches database structure
Easy to find objects
Option 2: Split by Object Type
schema/
├── 01_tables.sql
├── 02_indexes.sql
├── 03_views.sql
├── 04_functions.sql
└── 05_sequences.sql
Benefits:
Organized by DDL type
Predictable file structure
Clear dependencies (tables before indexes)
Hybrid Approach
Combine both workflows for different purposes:
database/
├── schema/ # SDL for structure (DDL)
│ ├── public.sql
│ └── analytics.sql
├── migrations/ # Migrations for data (DML)
│ ├── 001__seed_roles_dml.sql
│ └── 002__migrate_users_dml.sql
└── .github/workflows/
├── schema-cicd.yml # SDL pipeline
└── data-cicd.yml # Migration pipeline
Best for:
Teams wanting declarative schema management
Projects requiring data migrations
Gradual migration from versioned to SDL
Documentation Structure
Maintain supporting documentation alongside migrations:
database/
├── migrations/
├── schema/
├── docs/
│ ├── CHANGELOG.md # Schema changelog
│ ├── DEPENDENCIES.md # Schema-app dependencies
│ └── ROLLBACK_PLAN.md # Rollback procedures
└── test-data/
└── seed.sql # Test data for development
Next Steps
Migration Guidelines Learn version numbering and file best practices
Git and CI/CD Set up branching strategies and pipelines