Naucz się tematu Bazy danych i SQL od zera
1Czym jest relacyjna baza danych
Relacyjna baza danych przechowuje dane w tabelach. Tabela wygląda jak arkusz kalkulacyjny: każdy wiersz to jeden rekord, każda kolumna to jedna właściwość.
Sklep może mieć tabelę customers z kolumnami id, name i city oraz tabelę orders z kolumnami id, customer_id i total.
Klucz główny to kolumna lub zestaw kolumn jednoznacznie identyfikujący każdy wiersz. Nigdy się nie powtarza i nigdy nie jest pusty. Tutaj jest to id każdej tabeli.
Klucz obcy to kolumna odwołująca się do klucza głównego innej tabeli. W orders customer_id mówi, który klient złożył zamówienie.
W ten sposób łączy się tabele: jeden klient może mieć wiele zamówień, ale każde zamówienie należy do jednego klienta. To relacja jeden do wielu.
SQL (Structured Query Language) to język, którego używasz do tworzenia tabel, zmieniania danych i zadawania pytań o nie.
Samosprawdzenie Czym jest klucz główny?
- Indeksem przyspieszającym wyszukiwanie
- Kolumną lub zestawem kolumn jednoznacznie identyfikującym każdy wiersz
- Kolumną odwołującą się do wiersza w innej tabeli
- Pierwszą kolumną każdej tabeli
Odpowiedź: Kolumną lub zestawem kolumn jednoznacznie identyfikującym każdy wiersz. Klucz główny jest unikalny i nigdy nie jest NULL, więc wskazuje dokładnie jeden wiersz. Kolumna odwołująca się do innej tabeli to klucz obcy.
2Odczyt danych za pomocą SELECT
Większość pytań dotyczy instrukcji SELECT. Składa się z klauzul, zawsze zapisywanych w tej kolejności:
SELECT … FROM … WHERE … GROUP BY … HAVING … ORDER BY …
- SELECT wymienia kolumny, które chcesz. DISTINCT usuwa zduplikowane wiersze.
- FROM wskazuje tabelę lub połączone tabele.
- WHERE zostawia tylko wiersze spełniające warunek, na przykład WHERE total > 20.
- GROUP BY łączy wiersze o tej samej wartości w jedną grupę, aby można było liczyć lub sumować dla grupy.
- HAVING zostawia tylko grupy spełniające warunek. Może używać agregatów, czego WHERE nie może.
- ORDER BY sortuje wynik, domyślnie rosnąco; dodaj DESC, aby najwyższe było pierwsze.
Funkcje agregujące podsumowują wiele wierszy w jedną wartość: COUNT, SUM, AVG, MIN i MAX.
Baza danych nie wykonuje klauzul w kolejności, w jakiej je zapisujesz. Najpierw wykonuje FROM, potem WHERE, GROUP BY, HAVING, SELECT i na końcu ORDER BY.
Inne instrukcje zmieniają dane: INSERT dodaje wiersze, UPDATE zmienia wiersze, a DELETE usuwa wiersze. CREATE, ALTER i DROP zmieniają same tabele.
Samosprawdzenie Chcesz tylko klientów z więcej niż 5 zamówieniami. Która klauzula filtruje według COUNT(*) > 5?
- DISTINCT
- HAVING
- ORDER BY
- WHERE
Odpowiedź: HAVING. Liczba istnieje dopiero po pogrupowaniu wierszy, a HAVING filtruje grupy. WHERE wykonuje się przed grupowaniem, więc nie może użyć agregatu takiego jak COUNT.
3Złączenia, normalizacja i transakcje
Złączenie (join) łączy wiersze dwóch tabel według warunku, zwykle klucz obcy = klucz główny:
FROM customers c JOIN orders o ON o.customer_id = c.id
- INNER JOIN (lub JOIN) zostawia tylko wiersze, które mają dopasowanie w obu tabelach.
- LEFT JOIN zostawia każdy wiersz lewej tabeli. Gdy nie ma dopasowania, kolumny prawej tabeli mają wartość NULL.
- NULL oznacza, że wartość jest brakująca lub nieznana. Sprawdzaj ją za pomocą IS NULL, nigdy za pomocą = NULL.
Normalizacja dzieli tabele tak, aby każdy fakt był przechowywany raz. Pozwala to uniknąć aktualizowania tego samego faktu w kilku miejscach.
- 1NF: każda komórka zawiera jedną atomową wartość, bez powtarzających się grup.
- 2NF: 1NF i każda kolumna niekluczowa zależy od całego klucza, a nie od jego części w kluczu złożonym.
- 3NF: 2NF i żadna kolumna niekluczowa nie zależy od innej kolumny niekluczowej.
Transakcja grupuje instrukcje w jedną jednostkę. COMMIT czyni ją trwałą, a ROLLBACK ją cofa. Transakcje spełniają ACID: atomowość (wszystko albo nic), spójność, izolację i trwałość.
Samosprawdzenie Klient nie złożył żadnych zamówień. Co dzieje się z tym klientem w customers LEFT JOIN orders?
- Klient pojawia się raz dla każdego zamówienia w tabeli
- Klient pojawia się raz, z NULL w kolumnach zamówienia
- Klient zostaje pominięty w wyniku
- Zapytanie kończy się błędem
Odpowiedź: Klient pojawia się raz, z NULL w kolumnach zamówienia. LEFT JOIN zostawia każdy wiersz lewej tabeli i uzupełnia brakującą prawą stronę wartością NULL. Pominięcie klienta to działanie INNER JOIN.
4Metoda krok po kroku
Aby napisać zapytanie albo ustalić, co zwraca dane zapytanie:
- Znajdź tabele zawierające dane i to, jak są połączone kluczami.
- Zapisz FROM ze złączeniami. Wybierz LEFT JOIN, gdy wiersze bez dopasowania mają zostać.
- Dodaj WHERE dla warunków na pojedynczych wierszach.
- Jeśli pytanie mówi „na” albo „dla każdego”, dodaj GROUP BY i agregat.
- Dodaj HAVING dla warunków na agregacie, potem ORDER BY, jeśli kolejność ma znaczenie.
- Sprawdź wynik na małym przykładzie: wypisz wiersze po każdej klauzuli, w kolejności, w jakiej wykonuje je baza danych.
W pytaniu teoretycznym najpierw nazwij pojęcie (klucz, rodzaj złączenia, postać normalna, właściwość ACID), potem wybierz opcję pasującą do jego definicji.
5Przykład krok po kroku
Przejdź przez każdy krok. Spróbuj przewidzieć następny, zanim go odsłonisz.
Przykład krok po krokuTabela customers ma wiersze (1, Ana), (2, Ben) i (3, Cas). Tabela orders ma wiersze (id, customer_id) = (10, 1), (11, 1), (12, 2) i (13, 1). Co zwraca to zapytanie? SELECT c.name, COUNT(o.id) FROM customers c LEFT JOIN orders o ON o.customer_id = c.id GROUP BY c.name
1Każdy klient jest sparowany z zamówieniami o jego id. Ana pasuje do zamówień 10, 11 i 13. Ben pasuje do zamówienia 12.
Cas nie ma zamówień. Ponieważ to LEFT JOIN, Cas zostaje w wyniku, z NULL dla o.id.
2- Ana, 10
- Ana, 11
- Ana, 13
- Ben, 12
- Cas, NULL
To 5 wierszy.
3GROUP BY c.name tworzy trzy grupy: Ana z 3 wierszami, Ben z 1 wierszem i Cas z 1 wierszem.
4COUNT(o.id) liczy tylko wartości różne od NULL. Ana dostaje 3, a Ben 1.
Cas ma jeden wiersz, ale jego o.id to NULL, więc Cas dostaje 0.
5Ana, Ben i Cas razem mają 3 + 1 + 0 = 4 zamówienia, tyle samo co wierszy w orders. Przy COUNT(*) Cas błędnie dostałby 1, ponieważ COUNT(*) liczy sam wiersz.
Odpowiedź Ana 3, Ben 1, Cas 0.
6Typowe błędy
- Użycie agregatu w WHERE. Warunki na COUNT, SUM lub AVG należą do HAVING.
- Pisanie = NULL. Każde porównanie z NULL jest nieznane; użyj IS NULL lub IS NOT NULL.
- Użycie INNER JOIN, gdy wiersze bez dopasowania mają zostać. Użyj LEFT JOIN.
- Zapomnienie o warunku złączenia. Bez ON każdy wiersz jest sparowany z każdym wierszem (złączenie krzyżowe).
- Wybranie kolumny, której nie ma w GROUP BY ani wewnątrz agregatu.
- Mylenie DELETE (usuwa wiersze) z DROP TABLE (usuwa całą tabelę).
- Uruchomienie UPDATE lub DELETE bez WHERE. Zmienia każdy wiersz w tabeli.
Samosprawdzenie Tabela ma 10 wierszy, a kolumna col ma w każdym wierszu wartość NULL. Co zwraca SELECT COUNT(col)?
- 0
- 10
- 1
- NULL
Odpowiedź: 0. COUNT(col) liczy tylko wartości różne od NULL, więc zwraca 0. COUNT(*) liczy wiersze i zwróciłoby 10.
7Jak wyglądają zadania egzaminacyjne
- Łatwe: pojęcia i fakty. Co robią SELECT, WHERE, ORDER BY lub DELETE, klucze główny i obcy, co oznacza NULL.
- Średnie: stosowanie pojęć. Właściwe zapytanie dla zadania, WHERE a HAVING, złączenia wewnętrzne a zewnętrzne, postacie normalne, ACID.
- Trudne: przypadki i analiza. Podzapytania, poziomy izolacji i ich anomalie, BCNF, funkcje okna, indeksy i wydajność zapytań, SQL injection.
Gdy podano zapytanie, prześledź je na kilku wierszach w kolejności FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY. Większość pułapek ujawnia się w ciągu trzech wierszy.
Ucz się krok po kroku w aplikacjiUcz się krok po kroku w aplikacji