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;
Przykładowy scenariusz: do istniejącej bazy sklepu (tabele: klienci, produkty, zamowienia) chcemy dodać system recenzji produktów i program lojalnościowy.
-- 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) );
-- 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;
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);
Czasem zmiana schematu wymaga przeniesienia lub przekształcenia istniejących danych.
-- 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;
-- 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';
Zaznacz poprawną kolejność kroków bezpiecznej migracji schematu:
Dopasuj polecenie SQL do jego zastosowania:
DESCRIBE tabelaSHOW CREATE TABLEINFORMATION_SCHEMAALTER TABLE … ADD COLUMNDo istniejącej tabeli pracownicy dodaj:
id_dzialu (INT, dopuszczalna NULL)dzialy (kolumna id_dzialu)ALTER TABLE pracownicy ADD COLUMN id_dzialu INT NULL, ADD CONSTRAINT fk_prac_dzial FOREIGN KEY (id_dzialu) REFERENCES dzialy(id_dzialu) ON DELETE SET NULL ON UPDATE CASCADE;
Po dodaniu kolumny NOT NULL do tabeli z istniejącymi danymi, operacja może się nie powieść. Dlaczego?
DESCRIBE / SHOW CREATE TABLE — analiza struktury tabeliINFORMATION_SCHEMA — słownik danych, metainformacje o bazieNOT NULL do tabeli z danymi — zawsze podaj DEFAULT