> Спроектируй базу данных для электронной библиотеки с таблицами авторов, книг и читателей, опиши связи, индексы и ограничения (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: Ozon

Стек: Go

> Пример ответа

Схема базы данных

SQL
-- Таблица авторов
CREATE TABLE authors (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
bio TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- Таблица книг
CREATE TABLE books (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
isbn VARCHAR(13) UNIQUE NOT NULL,
publication_year SMALLINT CHECK (publication_year > 0),
author_id INTEGER NOT NULL REFERENCES authors(id) ON DELETE CASCADE,
created_at TIMESTAMP DEFAULT NOW()
);
-- Таблица читателей
CREATE TABLE readers (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
registered_at TIMESTAMP DEFAULT NOW()
);
-- Таблица выдачи (связь многие-ко-многим)
CREATE TABLE loans (
id SERIAL PRIMARY KEY,
book_id INTEGER NOT NULL REFERENCES books(id) ON DELETE CASCADE,
reader_id INTEGER NOT NULL REFERENCES readers(id) ON DELETE CASCADE,
borrowed_at TIMESTAMP DEFAULT NOW(),
returned_at TIMESTAMP,
CONSTRAINT chk_return_date CHECK (returned_at IS NULL OR returned_at >= borrowed_at)
);

Связи

  • authorsbooks: один автор может написать много книг (1:N), внешний ключ author_id.

  • booksloans: одна книга может быть выдана много раз (1:N).

  • readersloans: один читатель может взять много книг (1:N).

  • Между books и readers реализована связь многие-ко-многим через таблицу loans.

Индексы

SQL
-- Для быстрого поиска книг по автору
CREATE INDEX idx_books_author_id ON books(author_id);
-- Для поиска книг по ISBN (уникальность уже обеспечена, индекс создаётся автоматически)
-- Для поиска читателей по email (автоматически при UNIQUE)
-- Для поиска активных выдач (книга не возвращена)
CREATE INDEX idx_loans_active ON loans(book_id) WHERE returned_at IS NULL;
-- Для поиска всех выдач читателя
CREATE INDEX idx_loans_reader_id ON loans(reader_id);

Ограничения

  • NOT NULL на обязательные поля (имя автора, название книги, email читателя).

  • UNIQUE на isbn (каждая книга имеет уникальный ISBN) и email (уникальность читателей).

  • CHECK на publication_year (год > 0) и на дату возврата (не раньше даты выдачи).

  • Внешние ключи с ON DELETE CASCADE - при удалении автора удаляются его книги, при удалении книги или читателя - соответствующие записи в loans.

Go-структуры (пример)

GO
type Author struct {
ID int `json:"id"`
Name string `json:"name"`
Bio string `json:"bio,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
type Book struct {
ID int `json:"id"`
Title string `json:"title"`
ISBN string `json:"isbn"`
PublicationYear int `json:"publication_year"`
AuthorID int `json:"author_id"`
CreatedAt time.Time `json:"created_at"`
}
type Reader struct {
ID int `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
RegisteredAt time.Time `json:"registered_at"`
}
type Loan struct {
ID int `json:"id"`
BookID int `json:"book_id"`
ReaderID int `json:"reader_id"`
BorrowedAt time.Time `json:"borrowed_at"`
ReturnedAt *time.Time `json:"returned_at,omitempty"`
}

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью