04.java/pr2Створити цикл із 8 глибоких, академічних статей у директорії content/04.java/pr2/, що проведе читача від першої ідеї предметної області до готового SQL-скрипта з міграціями Flyway. Наскрізний приклад — платформа аудіокниг (Authors, Audiobooks, Genres, Users, Collections, Listening Progress).
!IMPORTANT
Вимоги до стилю та обсягу:
- Академічний, книжковий стиль — формальний, але живий; текст-перше, код-ілюстрація.
- Кожна стаття ~ 1000–1200 рядків Markdown.
- Писати частинами по ~100 рядків, а не всю статтю одразу. Після кожного блоку — перевірка, корекція, продовження.
- Суворе дотримання
prompt.md(Why Before How, Scaffolding, Text First, Code Anatomy, No Silent Code).- Активне використання Docus-компонентів із
DOCUS_COMPONENTS.md.- Концептуальна модель — технологічно-агностична (не прив'язана до реляційної парадигми).
Файл: content/04.java/pr2/01.conceptual-modeling.md
Обсяг: ~1000–1200 рядків
CREATE TABLE, а з розмови з бізнесом.::mermaid — піраміда трьох рівнів абстракції.::card-group — порівняння: "Одна модель → різні реалізації" (SQL, Document, Graph).Audiobook File залежить від Audiobook.::plant-uml — Chen-нотація: сутності аудіоплатформи (на основі schema.txt).::tip — Практичний критерій: "Якщо можна скласти список екземплярів — це сутність."Author.Name як складений атрибут (FirstName + LastName).::plant-uml — Chen-нотація з атрибутами для 2–3 сутностей.Listening_Progress як зв'язок-з-даними між User та Audiobook.::mermaid — erDiagram (спрощена Crow's Foot) для аудіоплатформи.::tabs — одна й та сама модель у двох нотаціях (Chen через ::plant-uml, Crow's Foot через ::mermaid).::note — "У цьому курсі ми далі використовуватимемо Crow's Foot як найпоширенішу в індустрії."::warning — "На концептуальному рівні це природно, але на реляційному рівні вимагатиме окремих рішень."::steps — завдання 3 рівнів:
Файл: content/04.java/pr2/02.logical-modeling.md
Обсяг: ~1000–1200 рядків
::mermaid — flowchart: Conceptual → Logical → Physical.::note — Математична основа (Codd, 1970) vs практична інтерпретація.::steps — покрокове відображення аудіоплатформи.::plant-uml — логічна схема (на основі PlantUML з schema.txt, секція @startuml).ISBN, email — переваги та ризики.UUID, SERIAL — чому UUID став стандартом для розподілених систем.::tabs — порівняння: Natural Key vs Surrogate Key.::warning — "Задайте собі питання: чи може це значення змінитися? Якщо так — воно не може бути PK."ON DELETE CASCADE vs SET NULL vs RESTRICT — коли що використовувати.audiobooks, коли видаляється author?duration > 0, UNIQUE(username), release_year в допустимому діапазоні.::card-group — три типи цілісності як картки.Файл: content/04.java/pr2/03.normalization.md
Обсяг: ~1000–1200 рядків
::tabs — "До 1НФ" vs "Після 1НФ".audiobook_collection з додатковим полем audiobook_title — порушення. Декомпозиція.::mermaid — схема декомпозиції.audiobooks зберігались author_name і author_bio — це транзитивна залежність через author_id.authors.::note — "На практиці НФБК збігається з 3НФ у 99% випадків."audiobook_count в таблиці collections.::warning — "Денормалізація — це свідомий, задокументований компроміс, а не лінь."::card-group — "Коли нормалізувати" vs "Коли денормалізувати".Файл: content/04.java/pr2/04.physical-schema.md
Обсяг: ~1000–1200 рядків
CREATE TABLE, ALTER TABLE, DROP TABLE.duration INTEGER а не VARCHAR — типізація запобігає помилкам.UUID vs SERIAL/IDENTITY — коли що обирати.ENUM типи: file_format_enum для форматів аудіофайлів.::tabs — порівняння типів даних між H2, SQLite, PostgreSQL (на основі SQL-файлів з temp/pr2/sql).ON DELETE / ON UPDATE.CONSTRAINT genres_name_key UNIQUE (name).CHECK (duration > 0), CHECK (release_year >= 1900 ...).::code-group — DDL для кожної таблиці аудіоплатформи (H2 SQL з ddl_h2.sql).CREATE INDEX audiobooks_author_id_idx ON audiobooks(author_id) — навіщо саме тут.::warning — "Індекс прискорює читання, але уповільнює запис."INSERT INTO — синтаксис з повними прикладами (на основі dml_h2.sql).::code-collapse — повний DML-скрипт аудіоплатформи.::plant-uml — фінальна ER-діаграма (Crow's Foot) з усіма таблицями, ключами, обмеженнями.Файл: content/04.java/pr2/05.table-classification.md
Обсяг: ~1000–1200 рядків
genres — 5–20 записів, задаються адміністратором.::note — "Статичний довідник — це «словник» вашого домену."authors, audiobooks, users — стрижень бізнесу.audiobook_collection — не містить бізнес-даних, лише FK.::mermaid — еволюція таблиці-зв'язки.listening_progress — часто записується, рідко читається цілком.::warning — "Транзакційна таблиця без стратегії архівації — це тикающий годинник."reviews (user_id FK, audiobook_id FK, rating, comment).::card-group або таблиця — всі типи з прикладами аудіоплатформи, частотою зміни, стратегіями кешування/архівації.::mermaid — mindmap або дерево класифікації.Файл: content/04.java/pr2/06.database-migrations.md
Обсяг: ~1000–1200 рядків
rating до audiobooks. Як ви це зробите? Відредагуєте ddl.sql і запустите знову? А що з даними користувачів?"::mermaid — timeline: V1 (initial) → V2 (add rating) → V3 (add reviews table).flyway_schema_history, послідовне виконання.V1__Create_authors_table.sql, V2__Create_genres_table.sql.::code-tree — структура директорії міграцій.ddl_h2.sql на версійовані міграції V1–V8.::steps — покрокове створення кожної міграції.::code-group — кожна міграція як окрема вкладка.V9__Seed_genres.sql).ALTER TABLE audiobooks ADD COLUMN rating DECIMAL(3,1).CREATE TABLE reviews (...).::warning — "Міграція — це append-only лог. НІКОЛИ не редагуйте вже застосовану міграцію."Flyway.configure().dataSource(...).load().migrate().Файл: content/04.java/pr2/07.impedance-mismatch.md
Обсяг: ~1000–1200 рядків
author_id. У Java — це об'єкт Audiobook з полем Author author. Хтось повинен перекласти."Author.Name — це Value Object з firstName + lastName?PremiumUser extends User), реляційна модель — ні. Стратегії: Single Table, Table Per Class, Joined.== vs .equals() vs PK.audiobook.getAuthor()), таблиці — FK (число 550e8400...).user.getCollections().get(0).getAudiobooks(). SQL — JOIN. N+1 проблема.::card-group — картка для кожної розбіжності.::mermaid — паралельне порівняння: Java-об'єкти зліва ↔ SQL-таблиці справа.ResultSet → Java Object: рядок за рядком, rs.getString("first_name").PreparedStatement: параметр за параметром.author_id, зробити ще один SELECT, створити об'єкт.Audiobook з Author всередині.::code-group — маппінг "вручну" vs "з ORM" (без деталей ORM, лише щоб показати біль).01.data-mapper-part1.md).::tabs — порівняння трьох підходів.::note — "Data Mapper — це ручний ORM. Розуміння його роботи — ключ до розуміння Hibernate."Author, Audiobook, Genre з'являться з таблиць, які ми спроектували.01.data-mapper-part1.md.Файл: content/04.java/pr2/08.beyond-relational.md
Обсяг: ~800–1000 рядків (коротша, оглядова)
audiobook.::code-group — JSON документ MongoDB vs SQL-рядки для тієї ж сутності.::warning — "Вбудовування автора в кожну аудіокнигу = денормалізація за замовчуванням."MATCH (u:User)-[:LISTENS_TO]->(a:Audiobook)<-[:WROTE]-(auth:Author) RETURN auth.name.::note — "Помітьте: наша концептуальна модель (сутності + зв'язки) природно відображається в графову."listening_progress як ідеальний кандидат для Redis (гарячі дані з частим оновленням).::card-group або сравнительная таблиця.::mermaid — архітектура Polyglot Persistence для аудіоплатформи..navigation.yml в content/04.java/pr2/title: Проектування баз даних
01., 02. ... всередині pr2/ (не залежно від 04.java).prompt.md.::mermaid, ::plant-uml, ::tabs, ::steps, ::code-group, ::card-group.temp/pr2/sql/.npm run dev) та перевірка рендерингу кожної статті.01.data-mapper-part1.md.Testcontainers: Тестування з реальною PostgreSQL у Docker-контейнерах
Від емуляції до реальності: архітектура Testcontainers, lifecycle Docker-контейнерів у тестах, тестування PostgreSQL-специфічних функцій (ENUM, JSON, full-text search), паралельне виконання тестів та інтеграція з CI/CD.
Введення в теорію баз даних
Історія розвитку баз даних, порівняння моделей зберігання даних та встановлення MS SQL Server