1/36MariaDB od podstaw – tutorial dla początkujących

Kompleksowy przewodnik: od instalacji do pierwszych zapytań SQL

Zakładamy zerowy poziom wiedzy – zaczniemy od uruchomienia MariaDB, a skończymy na zaawansowanych zapytaniach SQL.

Czego się nauczysz?

  • Instalacji i uruchamiania MariaDB
  • Logowania i podstawowej konfiguracji
  • Tworzenia baz danych i tabel (ręcznie)
  • Wgrywania plików SQL
  • Przeglądania struktury bazy
  • Poleceń SQL: INSERT, SELECT, UPDATE, DELETE
  • Łączenia tabel (JOIN), grupowania, indeksów
Nie potrzebujesz żadnego doświadczenia – wszystko wyjaśniamy krok po kroku.
Logo MariaDB + napis

Witamy w kompleksowym tutorialu MariaDB przeznaczonym dla osób, które nigdy wcześniej nie miały styczności z bazami danych. Celem tej prezentacji jest przeprowadzenie Cię przez wszystkie etapy pracy z systemem MariaDB – od fizycznej instalacji oprogramowania, przez konfigurację środowiska, aż po samodzielne formułowanie zapytań SQL różnego typu.

Prezentacja ma charakter wyłącznie praktyczny. Każde polecenie jest opatrzone przykładem, który możesz samodzielnie uruchomić. Zachęcamy do aktywnego śledzenia materiału i wykonywania wszystkich ćwiczeń na własnym komputerze – tylko praktyka pozwoli Ci trwale opanować umiejętność pracy z bazami danych. W trakcie 36 slajdów zbudujesz solidne fundamenty, które otworzą Ci drogę do bardziej zaawansowanych tematów, takich jak normalizacja, optymalizacja zapytań czy administracja serwerem.

2/36Czym jest MariaDB?

Relacyjny system zarządzania bazą danych (RDBMS)

MariaDB to darmowy, otwartoźródłowy system zarządzania relacyjną bazą danych. Powstał jako rozwidlenie (fork) MySQL-a w 2009 roku, gdy istniały obawy o przyszłość MySQL-a po przejęciu przez Oracle.

Najważniejsze cechy:

  • Open-source – całkowicie darmowy, bez ukrytych opłat
  • Relacyjny – dane przechowywane w tabelach powiązanych kluczami
  • MariaDB – komunikacja za pomocą języka SQL
  • Wieloplatformowy – działa na Windows, Linux, macOS
  • Zgodny z MySQL – narzędzia i skrypty MySQL działają bez zmian
MariaDB jest używana przez Wikipedię, Google, Mozillę i tysiące firm na całym świecie.
Loga firm używających MariaDB – Wikipedia, Google, Mozilla

MariaDB jest rozwijana przez fundację MariaDB Foundation i społeczność open-source. Pełna kompatybilność z MySQL oznacza, że możesz korzystać z większości narzędzi, dokumentacji i bibliotek napisanych dla MySQL-a. Jednocześnie MariaDB wprowadza własne usprawnienia, takie jak dodatkowe silniki składowania (Aria, ColumnStore), ulepszony optymalizator zapytań oraz rozszerzenia składni SQL, które nie są dostępne w MySQL-u.

W środowisku akademickim i edukacyjnym MariaDB jest szczególnie polecana ze względu na prostotę instalacji, niskie wymagania sprzętowe oraz bogatą dokumentację. Jeśli dopiero zaczynasz przygodę z bazami danych, MariaDB będzie doskonałym wyborem – pozwoli Ci skupić się na nauce koncepcji, zamiast na walce z konfiguracją.

3/36Instalacja MariaDB

MariaDB na różnych systemach operacyjnych

Linux (Ubuntu/Debian):

# Aktualizacja repozytoriów i instalacja
sudo apt update
sudo apt install mariadb-server mariadb-client -y

Linux (Fedora/RHEL):

sudo dnf install mariadb-server mariadb -y

Windows:

Pobierz installer ze strony mariadb.org/download i uruchom. W trakcie instalacji ustaw hasło dla użytkownika root.

macOS (Homebrew):

brew install mariadb
Po instalacji w systemie Linux musisz ręcznie uruchomić serwer – pokażemy jak w następnym slajdzie.
Zrzuty ekranu instalacji na Ubuntu, Windows i macOS

Niezależnie od wybranego systemu operacyjnego, proces instalacji MariaDB jest prosty i dobrze udokumentowany. Na systemach Linux najwygodniej skorzystać z menedżera pakietów dystrybucji – pakiety mariadb-server i mariadb-client zawierają odpowiednio serwer bazodanowy oraz klient konsolowy mysql. Na Windows dostępny jest instalator MSI, który przeprowadzi Cię przez cały proces krok po kroku, oferując dodatkowe opcje, takie jak instalacja HeidiSQL (graficznego klienta).

Po udanej instalacji warto sprawdzić, czy serwer został poprawnie zainstalowany i uruchomiony. W kolejnych slajdach pokażemy, jak uruchomić serwer, połączyć się z nim za pomocą konsoli oraz wykonać podstawowe polecenia konfiguracyjne. Pamiętaj, że do pracy z bazami danych potrzebujesz uruchomionego serwera – sama instalacja klienta nie wystarczy.

4/36Uruchamianie serwera MariaDB

Jak uruchomić, zatrzymać i sprawdzić status serwera

Po instalacji serwer MariaDB nie uruchamia się automatycznie (w systemie Linux). Musisz zrobić to ręcznie.

Systemd (większość dystrybucji Linux):

# Uruchomienie serwera
sudo systemctl start mariadb

# Włączenie autostartu (serwer startuje przy bootowaniu)
sudo systemctl enable mariadb

# Sprawdzenie statusu
sudo systemctl status mariadb

# Zatrzymanie serwera
sudo systemctl stop mariadb

# Restart serwera
sudo systemctl restart mariadb

Windows:

Serwer uruchamia się automatycznie jako usługa Windows. Możesz zarządzać nią przez Services.msc lub panel sterowania MariaDB.

Zawsze sprawdzaj status komendą 'systemctl status mariadb' – jeśli widzisz "active (running)", serwer działa.
Zrzut ekranu z konsoli pokazujący wynik komendy systemctl status mariadb

Na systemach Linux serwer MariaDB jest zarządzany przez systemd – nowoczesny system inicjalizacji używany w większości dystrybucji. Polecenia systemctl pozwalają na wygodne zarządzanie serwerem: uruchamianie, zatrzymywanie, restart oraz sprawdzanie statusu. Po instalacji warto od razu włączyć autostart (enable), aby serwer uruchamiał się automatycznie przy starcie systemu.

Jeśli podczas sprawdzania statusu zobaczysz błąd "Failed to start mariadb.service: Unit not found", oznacza to, że serwer nie został poprawnie zainstalowany – spróbuj ponownie wykonać instalację. Na Windows serwer MariaDB jest domyślnie instalowany jako usługa z automatycznym uruchamianiem, więc po instalacji od razu możesz przystąpić do logowania.

5/36Logowanie do MariaDB przez konsolę

Polecenie mysql – Twoje okno na świat baz danych

Aby połączyć się z serwerem MariaDB, użyj programu mysql (klient konsolowy).

Podstawowe logowanie:

-- Logowanie jako root (z hasłem)
mysql -u root -p

-- Po naciśnięciu Enter wpisz hasło (kursor się nie porusza – to normalne)
-- Po zalogowaniu widzisz:
MariaDB [(none)]>

Logowanie z wybraną bazą:

-- Logowanie i od razu wybór bazy 'biblioteka'
mysql -u root -p biblioteka

Wylogowanie:

EXIT;
-- lub
QUIT;
Puste hasło? Dla bezpieczeństwa zawsze ustaw hasło (slajd 6).
Zrzut konsoli – proces logowania mysql -u root -p z widocznym monitem MariaDB [(none)>]

Program mysql jest tekstowym klientem MariaDB/MySQL. Po uruchomieniu bez żadnych parametrów mysql próbuje zalogować się jako bieżący użytkownik systemowy na lokalnym serwerze. Flaga -u określa nazwę użytkownika (domyślnie: root), a -p wymusza pytanie o hasło. Jeśli Twoje konto nie ma hasła, możesz pominąć -p, ale jest to niezalecane ze względów bezpieczeństwa.

Po zalogowaniu widzisz znak zachęty (prompt): MariaDB [(none)]>. (none) oznacza, że nie wybrałeś jeszcze żadnej bazy danych – aby to zrobić, użyj polecenia USE. W konsoli każde polecenie SQL musi kończyć się średnikiem (;) – dopiero wtedy zostanie wysłane do serwera. Jeśli zapomnisz o średniku, konsola przejdzie do nowej linii i będzie czekać na kontynuację.

6/36Pierwsze logowanie – zabezpieczenie konta root

mysql_secure_installation – skrypt bezpieczeństwa

Po pierwszym uruchomieniu MariaDB natychmiast zabezpiecz konto root. MariaDB dostarcza do tego skrypt mysql_secure_installation.

# Uruchom skrypt (będziesz na bieżąco wybierać opcje)
sudo mysql_secure_installation

Co robi skrypt krok po kroku:

  1. Ustawia hasło dla użytkownika root
  2. Usuwa anonimowych użytkowników
  3. Wyłącza zdalne logowanie roota
  4. Usuwa testową bazę danych 'test'
  5. Przeładowuje uprawnienia
Zawsze uruchamiaj ten skrypt po instalacji! Inaczej Twoja baza jest otwarta dla każdego.
Zrzut konsoli z przebiegiem skryptu mysql_secure_installation

Skrypt mysql_secure_installation to niezbędne narzędzie do zabezpieczenia świeżo zainstalowanej instancji MariaDB. Domyślnie MariaDB tworzy konto root bez hasła, anonimowych użytkowników oraz przykładową bazę danych testową. Te domyślne ustawienia są wygodne podczas pierwszego uruchomienia, ale stanowią poważne zagrożenie bezpieczeństwa w środowisku produkcyjnym.

Podczas działania skryptu odpowiadasz na pytania (Y/n). Najbezpieczniejszą odpowiedzią jest 'Y' (tak) na wszystkie pytania. Po zakończeniu skryptu Twoja baza będzie odpowiednio zabezpieczona. Jeśli kiedykolwiek zapomnisz hasła root, możesz je zresetować, uruchamiając serwer w trybie pomijającym sprawdzanie uprawnień (mysqld --skip-grant-tables), ale to już zaawansowany temat.

7/36Pierwsze polecenia – poznaj środowisko

Po zalogowaniu – sprawdź co mamy

Zalogowałeś się do MariaDB. Czas na pierwsze polecenia, które pomogą Ci poznać środowisko.

-- Wersja serwera
SHOW VARIABLES LIKE 'version';

-- Wyświetlenie wszystkich baz danych
SHOW DATABASES;

-- Wybór bazy do pracy
USE mysql;

-- Wyświetlenie tabel w bieżącej bazie
SHOW TABLES;

-- Aktualny użytkownik
SELECT CURRENT_USER();

-- Serwer i jego status
STATUS;
Każde polecenie kończy się średnikiem (;). Wielkość liter nie ma znaczenia – 'show databases;' też zadziała.
Zrzut konsoli z wynikami poleceń SHOW DATABASES i STATUS

Po pierwszym zalogowaniu warto wykonać kilka poleceń rozpoznawczych, aby upewnić się, że środowisko działa poprawnie. Polecenie SHOW DATABASES wyświetli listę istniejących baz danych – domyślnie zobaczysz co najmniej bazy: information_schema, mysql, performance_schema oraz sys. To są systemowe bazy danych MariaDB, które przechowują metadane (dane o danych) i konfigurację serwera.

Polecenie STATUS (lub jego skrócona wersja \s) wyświetla szczegółowe informacje o bieżącej sesji: wersję serwera, kodowanie znaków (charset), czas pracy serwera (uptime), używany port i wiele innych. Znajomość tych informacji jest przydatna przy diagnozowaniu problemów z połączeniem lub wydajnością. Polecenie SELECT CURRENT_USER() zwraca nazwę użytkownika, pod którym jesteś zalogowany – w Twoim przypadku będzie to root@localhost.

8/36CREATE DATABASE – tworzenie własnej bazy danych

Zanim stworzysz tabele, musisz mieć bazę danych

Baza danych (ang. database) to pojemnik na tabele. Przed utworzeniem tabel musisz najpierw stworzyć (lub wybrać) bazę.

Tworzenie bazy danych:

-- Tworzenie bazy o nazwie 'biblioteka'
CREATE DATABASE biblioteka;

-- Tworzenie z wybranym zestawem znaków (zalecane dla polskich znaków)
CREATE DATABASE biblioteka
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_polish_ci;

Wybór bazy do pracy:

-- Przełączenie na bazę 'biblioteka'
USE biblioteka;

-- Sprawdzenie, która baza jest aktualnie wybrana
SELECT DATABASE();

Usuwanie bazy danych:

-- UWAGA: usuwa całą bazę z wszystkimi tabelami!
DROP DATABASE biblioteka;
Nazwy baz danych są case-sensitive w systemie Linux – 'Biblioteka' to inna baza niż 'biblioteka'.
Schemat – baza danych jako pudełko zawierające tabele

W MariaDB baza danych pełni funkcję przestrzeni nazw dla tabel. W ramach jednego serwera możesz mieć wiele baz danych, każdą dla innego projektu. Na przykład: biblioteka, sklep_internetowy, system_ocen. Tabele w różnych bazach mogą mieć te same nazwy – nie będą ze sobą kolidować.

Zalecane kodowanie to utf8mb4, które obsługuje pełny zestaw znaków Unicode, w tym polskie znaki diakrytyczne (ą, ć, ę, ł, ń, ó, ś, ź, ż) oraz emoji. COLLATE utf8mb4_polish_ci określa reguły porównywania znaków zgodne z polskim alfabetem. Jeśli nie podasz tych opcji, MariaDB użyje domyślnego kodowania (zwykle latin1), które ma ograniczoną obsługę polskich znaków.

9/36Typy danych w MariaDB – przegląd

Każda kolumna musi mieć określony typ danych

Typ danych określa, jakie wartości może przechowywać kolumna. Wybór odpowiedniego typu oszczędza miejsce i zapobiega błędom.

Najważniejsze typy liczbowe:

TypZakres / opis
TINYINTOd -128 do 127 (lub 0–255 z UNSIGNED)
SMALLINTOd -32768 do 32767
INTOd -2^31 do 2^31-1 (najczęściej używany)
BIGINTOd -2^63 do 2^63-1 (dla bardzo dużych liczb)
DECIMAL(10,2)Liczba stałoprzecinkowa: 10 cyfr, 2 po przecinku (np. 12345678.99)

Najważniejsze typy tekstowe:

TypOpis
VARCHAR(255)Tekst o zmiennej długości (max 255 znaków)
CHAR(10)Tekst o stałej długości (szybszy, stałe rozmiary)
TEXTDługi tekst (max ~65535 bajtów, ok. 16383 znaków przy utf8mb4)

Typy dat:

TypFormat
DATE'YYYY-MM-DD' np. '2026-06-12'
DATETIME'YYYY-MM-DD HH:MM:SS' np. '2026-06-12 14:30:00'
TIMESTAMPJak DATETIME, ale zapisywany w strefie UTC
VARCHAR jest najczęściej używany dla tekstu. Dla stałych długości (np. PESEL = 11 znaków) używaj CHAR.
Tabela typów danych z ikonami – liczby (123), tekst (abc), data (kalendarz)

Wybór odpowiedniego typu danych ma kluczowe znaczenie dla wydajności i integralności bazy. Użycie zbyt dużego typu (np. BIGINT zamiast INT dla wieku czytelnika) marnuje pamięć i spowalnia zapytania, podczas gdy użycie zbyt małego typu (np. TINYINT dla populacji miasta) może spowodować przepełnienie.

Szczególną uwagę zwróć na typ DECIMAL – służy do przechowywania kwot pieniężnych i innych wartości, gdzie dokładność jest krytyczna. Nigdy nie używaj do tego typu FLOAT ani DOUBLE, ponieważ liczby zmiennoprzecinkowe mają problemy z precyzją (np. 0.1 + 0.2 = 0.30000000000000004). Dla wartości logicznych (tak/nie) MariaDB ma typ BOOLEAN, który jest synonimem TINYINT(1) – gdzie 0 = fałsz, 1 = prawda.

10/36CREATE TABLE – ręczne tworzenie tabeli

Tworzymy pierwszą tabelę – Czytelnicy

Polecenie CREATE TABLE definiuje strukturę tabeli: nazwy kolumn, typy danych i ograniczenia.

CREATE TABLE Czytelnicy (
    ID_Czytelnika INT NOT NULL AUTO_INCREMENT,
    Imie          VARCHAR(50) NOT NULL,
    Nazwisko      VARCHAR(50) NOT NULL,
    Miasto        VARCHAR(50) NULL,
    PRIMARY KEY (ID_Czytelnika)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Wyjaśnienie składni:

  • CREATE TABLE nazwa – zaczynamy tworzenie tabeli
  • (...) – w nawiasie definiujemy kolumny i ograniczenia (oddzielone przecinkami)
  • ENGINE=InnoDB – silnik składowania (obsługuje klucze obce i transakcje)
  • Średnik (;) na końcu – wykonanie polecenia
InnoDB to domyślny i zalecany silnik MariaDB. Zawsze go używaj.
Schemat – CREATE TABLE z przypisaniem każdej części składni do opisu

CREATE TABLE to jedno z najważniejszych poleceń DDL (Data Definition Language). Definiuje ono strukturę tabeli, która później będzie wypełniana danymi za pomocą INSERT. Każda kolumna w definicji składa się z trzech elementów: nazwy (np. ID_Czytelnika), typu danych (np. INT) oraz opcjonalnych ograniczeń (np. NOT NULL, AUTO_INCREMENT).

ENGINE=InnoDB określa silnik składowania, czyli sposób, w jaki MariaDB fizycznie przechowuje dane na dysku. InnoDB jest domyślnym silnikiem i oferuje wsparcie dla transakcji (BEGIN, COMMIT, ROLLBACK), kluczy obcych (FOREIGN KEY) oraz lepszą wydajność przy równoczesnym dostępie wielu użytkowników. Drugi popularny silnik, MyISAM, jest szybszy przy odczycie, ale nie obsługuje transakcji ani kluczy obcych – nie jest zalecany dla nowych projektów.

11/36PRIMARY KEY i AUTO_INCREMENT

Klucz główny – jednoznaczna identyfikacja każdego wiersza

PRIMARY KEY to kolumna (lub zestaw kolumn), która jednoznacznie identyfikuje każdy wiersz. Każda tabela powinna mieć klucz główny.

Z AUTO_INCREMENT:

CREATE TABLE Ksiazki (
    ID_Ksiazki    INT NOT NULL AUTO_INCREMENT,
    Tytul         VARCHAR(100) NOT NULL,
    Gatunek       VARCHAR(50) NULL,
    Cena          DECIMAL(10,2) NULL,
    Rok_Wydania   INT NULL,
    PRIMARY KEY (ID_Ksiazki)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Bez AUTO_INCREMENT (klucz naturalny):

CREATE TABLE Miasta (
    Nazwa_Miasta  VARCHAR(50) NOT NULL,
    Wojewodztwo   VARCHAR(50) NOT NULL,
    PRIMARY KEY (Nazwa_Miasta)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

AUTO_INCREMENT automatycznie nadaje kolejne wartości (1, 2, 3, ...). Działa tylko z typami liczbowymi i kolumną będącą kluczem (lub jej częścią).

Klucz główny to jak numer PESEL dla wiersza – każdy wiersz ma inny, niepowtarzalny numer.
Tabela z wierszami – klucz główny oznaczony symbolem klucza (🔑) przy ID_Ksiazki

Klucz główny (PRIMARY KEY) ma dwie fundamentalne właściwości: unikalność (żadne dwa wiersze nie mogą mieć tej samej wartości klucza) oraz NOT NULL (klucz nie może być pusty). MariaDB automatycznie tworzy indeks na kluczu głównym, co znacznie przyspiesza wyszukiwanie po tej kolumnie.

AUTO_INCREMENT to popularna technika tworzenia sztucznych (zastępczych) kluczy głównych. Zaletą jest gwarantowana unikalność i stabilność – wartość klucza nie zmienia się nawet jeśli zmienią się dane w pozostałych kolumnach. Wada? Klucz nie niesie żadnej informacji o danych. Alternatywą są klucze naturalne, takie jak PESEL, ISBN czy Nazwa_Miasta, ale są one trudniejsze w utrzymaniu (np. zmiana nazwy miasta wymagałaby aktualizacji wszystkich powiązanych rekordów).

12/36Ograniczenia kolumn – NOT NULL, UNIQUE, DEFAULT

Ograniczenia (constraints) – reguły dla danych w kolumnie

Ograniczenia to reguły, które MariaDB wymusza automatycznie – nie pozwoli na naruszenie żadnej z nich.

CREATE TABLE Przyklady (
    ID         INT NOT NULL AUTO_INCREMENT,
    Kolumna1   VARCHAR(50) NOT NULL,
    Kolumna2   INT NULL,
    Kolumna3   VARCHAR(50) UNIQUE,
    Kolumna4   VARCHAR(20) DEFAULT 'brak',
    Kolumna5   DATE DEFAULT (CURRENT_DATE),
    PRIMARY KEY (ID)
) ENGINE=InnoDB;

Rodzaje ograniczeń:

OgraniczenieZnaczenie
NOT NULLKolumna nie może być pusta (musisz podać wartość)
NULLKolumna może być pusta (domyślnie)
UNIQUEWartości w kolumnie muszą być unikalne (nie mogą się powtarzać)
DEFAULT wartośćJeśli nie podasz wartości, zostanie użyta domyślna
CHECK (warunek)Wartość musi spełniać warunek (MariaDB 10.2+)
NOT NULL dla kluczy i obowiązkowych pól. UNIQUE dla emaili, loginów, PESEL.
Tabela z zaznaczonymi ograniczeniami – NOT NULL (czerwona ikona), UNIQUE (klucz), DEFAULT (zielona strzałka)

Ograniczenia kolumn (ang. column constraints) są pierwszym poziomem walidacji danych w MariaDB. Działają na poziomie serwera – niezależnie od tego, skąd pochodzą dane (aplikacja webowa, skrypt, konsola), MariaDB sprawdzi, czy wszystkie ograniczenia są spełnione, zanim zapisze dane na dysku. Jeśli któreś z ograniczeń jest naruszone, MariaDB zwróci błąd i operacja (INSERT/UPDATE) nie zostanie wykonana.

Ograniczenie CHECK dostępne jest od wersji MariaDB 10.2. Przykład: CHECK (Rok_Wydania >= 1800) – uniemożliwia wpisanie roku wydania wcześniejszego niż 1800. W starszych wersjach CHECK był parsowany, ale nie wymuszany. Od wersji 10.2 CHECK działa w pełni. Pamiętaj, że UNIQUE dopuszcza wiele wartości NULL (w MariaDB NULL != NULL, więc wiele wierszy może mieć UNIQUE z wartością NULL).

13/36DESCRIBE – przeglądanie struktury tabeli

Jak sprawdzić strukturę istniejącej tabeli?

Polecenie DESCRIBE (skrót: DESC) pokazuje kolumny, typy, ograniczenia i klucze tabeli.

DESCRIBE Czytelnicy;
-- lub krócej
DESC Czytelnicy;

Przykładowy wynik:

+----------------+-------------+------+-----+---------+----------------+
| Field          | Type        | Null | Key | Default | Extra          |
+----------------+-------------+------+-----+---------+----------------+
| ID_Czytelnika  | int(11)     | NO   | PRI | NULL    | auto_increment |
| Imie           | varchar(50) | NO   |     | NULL    |                |
| Nazwisko       | varchar(50) | NO   |     | NULL    |                |
| Miasto         | varchar(50) | YES  |     | NULL    |                |
+----------------+-------------+------+-----+---------+----------------+

Inne polecenia do przeglądania struktury:

-- Pełna definicja CREATE TABLE (jak została utworzona)
SHOW CREATE TABLE Czytelnicy;

-- Tylko kolumny (starsza składnia)
SHOW COLUMNS FROM Czytelnicy;
Field = nazwa kolumny, Type = typ, Null = YES/NO, Key = PRI (klucz główny), Default = wartość domyślna.
Zrzut konsoli z wynikiem DESCRIBE w kolorowej tabeli ASCII

DESCRIBE to najszybszy sposób na poznanie struktury tabeli. Każda kolumna w wyniku odpowiada jednemu atrybutowi definicji: Field (nazwa kolumny), Type (typ danych wraz z rozmiarem), Null (czy dopuszcza NULL), Key (rodzaj klucza: PRI=primary, UNI=unique, MUL=indeks nienakładający unikalności), Default (wartość domyślna), Extra (dodatkowe informacje, np. auto_increment).

SHOW CREATE TABLE to jeszcze potężniejsze narzędzie – wyświetla pełne polecenie CREATE TABLE, które odtworzyłoby daną tabelę ze wszystkimi ograniczeniami, indeksami i ustawieniami. Jest to szczególnie przydatne przy przenoszeniu schematu między środowiskami lub dokumentowaniu struktury bazy danych. W praktyce pokazuje to, jak MariaDB interpretuje Twoją definicję – możesz porównać swoje oryginalne CREATE TABLE z tym, co pokazuje SHOW CREATE TABLE, aby wychwycić ewentualne różnice.

14/36Wgrywanie pliku SQL z konsoli

Jak zaimportować gotowy plik .sql do bazy?

Gotowe skrypty SQL (np. bd_1nf, bd_2nf, bd_3nf, bd_4nf, bd_5nf, bcnf z wykładów) możesz wgrać na dwa sposoby. Pierwszy: przekierowanie pliku do klienta mysql z poziomu terminala (przed zalogowaniem).

Sposób 1 – przekierowanie wejścia:

# Składnia: mysql -u uzytkownik -p nazwa_bazy < plik.sql
mysql -u root -p biblioteka < /home/student/biblioteka.sql

Po naciśnięciu Enter wpisz hasło roota. Plik zostanie wykonany polecenie po poleceniu. Komunikaty o błędach (jeśli wystąpią) pojawią się na ekranie.

Jak sprawdzić, czy import się udał?

-- Po zalogowaniu sprawdź tabele w bazie
USE biblioteka;
SHOW TABLES;

-- Jeśli widzisz tabele – import się udał
Baza danych musi istnieć, zanim wgrasz plik. Jeśli nie istnieje, utwórz ją: CREATE DATABASE biblioteka;
Schemat – plik .sql wchodzi do konsoli mysql i trafia do bazy danych

Import przez przekierowanie wejścia (operator <) to najwygodniejszy i najszybszy sposób wgrywania dużych plików SQL. Terminal przekazuje całą zawartość pliku na standardowe wejście klienta mysql, który wykonuje każde polecenie po kolei. Jest to szczególnie przydatne przy inicjalizacji bazy danych skryptami z wykładów lub przy migracjach między środowiskami.

Jeśli plik SQL zawiera błędy (np. próbę utworzenia tabeli, która już istnieje), MariaDB zatrzyma wykonanie przy pierwszym błędzie (zachowanie domyślne). Aby kontynuować mimo błędów, możesz dodać opcję --force: mysql -u root -p --force biblioteka < plik.sql. Po zakończeniu importu zawsze sprawdź, czy liczba tabel i wierszy zgadza się z oczekiwaniami.

Import danych z plików CSV: W katalogu csv/ znajdują się pliki CSV z danymi dla tabel systemu bibliotecznego (rozdzielane średnikiem). Aby zaimportować dane z CSV do istniejącej tabeli, użyj polecenia LOAD DATA po zalogowaniu do MariaDB, np.: LOAD DATA LOCAL INFILE 'csv/miasta.csv' INTO TABLE Miasta FIELDS TERMINATED BY ';' LINES TERMINATED BY '\n' IGNORE 1 ROWS;. Pamiętaj o kolejności importu – najpierw tabele nadrzędne, potem zależne. Opcja IGNORE 1 ROWS pomija wiersz nagłówkowy CSV.

15/36Wgrywanie pliku SQL poleceniem SOURCE

Sposób 2 – SOURCE z wnętrza konsoli MariaDB

Drugi sposób: wgrać plik SQL już po zalogowaniu do MariaDB, używając polecenia SOURCE (lub \.).

Krok po kroku:

-- 1. Zaloguj się do MariaDB
mysql -u root -p

-- 2. Wybierz (lub utwórz) bazę
CREATE DATABASE IF NOT EXISTS biblioteka;
USE biblioteka;

-- 3. Wgraj plik SQL (pełna ścieżka bezwzględna lub względna)
SOURCE /home/student/biblioteka.sql;

-- lub skrót
\. /home/student/biblioteka.sql;

-- 4. Sprawdź, czy tabele zostały utworzone
SHOW TABLES;
Różnica: przy przekierowaniu (<) siedzisz w terminalu OS, przy SOURCE – wewnątrz konsoli MariaDB.
Zrzut konsoli – polecenie SOURCE wykonujące plik i wyświetlające komunikaty Query OK

Polecenie SOURCE jest szczególnie przydatne, gdy już pracujesz w konsoli MariaDB i chcesz doładować dodatkowy skrypt bez wychodzenia z sesji. MariaDB wyświetli komunikat Query OK dla każdego poprawnie wykonanego polecenia z pliku oraz komunikat ERROR dla każdego błędu. W przeciwieństwie do przekierowania zewnętrznego, przy SOURCE możesz na bieżąco widzieć, które polecenia są wykonywane.

Jeśli plik SQL znajduje się w bieżącym katalogu, możesz podać tylko nazwę pliku bez ścieżki: SOURCE biblioteka.sql;. W przypadku błędów składniowych MariaDB wskaże numer linii w pliku, co ułatwia debugowanie. Warto wiedzieć, że SOURCE działa również w phpMyAdmin i innych klientach SQL, ale tam często nazywa się to "Import" i udostępnia graficzny interfejs wyboru pliku.

16/36SHOW TABLES i SHOW CREATE TABLE

Przeglądanie tabel w bazie i ich definicji

Po wgraniu pliku SQL warto sprawdzić, jakie tabele zostały utworzone i jaka jest ich struktura.

Lista wszystkich tabel w bieżącej bazie:

SHOW TABLES;

Przykładowy wynik:

+----------------------+
| Tables_in_biblioteka |
+----------------------+
| Czytelnicy           |
| Ksiazki              |
| Wypozyczenia         |
+----------------------+

Pełna definicja wybranej tabeli:

SHOW CREATE TABLE Czytelnicy\G

Dodanie \G zamiast średnika wyświetla wynik pionowo – wygodniejsze dla szerokich tabel.

Inne przydatne polecenia:

-- Wszystkie bazy danych na serwerze
SHOW DATABASES;

-- Lista tabel we wszystkich bazach (od MariaDB 10.0)
SHOW TABLES FROM mysql;
SHOW TABLES bez USE – nie zadziała! Najpierw wybierz bazę: USE biblioteka;
Zrzut konsoli z wynikami SHOW TABLES i SHOW CREATE TABLE

SHOW TABLES wypisuje wszystkie tabele w bieżącej bazie danych. MariaDB zapamiętuje, którą bazę wybrałeś poleceniem USE na czas trwania sesji – po wylogowaniu i ponownym zalogowaniu musisz ponownie wybrać bazę. Aby sprawdzić, która baza jest aktualnie wybrana, użyj SELECT DATABASE();

SHOW CREATE TABLE z opcją \G (zamiast średnika) to ukryty klejnot MariaDB. W normalnym widoku tabela jest zbyt szeroka, by wygodnie zmieścić się w konsoli, a \G wyświetla każdą kolumnę w osobnej linii: CREATE TABLE, kolumny, klucze, opcje. To najlepszy sposób na skopiowanie definicji tabeli do dokumentacji lub do innego środowiska.

17/36INSERT – dodawanie danych do tabeli

INSERT – pierwsze polecenie DML

Po utworzeniu tabeli czas wypełnić ją danymi. Służy do tego polecenie INSERT.

INSERT – pojedynczy wiersz:

INSERT INTO Czytelnicy (Imie, Nazwisko, Miasto)
VALUES ('Jan', 'Kowalski', 'Kraków');

INSERT – wiele wierszy naraz (wydajniejsze!):

INSERT INTO Czytelnicy (Imie, Nazwisko, Miasto)
VALUES
    ('Anna', 'Nowak', 'Warszawa'),
    ('Piotr', 'Wiśniewski', 'Gdańsk'),
    ('Katarzyna', 'Zielińska', 'Poznań');

INSERT – pomijanie listy kolumn (wszystkie kolumny po kolei):

-- UWAGA: musisz znać dokładną kolejność kolumn w tabeli!
INSERT INTO Czytelnicy
VALUES (5, 'Tomasz', 'Adamczyk', 'Łódź');
Zawsze podawaj listę kolumn – to bezpieczniejsze i czytelniejsze. Kolejność VALUES musi być zgodna z listą kolumn.
Schemat – strzałka z VALUES do tabeli, wiersz pojawia się jako nowy rekord

INSERT to podstawowe polecenie DML (Data Manipulation Language) służące do dodawania nowych wierszy do tabeli. Możesz pominąć kolumnę ID_Czytelnika (dzięki AUTO_INCREMENT MariaDB sama wpisze kolejną wartość) oraz kolumnę Miasto (jeśli nie jest NOT NULL – wtedy przyjmie wartość NULL).

Dodawanie wielu wierszy jednym INSERT (wielowierszowy INSERT) jest znacznie wydajniejsze niż wykonywanie osobnych INSERT dla każdego wiersza – MariaDB przetwarza całe polecenie jako jedną transakcję, co redukuje narzut komunikacji. Dla 1000 wierszy różnica może być rzędu 10-100 razy szybsza. W praktyce zawsze grupuj wstawienia w jeden INSERT, jeśli to możliwe.

18/36INSERT – zaawansowane: IGNORE i ON DUPLICATE KEY

Radzenie sobie z duplikatami i błędami

Co jeśli próbujesz wstawić wiersz, który już istnieje (łamiąc UNIQUE lub PRIMARY KEY)? MariaDB zwróci błąd. Możesz to obsłużyć na dwa sposoby:

INSERT IGNORE – pomiń błędne wiersze:

INSERT IGNORE INTO Czytelnicy (ID_Czytelnika, Imie, Nazwisko, Miasto)
VALUES (1, 'Jan', 'Kowalski', 'Kraków');
-- Jeśli ID=1 już istnieje – MariaDB wyświetli ostrzeżenie, ale nie przerwie

ON DUPLICATE KEY UPDATE – aktualizuj jeśli istnieje:

INSERT INTO Czytelnicy (ID_Czytelnika, Imie, Nazwisko, Miasto)
VALUES (1, 'Jan', 'Kowalski', 'Warszawa')
ON DUPLICATE KEY UPDATE
    Miasto = 'Warszawa';
-- Jeśli ID=1 istnieje – zaktualizuje miasto; jeśli nie – wstawi nowy wiersz
INSERT IGNORE po cichu pomija błędy. ON DUPLICATE KEY UPDATE jest bezpieczniejszy – wiesz, co się stało.
Diagram – dwa flow: INSERT normalny (błąd przy duplikacie) vs INSERT ON DUPLICATE KEY UPDATE (aktualizacja)

INSERT IGNORE i ON DUPLICATE KEY UPDATE to zaawansowane warianty INSERT, które pozwalają na bezpieczne wstawianie danych bez ryzyka przerwania transakcji z powodu duplikatów. INSERT IGNORE po prostu pomija wiersze, które naruszają ograniczenia (PRIMARY KEY, UNIQUE) i kontynuuje z kolejnymi. MariaDB wyświetla ostrzeżenie (SHOW WARNINGS;), ale nie zwraca błędu.

ON DUPLICATE KEY UPDATE to potężniejsze narzędzie – pozwala zdefiniować, co zrobić, gdy wiersz już istnieje. Typowym zastosowaniem jest aktualizacja danych zamiast ich pomijania. W przykładzie: jeśli czytelnik z ID=1 już istnieje, zmieniamy jego miasto na Warszawę. Jeśli nie istnieje – wstawiamy nowy wiersz. To jest podstawa operacji "upsert" (UPDATE + INSERT).

19/36SELECT – podstawy odczytu danych

SELECT – najważniejsze polecenie SQL

SELECT służy do odczytywania danych z tabel. To najczęściej używane polecenie w SQL.

Wszystkie kolumny (*):

SELECT * FROM Czytelnicy;

Wybrane kolumny:

SELECT Imie, Nazwisko FROM Czytelnicy;

Aliasy (przezwanie kolumn):

SELECT Imie AS ImieM, Nazwisko AS NazwiskoM
FROM Czytelnicy;

Wyrażenia w SELECT:

SELECT Imie, Nazwisko,
       CONCAT(Imie, ' ', Nazwisko) AS PelneNazwisko
FROM Czytelnicy;

Przykładowy wynik:

+-------+----------+------------------+
| Imie  | Nazwisko | PelneNazwisko    |
+-------+----------+------------------+
| Jan   | Kowalski | Jan Kowalski     |
| Anna  | Nowak    | Anna Nowak       |
| Piotr | Wiśniewski | Piotr Wiśniewski |
+-------+----------+------------------+
Nie używaj * w kodzie produkcyjnym – zawsze wymieniaj konkretne kolumny. * jest OK tylko do szybkiego podglądu.
Schemat – strzałki: SELECT wybiera kolumny, FROM wskazuje tabelę, strzałka do wyniku

SELECT jest najważniejszym i najczęściej używanym poleceniem SQL. Jego podstawowa składnia to SELECT ... FROM ... [WHERE] [ORDER BY] [LIMIT]. Klauzula SELECT określa, które kolumny mają być zwrócone, FROM – z której tabeli, a opcjonalne dalsze klauzule (które poznamy) filtrują, sortują i ograniczają wyniki.

Używanie * (gwiazdki) w SELECT jest wygodne podczas eksploracji danych, ale w aplikacjach i skryptach produkcyjnych powinieneś zawsze wymieniać konkretne kolumny. Powód: * zwraca wszystkie kolumny, które mogą być zbędne, co zwiększa ilość przesyłanych danych i obciąża serwer. Ponadto, jeśli ktoś doda nową kolumnę do tabeli, Twój kod nagle zacznie zwracać dodatkowe dane, co może powodować nieoczekiwane błędy w aplikacji.

20/36SELECT – WHERE i operatory porównania

WHERE – filtr danych (wybierz tylko interesujące Cię wiersze)

Klauzula WHERE pozwala wybrać tylko te wiersze, które spełniają określony warunek.

Podstawowe operatory porównania:

OperatorZnaczeniePrzykład
=równyMiasto = 'Kraków'
<> lub !=różnyMiasto <> 'Kraków'
>większyRok_Wydania > 2000
<mniejszyCena < 50
>=większy lub równyWiek >= 18
<=mniejszy lub równyOcena <= 3.0

Przykłady:

-- Czytelnicy z Krakowa
SELECT * FROM Czytelnicy
WHERE Miasto = 'Kraków';

-- Książki wydane po 2000 roku
SELECT Tytul, Rok_Wydania FROM Ksiazki
WHERE Rok_Wydania > 2000;
Uwaga: w SQL do porównania używa się = (pojedynczy), nie ==. Dla tekstu używaj apostrofów: WHERE Miasto = 'Kraków'
Schemat – lejek WHERE: z wszystkich wierszy tabeli przechodzą tylko spełniające warunek

Klauzula WHERE jest sercem zapytań SQL – to ona umożliwia precyzyjne wybieranie danych spośród tysięcy czy milionów wierszy. WHERE wykonuje filtrowanie na poziomie wierszy przed ewentualnym grupowaniem i sortowaniem. Kolejność klauzul w SELECT jest ściśle określona: SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT.

Warto wiedzieć, że porównywanie wartości NULL wymaga specjalnych operatorów: IS NULL i IS NOT NULL. Zwykłe porównanie (= NULL) nie zadziała, ponieważ NULL oznacza "brak wartości", a nie "zero" czy "pusty tekst". Przykład: WHERE Miasto IS NULL – wybierze czytelników, którzy nie mają przypisanego miasta.

21/36SELECT – AND, OR, NOT, BETWEEN, IN

Łączenie warunków w WHERE

Możesz łączyć wiele warunków za pomocą operatorów logicznych.

AND – wszystkie warunki muszą być spełnione:

-- Czytelnicy z Krakowa o nazwisku Kowalski
SELECT * FROM Czytelnicy
WHERE Miasto = 'Kraków' AND Nazwisko = 'Kowalski';

OR – przynajmniej jeden warunek spełniony:

-- Czytelnicy z Krakowa LUB Warszawy
SELECT * FROM Czytelnicy
WHERE Miasto = 'Kraków' OR Miasto = 'Warszawa';

BETWEEN – zakres (włącznie z granicami):

-- Książki wydane między 1990 a 2020 (włącznie)
SELECT * FROM Ksiazki
WHERE Rok_Wydania BETWEEN 1990 AND 2020;

IN – lista dozwolonych wartości:

-- To samo co OR, ale krócej i czytelniej
SELECT * FROM Czytelnicy
WHERE Miasto IN ('Kraków', 'Warszawa', 'Gdańsk');

NOT – zaprzeczenie:

-- Czytelnicy spoza Krakowa
SELECT * FROM Czytelnicy
WHERE Miasto NOT IN ('Kraków');
AND ma wyższy priorytet niż OR. Używaj nawiasów, aby wymusić kolejność: (war1 OR war2) AND war3.
Diagram Venna – AND (część wspólna), OR (suma), NOT (dopełnienie)

Operatory logiczne AND, OR i NOT działają w SQL tak samo jak w innych językach programowania. AND zwraca prawdę, gdy oba warunki są prawdziwe; OR – gdy przynajmniej jeden jest prawdziwy; NOT – odwraca wartość logiczną. Ważna jest kolejność wykonywania: AND ma wyższy priorytet niż OR, co może prowadzić do nieoczekiwanych wyników. Przykład: WHERE Miasto = 'Kraków' OR Miasto = 'Warszawa' AND Wiek > 18 – AND wykona się najpierw, więc warunek oznacza "Miasto = Kraków LUB (Miasto = Warszawa I Wiek > 18)". Aby uzyskać "(Kraków lub Warszawa) I wiek > 18", musisz użyć nawiasów.

Operator BETWEEN jest włączający (obejmuje granice), więc BETWEEN 1990 AND 2020 obejmuje lata 1990 i 2020. Operator IN to czytelny skrót dla wielu warunków OR – zamiast pisać Miasto = 'A' OR Miasto = 'B' OR Miasto = 'C', piszesz Miasto IN ('A', 'B', 'C').

22/36SELECT – LIKE (wyszukiwanie wzorców)

LIKE – wyszukiwanie według wzorca

Operator LIKE pozwala szukać tekstu pasującego do wzorca z użyciem dwóch znaków specjalnych (wildcards).

Znaki specjalne LIKE:

ZnakZnaczeniePrzykład
%Dowolny ciąg znaków (0 lub więcej)'Kra%' → Kraków, Krab, Krawat
_Dokładnie jeden dowolny znak'Kra_' → Krak, Krab, Kram

Przykłady:

-- Nazwiska zaczynające się na 'K'
SELECT * FROM Czytelnicy
WHERE Nazwisko LIKE 'K%';

-- Miasta kończące się na 'ów'
SELECT * FROM Czytelnicy
WHERE Miasto LIKE '%ów';

-- Nazwiska zawierające 'ski' (np. Kowalski, Wiśniewski)
SELECT * FROM Czytelnicy
WHERE Nazwisko LIKE '%ski%';

-- NOT LIKE – zaprzeczenie
SELECT * FROM Czytelnicy
WHERE Nazwisko NOT LIKE 'K%';
LIKE rozróżnia wielkość liter w zależności od COLLATION. utf8mb4_polish_ci – CI = Case Insensitive (nie rozróżnia).
Schemat – ciąg znaków z zaznaczonymi % (wiele znaków) i _ (jeden znak)

LIKE to podstawowe narzędzie do wyszukiwania tekstu w MariaDB. Znak % oznacza "dowolny ciąg znaków" (może być pusty), a _ oznacza "dokładnie jeden dowolny znak". Wzorce LIKE są wrażliwe na ustawienia porównywania (collation) – jeśli używasz utf8mb4_polish_ci, wyszukiwanie nie rozróżnia wielkości liter (CI = Case Insensitive).

Uwaga: LIKE z % na początku wzorca (np. '%ski') jest bardzo wolne na dużych tabelach, ponieważ MariaDB nie może użyć indeksu – musi przeskanować wszystkie wiersze (pełne skanowanie tabeli). Jeśli potrzebujesz wyszukiwania pełnotekstowego, rozważ użycie indeksów FULLTEXT i operatora MATCH ... AGAINST, który jest wydajniejszy i oferuje ranking trafności.

23/36SELECT – ORDER BY (sortowanie wyników)

ORDER BY – sortowanie wg wybranej kolumny

Klauzula ORDER BY sortuje wyniki zapytania rosnąco (ASC) lub malejąco (DESC).

Sortowanie rosnące (domyślne):

-- Czytelnicy posortowani alfabetycznie według nazwiska
SELECT * FROM Czytelnicy
ORDER BY Nazwisko;

-- Można też jawnie: ASC
ORDER BY Nazwisko ASC;

Sortowanie malejące:

-- Najpierw najnowsze książki
SELECT Tytul, Rok_Wydania FROM Ksiazki
ORDER BY Rok_Wydania DESC;

Sortowanie po wielu kolumnach:

-- Najpierw po mieście (rosnąco), potem po nazwisku (rosnąco)
SELECT * FROM Czytelnicy
ORDER BY Miasto, Nazwisko;

-- Mieszane: miasto rosnąco, nazwisko malejąco
ORDER BY Miasto ASC, Nazwisko DESC;
ORDER BY wykonuje się jako przedostatnie (przed LIMIT), po WHERE. W MariaDB wartości NULL są sortowane jako pierwsze w sortowaniu rosnącym (ASC).
Schemat – strzałki pokazujące sortowanie A→Z (ASC) i Z→A (DESC)

ORDER BY sortuje wynik zapytania według jednej lub więcej kolumn. Kierunek sortowania: ASC (ascending, rosnąco, od A do Z, od najmniejszej do największej) i DESC (descending, malejąco, od Z do A, od największej do najmniejszej). Jeśli nie podasz kierunku, domyślnie używane jest ASC.

Sortowanie po wielu kolumnach działa hierarchicznie: najpierw wiersze są sortowane według pierwszej kolumny, a wiersze z tą samą wartością w pierwszej kolumnie są sortowane według drugiej kolumny, itd. W przykładzie: wszyscy czytelnicy z Krakowa będą przed tymi z Warszawy, a w obrębie tego samego miasta czytelnicy będą posortowani według nazwiska. Sortowanie zużywa zasoby serwera – dla bardzo dużych zbiorów danych (miliony wierszy) rozważ dodanie indeksu na kolumnie, po której sortujesz.

24/36SELECT – LIMIT i OFFSET (ograniczenie wyników)

LIMIT – tylko pierwsze N wierszy

Klauzula LIMIT ogranicza liczbę zwracanych wierszy. Niezbędna przy paginacji i szybkim podglądzie.

LIMIT – podstawowe użycie:

-- Pierwszych 5 czytelników
SELECT * FROM Czytelnicy LIMIT 5;

-- 10 najnowszych książek
SELECT Tytul, Rok_Wydania FROM Ksiazki
ORDER BY Rok_Wydania DESC
LIMIT 10;

LIMIT z OFFSET – pomiń N wierszy:

-- Pomiń 2 pierwsze książki, pokaż 3 następne (strona 2)
SELECT * FROM Ksiazki
ORDER BY Tytul
LIMIT 3 OFFSET 2;

-- Składnia skrócona: LIMIT offset, count
LIMIT 2, 3;  -- to samo co LIMIT 3 OFFSET 2

Paginacja: Strona 1: LIMIT 10 OFFSET 0; Strona 2: LIMIT 10 OFFSET 10; Strona 3: LIMIT 10 OFFSET 20; ...

Zawsze używaj ORDER BY z LIMIT – bez ORDER BY nie masz gwarancji, które wiersze zostaną zwrócone!
Schemat – tabela z wierszami, strzałka LIMIT odcina górne wiersze, OFFSET pomija

LIMIT to klauzula, która mówi MariaDB: "zwróć tylko N pierwszych wierszy wyniku". OFFSET mówi: "pomiń M wierszy od początku". Razem umożliwiają paginację – dzielenie wyników na strony. Przykład: masz 100 książek, chcesz pokazać po 10 na stronę. Strona 1: LIMIT 10 OFFSET 0; Strona 2: LIMIT 10 OFFSET 10; itd.

Bardzo ważne: LIMIT bez ORDER BY daje nieprzewidywalne wyniki! MariaDB może zwrócić dowolne wiersze – nie ma gwarancji, że będą to te, które chciałeś. Zawsze łącz LIMIT z ORDER BY, aby mieć kontrolę nad tym, które wiersze zostaną zwrócone. Składnia skrócona LIMIT offset, count pochodzi z MySQL-a i działa w MariaDB, ale dla czytelności zaleca się LIMIT count OFFSET offset.

25/36Funkcje agregujące – COUNT, SUM, AVG, MIN, MAX

Funkcje agregujące – obliczenia na grupie wierszy

Funkcje agregujące wykonują obliczenia na zbiorze wierszy i zwracają pojedynczą wartość.

-- Liczba wszystkich czytelników
SELECT COUNT(*) AS LiczbaCzytelnikow FROM Czytelnicy;

-- Liczba czytelników z przypisanym miastem (nie NULL)
SELECT COUNT(Miasto) FROM Czytelnicy;

-- Liczba unikalnych miast
SELECT COUNT(DISTINCT Miasto) FROM Czytelnicy;

-- Średni rok wydania książek
SELECT AVG(Rok_Wydania) AS SredniRok FROM Ksiazki;

-- Najstarsza i najnowsza książka
SELECT MIN(Rok_Wydania) AS Najstarsza,
       MAX(Rok_Wydania) AS Najnowsza
FROM Ksiazki;

-- SUM – suma (np. wszystkich wypożyczeń)
SELECT SUM(Cena) FROM Ksiazki;
COUNT(*) liczy wszystkie wiersze łącznie z NULL-ami. COUNT(kolumna) liczy wiersze, gdzie kolumna nie jest NULL.
Ikony – COUNT (licznik), SUM (Σ), AVG (średnia), MIN (minimum), MAX (maksimum)

Funkcje agregujące to podstawowe narzędzie analizy danych w SQL. COUNT zwraca liczbę wierszy, SUM – sumę wartości, AVG – średnią arytmetyczną, MIN – wartość minimalną, MAX – wartość maksymalną. Wszystkie funkcje agregujące (z wyjątkiem COUNT(*)) ignorują wartości NULL w obliczeniach. COUNT(kolumna) policzy tylko wiersze, w których dana kolumna nie jest NULL.

COUNT(DISTINCT kolumna) to przydatna odmiana – liczy unikalne, niepuste wartości w kolumnie. Przykład: jeśli w tabeli Czytelnicy masz 100 wierszy, ale tylko 5 różnych miast, COUNT(DISTINCT Miasto) zwróci 5. Funkcje agregujące są często używane razem z GROUP BY (następny slajd) do tworzenia podsumowań dla poszczególnych grup danych.

26/36SELECT – GROUP BY (grupowanie wyników)

GROUP BY – grupowanie wierszy według wartości w kolumnie

GROUP BY łączy wiersze o tych samych wartościach w wybranych kolumnach i pozwala na obliczenia agregujące dla każdej grupy.

-- Liczba czytelników w każdym mieście
SELECT Miasto, COUNT(*) AS Liczba
FROM Czytelnicy
GROUP BY Miasto;

-- Średni rok wydania książek dla każdej kategorii
SELECT Gatunek, AVG(Rok_Wydania) AS SredniRok
FROM Ksiazki
GROUP BY Gatunek;

Przykładowy wynik dla COUNT per miasto:

+----------+--------+
| Miasto   | Liczba |
+----------+--------+
| Kraków   |      5 |
| Warszawa |      3 |
| Gdańsk   |      2 |
| Poznań   |      1 |
+----------+--------+

Grupowanie po wielu kolumnach:

-- Liczba książek w każdym mieście według gatunku
SELECT c.Miasto, k.Gatunek, COUNT(*) AS Liczba
FROM Ksiazki k
JOIN Wypozyczenia w ON k.ID_Ksiazki = w.ID_Ksiazki
JOIN Czytelnicy c ON w.ID_Czytelnika = c.ID_Czytelnika
GROUP BY c.Miasto, k.Gatunek;
Każda kolumna w SELECT (poza funkcjami agregującymi) musi być wymieniona w GROUP BY!
Schemat – wiersze są grupowane według kolorów, dla każdej grupy liczona jest agregacja

GROUP BY to jedna z najpotężniejszych klauzul SQL. Dzieli wiersze na grupy na podstawie wartości w jednej lub więcej kolumnach, a następnie dla każdej grupy oblicza funkcje agregujące. W przykładzie: wszystkie wiersze Czytelnicy są dzielone według kolumny Miasto; czytelnicy z Krakowa tworzą jedną grupę, z Warszawy drugą, itd. Dla każdej grupy COUNT(*) podaje liczbę wierszy w grupie.

Ważna zasada: wszystkie kolumny wymienione w SELECT, które nie są funkcjami agregującymi (COUNT, SUM, AVG, MIN, MAX), muszą być wymienione w GROUP BY. Jeśli tego nie zrobisz, MariaDB zwróci błąd (w trybie strict) lub nieprzewidywalne wyniki. Wyjątek: jeśli grupujesz po kluczu głównym tabeli, możesz SELECTować inne kolumny – ale to działa tylko w MySQL/MariaDB, nie w innych bazach.

27/36SELECT – HAVING (filtrowanie grup)

HAVING – filtr dla grup (po GROUP BY)

WHERE filtruje wiersze przed grupowaniem. HAVING filtruje grupy po grupowaniu. Nie możesz użyć funkcji agregującej w WHERE.

Różnica między WHERE a HAVING:

-- WHERE – filtruje wiersze PRZED grupowaniem
-- HAVING – filtruje grupy PO grupowaniu

-- Miasta, w których jest więcej niż 2 czytelników
SELECT Miasto, COUNT(*) AS Liczba
FROM Czytelnicy
GROUP BY Miasto
HAVING Liczba > 2;

-- To nie zadziała – funkcja agregująca w WHERE!
-- SELECT Miasto, COUNT(*) FROM Czytelnicy WHERE COUNT(*) > 2 GROUP BY Miasto; -- BŁĄD!

Przykład złożony – WHERE + GROUP BY + HAVING:

-- Miasta z co najmniej 2 czytelnikami, ale tylko dorośli (wiek >= 18)
SELECT Miasto, COUNT(*) AS Liczba
FROM Czytelnicy
WHERE Wiek >= 18        -- WHERE: przed grupowaniem
GROUP BY Miasto
HAVING COUNT(*) > 1;     -- HAVING: po grupowaniu
WHERE → GROUP BY → HAVING → ORDER BY → LIMIT. Taka jest kolejność wykonywania klauzul.
Schemat przepływu: WHERE (filtruje wiersze) → GROUP BY (grupuje) → HAVING (filtruje grupy)

Klauzula HAVING jest często mylona z WHERE, ale pełni zupełnie inną rolę. WHERE filtruje wiersze przed grupowaniem i nie może używać funkcji agregujących. HAVING filtruje grupy po grupowaniu i może używać funkcji agregujących. Kolejność wykonywania zapytania jest ściśle określona: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT.

W praktyce: WHERE odrzuca niepotrzebne wiersze na samym początku, co zmniejsza ilość danych do grupowania i przyspiesza zapytanie. HAVING odrzuca całe grupy po obliczeniu agregacji. W przykładzie: najpierw WHERE odrzuca niepełnoletnich czytelników, potem GROUP BY grupuje pozostałych według miast, a HAVING zostawia tylko miasta z więcej niż 1 czytelnikiem. To bardzo wydajny przepływ – nie grupujemy w ogóle niepełnoletnich czytelników.

28/36JOIN – INNER JOIN (łączenie tabel)

INNER JOIN – łączenie danych z dwóch tabel

JOIN pozwala pobrać dane z wielu tabel jednocześnie, łącząc je na podstawie wspólnej kolumny (klucza obcego).

-- Kto wypożyczył jaką książkę?
SELECT Czytelnicy.Imie, Czytelnicy.Nazwisko,
       Ksiazki.Tytul
FROM Wypozyczenia
INNER JOIN Czytelnicy
    ON Wypozyczenia.ID_Czytelnika = Czytelnicy.ID_Czytelnika
INNER JOIN Ksiazki
    ON Wypozyczenia.ID_Ksiazki = Ksiazki.ID_Ksiazki;

Skrócona składnia z aliasami:

SELECT c.Imie, c.Nazwisko, k.Tytul
FROM Wypozyczenia w
JOIN Czytelnicy c ON w.ID_Czytelnika = c.ID_Czytelnika
JOIN Ksiazki k ON w.ID_Ksiazki = k.ID_Ksiazki;

INNER JOIN zwraca tylko pasujące wiersze:

Jeśli czytelnik nie ma żadnego wypożyczenia – nie pojawi się w wyniku. Jeśli książka nie była wypożyczona – też nie.

INNER JOIN to najczęściej używany typ JOIN. Zwraca tylko wiersze, które mają dopasowanie w obu tabelach.
Diagram Venna – INNER JOIN jako przecięcie dwóch zbiorów (część wspólna)

JOIN to fundamentalna operacja w relacyjnych bazach danych, która pozwala łączyć dane z wielu tabel w jednym zapytaniu. Bez JOIN każda tabela byłaby wyspą – nie mógłbyś powiedzieć "pokaż mi książki wypożyczone przez Jana Kowalskiego", ponieważ dane o czytelnikach są w jednej tabeli, a o wypożyczeniach w drugiej.

INNER JOIN zwraca tylko te wiersze, dla których warunek ON jest spełniony (znaleziono dopasowanie w obu tabelach). Jeśli czytelnik nie wypożyczył żadnej książki, nie pojawi się w wyniku – nawet jeśli istnieje w tabeli Czytelnicy. Aliasowanie tabel (w, c, k) skraca zapis i poprawia czytelność. Zawsze używaj aliasów w JOIN – bez nich zapytania szybko stają się nieczytelne.

29/36JOIN – LEFT JOIN (wszystkie wiersze z lewej tabeli)

LEFT JOIN – wszystkie wiersze z lewej tabeli, nawet bez dopasowania

LEFT JOIN zwraca wszystkie wiersze z lewej tabeli (FROM) i dopasowane wiersze z prawej tabeli (JOIN). Jeśli nie ma dopasowania, kolumny z prawej tabeli są NULL.

-- Wszyscy czytelnicy i ich wypożyczenia (nawet jeśli nie wypożyczyli)
SELECT c.Imie, c.Nazwisko, k.Tytul
FROM Czytelnicy c
LEFT JOIN Wypozyczenia w ON c.ID_Czytelnika = w.ID_Czytelnika
LEFT JOIN Ksiazki k ON w.ID_Ksiazki = k.ID_Ksiazki
ORDER BY c.Nazwisko;

-- Czytelnicy, którzy NIE wypożyczyli żadnej książki
SELECT c.Imie, c.Nazwisko
FROM Czytelnicy c
LEFT JOIN Wypozyczenia w ON c.ID_Czytelnika = w.ID_Czytelnika
WHERE w.ID_Wypozyczenia IS NULL;

Różnice:

Typ JOINWynik
INNER JOINTylko pasujące wiersze
LEFT JOINWszystkie z lewej + pasujące z prawej
RIGHT JOINWszystkie z prawej + pasujące z lewej
LEFT JOIN to INNER JOIN + wiersze bez dopasowania (z NULL-ami po prawej).
Diagram Venna – LEFT JOIN jako cały lewy zbiór z częścią wspólną

LEFT JOIN jest niezwykle przydatny, gdy chcesz znaleźć "wszystkie elementy z A, nawet jeśli nie mają odpowiednika w B". Typowym zastosowaniem jest raport "wszyscy użytkownicy i liczba ich zamówień" – nawet jeśli ktoś nic nie zamówił, powinien się pojawić z zerem (COUNT zliczy wiersze, a NULL-e nie są liczone).

Ważna sztuczka: aby znaleźć wiersze z lewej tabeli, które NIE mają dopasowania w prawej, użyj LEFT JOIN i sprawdź WHERE prawa_kolumna IS NULL. To jest odpowiednik operatora "NOT EXISTS" lub "NOT IN". W przykładzie: znajdujemy czytelników, którzy nie wypożyczyli żadnej książki – sprawdzamy, czy ID_Wypozyczenia (z prawej tabeli) jest NULL.

30/36UPDATE – modyfikacja istniejących danych

UPDATE – zmiana wartości w istniejących wierszach

Polecenie UPDATE modyfikuje dane w już istniejących wierszach. Zawsze używaj WHERE – bez WHERE zaktualizujesz wszystkie wiersze!

Podstawowa składnia:

UPDATE Czytelnicy
SET Miasto = 'Kraków'
WHERE ID_Czytelnika = 1;
-- Zmienia miasto czytelnika o ID=1 na 'Kraków'

Aktualizacja wielu kolumn:

UPDATE Czytelnicy
SET
    Miasto = 'Warszawa',
    Nazwisko = 'Nowak-Kowalski'
WHERE ID_Czytelnika = 2;

Aktualizacja wielu wierszy:

-- Podwyżka ceny o 10% dla wszystkich książek wydanych przed 2000
UPDATE Ksiazki
SET Cena = Cena * 1.10
WHERE Rok_Wydania < 2000;

Aktualizacja na podstawie innej tabeli (z JOIN):

UPDATE Ksiazki k
JOIN Wypozyczenia w ON k.ID_Ksiazki = w.ID_Ksiazki
SET k.Cena = k.Cena * 0.95
WHERE w.Data_Wypozyczenia < '2020-01-01';
UWAGA! UPDATE bez WHERE zaktualizuje WSZYSTKIE wiersze w tabeli. Zawsze sprawdzaj warunek WHERE dwukrotnie!
Schemat – strzałka z SET do konkretnej komórki w tabeli, WHERE wskazuje wiersz

UPDATE to polecenie DML służące do modyfikacji istniejących danych. Klauzula SET określa, które kolumny zmienić i na jakie wartości. Klauzula WHERE określa, które wiersze zaktualizować. Bez WHERE zaktualizowane zostaną wszystkie wiersze – to najczęstszy błąd początkujących. Przed wykonaniem UPDATE na produkcji zawsze wykonaj najpierw SELECT z tym samym WHERE, aby zobaczyć, które wiersze zostaną zmodyfikowane.

UPDATE z JOIN pozwala na aktualizację danych w jednej tabeli na podstawie wartości z innej tabeli. To potężne narzędzie, ale wymaga ostrożności. W przykładzie: obniżamy cenę książek, które były wypożyczone przed 2020 rokiem. MariaDB łączy tabele Ksiazki i Wypozyczenia, a następnie aktualizuje tylko te wiersze Ksiazki, które spełniają warunek WHERE.

31/36DELETE – usuwanie danych

DELETE – usuwanie wierszy z tabeli

Polecenie DELETE usuwa wiersze z tabeli. Podobnie jak w UPDATE – WHERE jest krytyczne!

Usunięcie wybranego wiersza:

DELETE FROM Czytelnicy
WHERE ID_Czytelnika = 5;

Usunięcie wielu wierszy:

-- Usuń czytelników z Łodzi
DELETE FROM Czytelnicy
WHERE Miasto = 'Łódź';

Usunięcie wszystkich wierszy (ale tabela zostaje):

-- UWAGA! Usuwa wszystkie dane, ale struktura tabeli pozostaje
DELETE FROM Czytelnicy;

-- Szybsza alternatywa (nie loguje każdego wiersza)
TRUNCATE TABLE Czytelnicy;

DELETE z JOIN – usuwanie na podstawie innych tabel:

-- Usuń książki, które nigdy nie były wypożyczone
DELETE k FROM Ksiazki k
LEFT JOIN Wypozyczenia w ON k.ID_Ksiazki = w.ID_Ksiazki
WHERE w.ID_Wypozyczenia IS NULL;
DELETE z WHERE to selektywne usuwanie. DELETE bez WHERE = wyczyść całą tabelę. TRUNCATE jest szybsze i zeruje AUTO_INCREMENT, ale w przeciwieństwie do DELETE nie zachowuje kolejności numeracji.
Ikona kosza na śmieci + strzałka wskazująca konkretny wiersz do usunięcia

DELETE usuwa wiersze z tabeli. Różnica między DELETE a TRUNCATE: DELETE usuwa wiersz po wierszu, zapisując każdą operację w dzienniku transakcji (redo log), co pozwala na wycofanie (ROLLBACK) – ale jest wolniejsze. TRUNCATE usuwa całą tabelę i tworzy ją od nowa – jest dużo szybsze, ale nie można go cofnąć. TRUNCATE zeruje też AUTO_INCREMENT, DELETE nie.

DELETE z JOIN pozwala usunąć wiersze z jednej tabeli na podstawie warunku dotyczącego innej tabeli. W przykładzie: znajdujemy książki, które nie mają żadnego dopasowania w tabeli Wypozyczenia (LEFT JOIN + IS NULL), i usuwamy je. To bezpieczne – nie usuniemy książek, które kiedykolwiek zostały wypożyczone. Zawsze sprawdź warunek WHERE na SELECT przed wykonaniem DELETE.

32/36ALTER TABLE – modyfikacja struktury tabeli

ALTER TABLE – zmiana struktury istniejącej tabeli

Po utworzeniu tabeli możesz ją modyfikować bez utraty danych. Służy do tego polecenie ALTER TABLE.

Dodanie nowej kolumny:

ALTER TABLE Czytelnicy
ADD COLUMN Email VARCHAR(100) NULL;

Dodanie kolumny w określonej pozycji:

ALTER TABLE Czytelnicy
ADD COLUMN Telefon VARCHAR(20) AFTER Nazwisko;

Zmiana typu/ograniczeń kolumny:

ALTER TABLE Czytelnicy
MODIFY COLUMN Nazwisko VARCHAR(100) NOT NULL;

ALTER TABLE Czytelnicy
MODIFY COLUMN Miasto VARCHAR(50) NOT NULL;

Zmiana nazwy kolumny:

ALTER TABLE Czytelnicy
RENAME COLUMN Miasto TO Miejscowosc;

Usunięcie kolumny:

ALTER TABLE Czytelnicy
DROP COLUMN Telefon;

Zmiana nazwy tabeli:

ALTER TABLE Czytelnicy RENAME TO Czytelnicy_archiwum;
-- lub
RENAME TABLE Czytelnicy TO Czytelnicy_archiwum;
ALTER TABLE na dużych tabelach (miliony wierszy) może trwać długo i blokować dostęp. Planuj zmiany poza godzinami szczytu.
Schemat – tabela przed i po ALTER TABLE z nową kolumną oznaczoną na zielono

ALTER TABLE to podstawowe narzędzie do ewolucji schematu bazy danych. W trakcie rozwoju projektu prawie zawsze zachodzi potrzeba dodania nowej kolumny, zmiany typu danych lub dodania ograniczenia. ALTER TABLE pozwala na to bez konieczności usuwania i odtwarzania tabeli (co wiązałoby się z utratą danych).

Ważne ograniczenia: MODIFY COLUMN może nie działać, jeśli nowy typ jest niekompatybilny z istniejącymi danymi (np. zmiana VARCHAR na INT, gdy w kolumnie są litery). ADD COLUMN z AFTER wstawia kolumnę po wskazanej kolumnie; bez AFTER kolumna jest dodawana na końcu. W MariaDB nie można dodać kolumny BEFORE – musiałaby być pierwsza, co wymagałoby AFTER na pierwszej kolumnie (co nie działa – użyj FIRST).

33/36Klucze obce (FOREIGN KEY) i integralność referencyjna

FOREIGN KEY – połączenie między tabelami

Klucz obcy to kolumna w tabeli, która odwołuje się do klucza głównego innej tabeli. Zapewnia integralność referencyjną – nie można dodać wypożyczenia dla nieistniejącego czytelnika.

CREATE TABLE Wypozyczenia (
    ID_Wypozyczenia  INT NOT NULL AUTO_INCREMENT,
    ID_Czytelnika    INT NOT NULL,
    ID_Ksiazki       INT NOT NULL,
    Data_Wypozyczenia DATE NOT NULL,
    Data_Oddania     DATE NULL,
    PRIMARY KEY (ID_Wypozyczenia),
    FOREIGN KEY (ID_Czytelnika)
        REFERENCES Czytelnicy(ID_Czytelnika)
        ON DELETE CASCADE,
    FOREIGN KEY (ID_Ksiazki)
        REFERENCES Ksiazki(ID_Ksiazki)
        ON DELETE RESTRICT
) ENGINE=InnoDB;

Opcje ON DELETE / ON UPDATE:

OpcjaDziałanie
CASCADEUsuń/zaktualizuj też powiązane wiersze
SET NULLUstaw klucz obcy na NULL
RESTRICTNie pozwól na usunięcie/aktualizację
NO ACTIONTo samo co RESTRICT (w MariaDB)
Klucze obce działają TYLKO z ENGINE=InnoDB. MyISAM nie obsługuje kluczy obcych!
Schemat – strzałki od kluczy obcych w Wypozyczenia do kluczy głównych w Czytelnicy i Ksiazki

Klucz obcy (FOREIGN KEY) to mechanizm zapewniający integralność referencyjną – gwarantuje, że wartości w kolumnie klucza obcego zawsze odpowiadają istniejącym wartościom w referowanej tabeli. Dzięki temu nie można: (a) wstawić wypożyczenia dla nieistniejącego czytelnika, (b) usunąć czytelnika, który ma wypożyczenia (jeśli użyto RESTRICT), (c) zmienić ID czytelnika, jeśli ma wypożyczenia.

Opcja ON DELETE CASCADE automatycznie usuwa wszystkie wypożyczenia czytelnika, gdy czytelnik jest usuwany – wygodne, ale niebezpieczne. ON DELETE RESTRICT (domyślne) blokuje usunięcie czytelnika, jeśli ma wypożyczenia – bezpieczniejsze. Wybór zależy od logiki biznesowej: czy usunięcie czytelnika ma automatycznie anulować jego wypożyczenia, czy wymagać ręcznego zwrotu książek.

34/36Indeksy – przyspieszanie zapytań

CREATE INDEX – indeksy dla szybszego wyszukiwania

Indeks to struktura danych (B-drzewo), która przyspiesza wyszukiwanie w tabeli. Działa jak indeks w książce – zamiast przeglądać wszystkie strony, od razu wiesz, gdzie szukać.

Tworzenie indeksu:

-- Indeks na kolumnie Nazwisko (szybkie wyszukiwanie po nazwisku)
CREATE INDEX idx_nazwisko ON Czytelnicy(Nazwisko);

-- Indeks na wielu kolumnach (indeks złożony)
CREATE INDEX idx_miasto_nazwisko ON Czytelnicy(Miasto, Nazwisko);

-- Indeks unikalny (jak UNIQUE constraint, ale jako indeks)
CREATE UNIQUE INDEX idx_email ON Czytelnicy(Email);

Sprawdzenie indeksów tabeli:

SHOW INDEX FROM Czytelnicy;

Usunięcie indeksu:

DROP INDEX idx_nazwisko ON Czytelnicy;

Kiedy indeks pomaga:

  • WHERE na indeksowanej kolumnie
  • JOIN po indeksowanej kolumnie
  • ORDER BY na indeksowanej kolumnie
  • COUNT/MIN/MAX na indeksowanej kolumnie
Indeksy przyspieszają SELECT, ale spowalniają INSERT/UPDATE/DELETE (bo trzeba aktualizować indeks). Nie przesadzaj z liczbą indeksów.
Schemat – B-drzewo (indeks) prowadzące od wartości do lokalizacji w tabeli

Indeksy to jeden z najważniejszych mechanizmów optymalizacji wydajności baz danych. Bez indeksu MariaDB musi przeskanować całą tabelę (ang. full table scan) – dla 10 milionów wierszy oznacza to odczytanie wszystkich 10 milionów. Z indeksem MariaDB może przejść przez B-drzewo (które ma wysokość ~3-4 dla milionów wierszy) i od razu znaleźć potrzebne dane.

Indeksy nie są darmowe: każdy indeks zajmuje miejsce na dysku (często więcej niż same dane) i musi być aktualizowany przy każdym INSERT, UPDATE i DELETE. Dlatego indeksuj tylko kolumny, po których często wyszukujesz (WHERE), łączysz (JOIN) lub sortujesz (ORDER BY). Klucze główne mają automatycznie indeks – nie musisz tworzyć osobnego indeksu dla PRIMARY KEY.

35/36Najczęstsze błędy początkujących

10 typowych błędów i jak ich unikać

BłądDlaczego to błąd?Poprawnie
UPDATE/DELETE bez WHEREModyfikujesz/usuwasz wszystkie wierszeZawsze dodawaj WHERE
Zapomniany średnik (;)Polecenie nie zostanie wykonaneKażde polecenie zakończ ;
Brak USE przed SHOW TABLESMariaDB nie wie, którą bazę pokazaćNajpierw USE nazwa_bazy
Porównanie z NULL przez =NULL = NULL daje NULL, nie TRUEUżywaj IS NULL, IS NOT NULL
MyISAM zamiast InnoDBBrak kluczy obcych i transakcjiZawsze ENGINE=InnoDB
Brak nawiasów przy AND/ORAND ma wyższy priorytet(war1 OR war2) AND war3
SELECT * w kodzie aplikacjiZwraca niepotrzebne kolumnyWymień konkretne kolumny
Brak indeksów dla JOIN/WHEREBardzo wolne zapytaniaDodaj indeks na kolumnach JOIN/WHERE
VARCHAR bez rozmiaruMariaDB zwróci błąd składniZawsze podaj rozmiar: VARCHAR(100)
Zapominanie o AUTO_INCREMENTMusisz ręcznie podawać IDDodaj AUTO_INCREMENT przy kluczu
Najgroźniejszy błąd: UPDATE/DELETE bez WHERE. Zawsze wykonaj SELECT z tym WHERE najpierw!
Znaki ostrzegawcze przy każdym błędzie – czerwone wykrzykniki

Większość błędów początkujących wynika z dwóch przyczyn: nieznajomości składni SQL oraz braku nawyków bezpieczeństwa. Kluczowa zasada: nigdy nie wykonuj UPDATE ani DELETE bez WHERE, którego dokładnie nie sprawdziłeś. W środowisku produkcyjnym często zdarza się, że programista przez pomyłkę wykona UPDATE users SET password = 'x' (bez WHERE) i zresetuje hasła wszystkich użytkowników. Profesjonaliści zawsze opakowują modyfikacje w transakcję (BEGIN/COMMIT/ROLLBACK) i wykonują SELECT przed UPDATE/DELETE.

Drugim częstym problemem jest ignorowanie błędów MariaDB. Gdy MariaDB zwraca błąd, zawsze zatrzymaj się i przeczytaj komunikat – często zawiera on wskazówkę, co poszło nie tak (np. "Column 'Miasto' cannot be null" – próbujesz wstawić NULL do kolumny z NOT NULL). W konsoli możesz użyć SHOW ERRORS; lub SHOW WARNINGS; po wykonaniu polecenia, aby zobaczyć szczegóły.

36/36Podsumowanie – co dalej?

Gratulacje! Opanowałeś podstawy MariaDB i SQL

Przebyliśmy długą drogę od instalacji MariaDB przez tworzenie tabel i zapytania SQL. Oto, czego się nauczyłeś:

Co potrafisz:

  • Zainstalować i uruchomić MariaDB
  • Zalogować się i zabezpieczyć konto root
  • Tworzyć bazy danych i tabele (z typami, kluczami, ograniczeniami)
  • Wgrywać pliki SQL (przez < i SOURCE)
  • Przeglądać strukturę baz (DESCRIBE, SHOW TABLES)
  • Dodawać, odczytywać, modyfikować i usuwać dane (CRUD)
  • Filtrować (WHERE), sortować (ORDER BY), grupować (GROUP BY)
  • Łączyć tabele (JOIN) – INNER i LEFT
  • Tworzyć indeksy dla wydajności

Gdzie dalej?

  • Normalizacja 1NF–5NF – projektowanie wydajnych schematów
  • Widoki tabel – gotowy przykład bazy bibliotecznej
  • Praktyka na własnych projektach – najlepsza nauka!
Bazy danych to umiejętność praktyczna. Uruchom konsolę i eksperymentuj – tylko ćwiczenia czynią mistrza.
Metafora – otwarta księga z napisem

Dotarłeś do końca tutoriala MariaDB od podstaw. To dopiero początek Twojej przygody z bazami danych – opanowałeś fundamenty, na których możesz budować bardziej zaawansowaną wiedzę. SQL jest językiem, który towarzyszy programistom przez całą karierę, a umiejętność sprawnego formułowania zapytań jest jedną z najbardziej cenionych na rynku pracy.

Rekomendowane kolejne kroki: (1) przejdź do prezentacji o normalizacji (1NF), aby nauczyć się projektować poprawne schematy baz danych; (2) przeanalizuj widoki tabel w widoki_tabele.html – zobaczysz, jak wygląda kompletna baza biblioteczna po normalizacji; (3) załóż konto na platformie do ćwiczenia SQL (np. SQLZoo, LeetCode, HackerRank) i regularnie rozwiązuj zadania. Pamiętaj: w bazach danych teoria bez praktyki jest jak książka kucharska bez gotowania – sama się nie nauczysz.