Схема БД и миграции
Relevant source files
The following files were used as context for generating this wiki page:
Система управления базами данных в проекте Music Service построена на использовании PostgreSQL 16. Структура БД обеспечивает хранение данных пользователей, механизмов аутентификации, музыкального каталога и пользовательского контента (плейлисты, избранное, история). Управление изменениями схемы осуществляется через SQL-миграции с использованием инструмента goose.
Источники: README.md, migrations/001_init.up.sql:1-85
Структура сущностей и связи
База данных состоит из 10 основных таблиц, связанных между собой внешними ключами с различными правилами удаления (CASCADE, SET NULL).
Ниже представлена диаграмма сущность-связь (ERD), описывающая структуру таблиц и их отношения:
Диаграмма отображает центральные сущности системы: пользователей и треки, а также вспомогательные таблицы для организации метаданных и пользовательского опыта.
Источники: migrations/001_init.up.sql:1-85
Пользователи и Аутентификация
Таблица users хранит основные данные профиля, включая роль (USER, ADMIN) и тип подписки (FREE, PREMIUM). Для управления сессиями используется таблица refresh_tokens.
| Поле | Тип | Описание |
|---|---|---|
id | BIGSERIAL | Первичный ключ |
email | VARCHAR(255) | Уникальный email, используется для входа |
role | VARCHAR(50) | Роль пользователя (default: 'USER') |
subscription_type | VARCHAR(50) | Тип подписки (default: 'FREE') |
Источники: migrations/001_init.up.sql:1-19, internal/features/users/repository/postgres/user_repository.go:27-33
Музыкальный каталог
Каталог разделен на артистов, альбомы, жанры и непосредственно треки. Таблица tracks является связующим звеном, ссылаясь на все три справочника.
- artists: Содержит уникальные имена исполнителей.
- albums: Связаны с артистами связью "многие к одному".
- genres: Уникальные названия музыкальных жанров.
- tracks: Основная сущность с метаданными и ссылкой на файл (
file_url).
Источники: migrations/001_init.up.sql:21-54
Процесс миграций
Миграции в проекте разделены на этапы инициализации схемы и наполнения данными (seeding).
Инициализация (001_init)
Создает базовую структуру таблиц и индексы для оптимизации запросов.
- Индексы: Создан композитный индекс
idx_listening_history_user_listened_atна таблицуlistening_historyпо полям(user_id, listened_at DESC)для быстрого получения истории последних прослушиваний пользователя. - Откат: Файл
001_init.down.sqlсодержит командыDROP TABLEдля всех созданных сущностей в порядке, обратном их созданию, чтобы избежать конфликтов внешних ключей.
Источники: migrations/001_init.up.sql:82-84, migrations/001_init.down.sql:1-12
Наполнение данными (002_seed, 003_rich_seed)
Для удобства разработки предусмотрены скрипты первичного наполнения каталога.
- 002_seed: Базовый набор (Eminem, Linkin Park, Michael Jackson).
- 003_rich_seed: Расширенный набор, включающий более 30 треков различных жанров (Electronic, Classical, Metal).
- Сброс последовательностей: После вставки данных с фиксированными ID выполняется обновление счетчиков
SERIAL, чтобы избежать конфликтов при создании новых записей через приложение.
SELECT setval('genres_id_seq', (SELECT MAX(id) FROM genres));
SELECT setval('tracks_id_seq', (SELECT MAX(id) FROM tracks));
Источники: migrations/002_seed.up.sql:1-35, migrations/003_rich_seed.up.sql:1-74
Взаимодействие с БД из кода
Проект использует библиотеку sqlx для работы с PostgreSQL. Репозитории (UserRepository, TrackRepository) инкапсулируют SQL-запросы.
Пример реализации репозитория
Код репозитория использует именованные параметры и маппинг структур через StructScan. При обновлении профиля или создании трека используются транзакционные или атомарные запросы.
func (r *TrackRepository) GetByID(ctx context.Context, id int64) (*model.Track, error) {
query := `
SELECT t.id, t.title, art.name AS artist_name, alb.title AS album_title
FROM tracks t
JOIN artists art ON t.artist_id = art.id
LEFT JOIN albums alb ON t.album_id = alb.id
WHERE t.id = $1
`
// ... логика выполнения запроса
}
Источники: internal/features/tracks/repository/postgres/track_repository.go:68-83, internal/features/users/repository/postgres/user_repository.go:19-24
Резюме
Схема БД спроектирована с учетом требований к целостности данных (внешние ключи, уникальные индексы) и производительности (индексы на историю прослушиваний). Система миграций позволяет быстро развернуть окружение с предзаполненным музыкальным каталогом, что упрощает разработку и тестирование.