> Как описать схему базы данных для модели библиотеки с сущностями автор, книга, читатель и связями между ними (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Ozon
Стек: Go
> Пример ответа
Короткий ответ
Схема библиотеки описывается через три основные сущности: авторы, книги и читатели. Связи: многие-ко-многим между авторами и книгами (через junction table), многие-ко-многим между книгами и читателями (через таблицу выдач с датами). В Go это отражается в структурах с foreign key и слайсами для связей. Основной trade-off - выбор между нормализацией и простотой запросов, а также решение о хранении истории выдач.
Подробное объяснение
Для модели библиотеки стандартная схема включает:
- authors - id, name, bio
- books - id, title, year, isbn
- book_authors - junction table: book_id, author_id (many-to-many)
- readers - id, name, email
- loans - id, book_id, reader_id, loan_date, return_date (nullable)
Связь "книга-автор" - классический many-to-many, потому что одна книга может иметь несколько авторов, и один автор пишет много книг. Связь "книга-читатель" - тоже many-to-many, но с дополнительной семантикой: loan_date и return_date делают её исторической. Если нужна только текущая выдача, можно хранить book_id в readers как active_loan, но это нарушает нормализацию и теряет историю.
В Go структуры выглядят так:
GOtype Author struct {ID int64Name stringBooks []Book // через join}type Book struct {ID int64Title stringAuthors []Author}type Reader struct {ID int64Name stringLoans []Loan}type Loan struct {ID int64BookID int64ReaderID int64LoanDate time.TimeReturnDate *time.Time}
Ключевой момент - индексы. Для loans обязателен индекс по reader_id и book_id, иначе запросы "какие книги у читателя" будут full scan. Для book_authors - составной индекс (book_id, author_id).
На практике
При реализации на Go с PostgreSQL:
- Используйте
sqlxилиpgxдля работы с БД. - Миграции - через
golang-migrateилиgoose. - Для many-to-many запросов используйте JOIN или отдельные запросы с последующей сборкой в Go (N+1 проблема решается через
INилиJOINс агрегацией). - Для loans решите: хранить только активные или всю историю. Если историю - добавьте
return_dateи фильтруйтеWHERE return_date IS NULLдля активных. - Подумайте о soft delete для книг, если библиотека списывает экземпляры.
Пример запроса "все книги автора":
SQLSELECT b.* FROM books bJOIN book_authors ba ON ba.book_id = b.idWHERE ba.author_id = $1;
Как отвечать на собеседовании
Начните с трёх таблиц и двух junction tables. Объясните, почему many-to-many, а не foreign key напрямую. Затем перейдите к loans - здесь важно показать понимание разницы между текущим состоянием и историей. Упомяните индексы и типичные запросы. Если спросят про нормализацию - скажите, что схема в 3NF, но для частых запросов можно добавить денормализованные поля (например, book_count у автора) при доказанной необходимости. В конце спросите про требования: нужна ли история выдач, сколько данных, какие запросы критичны.
Что проверяет интервьюер
- Понимание отношений между сущностями (1:1, 1:N, M:N).
- Умение проектировать junction tables.
- Осознание trade-off между нормализацией и производительностью.
- Знание, как это ложится на Go-структуры и SQL-запросы.
- Способность обсуждать индексы и типичные проблемы (N+1, full scan).
Типичные ошибки
- Прямой foreign key book_id в readers - теряется история, нарушается many-to-many.
- Отсутствие junction table для авторов - если книга с двумя авторами, придётся дублировать строки.
- Не учитывать nullable return_date - без него нельзя отличить активную выдачу от завершённой.
- Забывать про индексы на внешние ключи - на больших данных запросы деградируют.
- Хранить даты как строки - в Go и PostgreSQL это должно быть
time.Timeиtimestamp.
> Похожие задачи по Go
Какие алгоритмы балансировки существуют
Какую архитектуру и технологии использовать для реализации клиента чата с REST API?
Какие сигналы существуют в операционной системе
Происходит ли копирование данных при передаче слайса и массива в функцию в Go
> Похожие задачи по backend
С какими типами данных чаще всего работали: списки, словари, массивы
Какую архитектуру и технологии использовать для реализации клиента чата с REST API?
Какие сигналы существуют в операционной системе
Происходит ли копирование данных при передаче слайса и массива в функцию в Go
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью