🎯 Cele lekcji

🔍

1. Analiza istniejącej struktury

Przed rozbudową bazy zawsze sprawdź aktualny stan schematu. Używaj poniższych poleceń:

-- Lista tabel w bieżącej bazie
SHOW TABLES;

-- Struktura konkretnej tabeli
DESCRIBE produkty;
-- lub skrót:
DESC produkty;

-- Pełna definicja tabeli (z FK, indeksami)
SHOW CREATE TABLE produkty\G

-- Lista kolumn z metadanymi
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, EXTRA
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'sklep' AND TABLE_NAME = 'produkty';

-- Wszystkie klucze obce w bazie
SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = 'sklep' AND REFERENCED_TABLE_NAME IS NOT NULL;
Zawsze analizuj relacje i zależności przed modyfikacją. Nierozważna zmiana może naruszyć integralność danych.
🏗️

2. Dodawanie nowych tabel i relacji

Przykładowy scenariusz: do istniejącej bazy sklepu (tabele: klienci, produkty, zamowienia) chcemy dodać system recenzji produktów i program lojalnościowy.

Krok 1 – Nowe tabele bez zależności (lub z już istniejącymi FK)

-- Tabela recenzji (odwołuje się do klientów i produktów)
CREATE TABLE IF NOT EXISTS recenzje (
  id_recenzji  INT           AUTO_INCREMENT PRIMARY KEY,
  id_klienta   INT           NOT NULL,
  id_produktu  INT           NOT NULL,
  ocena        TINYINT       NOT NULL,    -- 1–5
  tresc        TEXT,
  data_dodania TIMESTAMP     DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_rec_klient  FOREIGN KEY (id_klienta)
    REFERENCES klienci(id_klienta) ON DELETE CASCADE,
  CONSTRAINT fk_rec_produkt FOREIGN KEY (id_produktu)
    REFERENCES produkty(id_produktu) ON DELETE CASCADE,
  CONSTRAINT chk_ocena CHECK (ocena BETWEEN 1 AND 5)
);

Krok 2 – Dodaj kolumny do istniejących tabel

-- Dodaj punkty lojalnościowe do klientów
ALTER TABLE klienci
  ADD COLUMN punkty_lojal  INT UNSIGNED NOT NULL DEFAULT 0,
  ADD COLUMN poziom_klienta ENUM('brązowy','srebrny','złoty') DEFAULT 'brązowy';

-- Dodaj ocenę średnią jako kolumnę wyliczaną (MySQL 5.7+)
ALTER TABLE produkty
  ADD COLUMN srednia_ocena DECIMAL(3,2) DEFAULT NULL;

Krok 3 – Dodaj indeksy dla wydajności

CREATE INDEX idx_recenzje_produkt ON recenzje(id_produktu);
CREATE INDEX idx_recenzje_klient  ON recenzje(id_klienta);
-- Indeks unikalny: jeden klient = jedna recenzja produktu
CREATE UNIQUE INDEX idx_rec_unik ON recenzje(id_klienta, id_produktu);
🔄

3. Migracja danych przy zmianie struktury

Czasem zmiana schematu wymaga przeniesienia lub przekształcenia istniejących danych.

Scenariusz: Split tabeli (podział kolumny adresu)

-- PRZED: klienci mają kolumnę adres (cały adres w jednym polu)
-- CEL: rozbić na ulica, miasto, kod_pocztowy

-- 1. Dodaj nowe kolumny
ALTER TABLE klienci
  ADD COLUMN ulica       VARCHAR(150) NULL AFTER adres,
  ADD COLUMN miasto      VARCHAR(80)  NULL AFTER ulica,
  ADD COLUMN kod_pocztowy CHAR(6)     NULL AFTER miasto;

-- 2. Przepisz dane (przykład uproszczony)
UPDATE klienci
SET
  ulica        = SUBSTRING_INDEX(adres, ',', 1),
  miasto       = TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(adres,',',2),',',-1)),
  kod_pocztowy = TRIM(SUBSTRING_INDEX(adres, ',', -1));

-- 3. Zweryfikuj dane
SELECT adres, ulica, miasto, kod_pocztowy FROM klienci LIMIT 5;

-- 4. Dopiero gdy pewny, usuń starą kolumnę
ALTER TABLE klienci DROP COLUMN adres;
Nigdy nie usuwaj starych kolumn przed zweryfikowaniem poprawności migracji. Zrób backup przed każdą migracją!

Weryfikacja po rozbudowie

-- Sprawdź integralność FK
SELECT r.id_recenzji
FROM recenzje r
LEFT JOIN klienci k ON r.id_klienta = k.id_klienta
WHERE k.id_klienta IS NULL;   -- powinno zwrócić 0 wierszy

-- Sprawdź nowe kolumny
SELECT COUNT(*) FROM klienci WHERE punkty_lojal IS NULL;

-- Statystyki tabel
SELECT TABLE_NAME, TABLE_ROWS, DATA_LENGTH/1024 AS KB
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'sklep';
✏️

Zadania interaktywne

Zadanie 1 Kolejność kroków migracji

Zaznacz poprawną kolejność kroków bezpiecznej migracji schematu:

  • 1. Usuń starą kolumnę → 2. Dodaj nową kolumnę → 3. Przepisz dane → 4. Zweryfikuj
  • 1. Backup bazy → 2. Dodaj nową kolumnę → 3. Przepisz/migruj dane → 4. Zweryfikuj → 5. Usuń starą kolumnę
  • 1. Dodaj nową kolumnę → 2. Usuń starą → 3. Backup → 4. Przepisz dane
  • 1. Przepisz dane → 2. Zweryfikuj → 3. Backup → 4. Usuń kolumnę
Zadanie 2 Dopasuj polecenie do celu

Dopasuj polecenie SQL do jego zastosowania:

DESCRIBE tabela
SHOW CREATE TABLE
INFORMATION_SCHEMA
ALTER TABLE … ADD COLUMN
Zadanie 3 Napisz ALTER TABLE z relacją

Do istniejącej tabeli pracownicy dodaj:

  • Kolumnę id_dzialu (INT, dopuszczalna NULL)
  • Klucz obcy łączący ją z tabelą dzialy (kolumna id_dzialu)
  • Przy usunięciu działu ustaw NULL w tej kolumnie
Zadanie 4 Quiz — weryfikacja po rozbudowie

Po dodaniu kolumny NOT NULL do tabeli z istniejącymi danymi, operacja może się nie powieść. Dlaczego?

  • MySQL nie obsługuje dodawania kolumn do niepustych tabel
  • Istniejące wiersze nie mają wartości dla nowej kolumny — naruszenie NOT NULL. Należy podać DEFAULT lub dodać jako NULL i później uzupełnić.
  • Kolumna NOT NULL może być dodana tylko przy tworzeniu tabeli
  • Trzeba najpierw usunąć wszystkie rekordy

📌 Zapamiętaj