Schemat „Kotomarketu”
What you'll learn
- wskazywać właściwą tabelę spośród pięciu tabel „Kotomarketu”:
users,products,orders,order_items,events - czytać diagram ER: określać kardynalność powiązania (1:N, N:M, 1:1) po tym, gdzie leży klucz obcy
- rozwiązywać relację „wiele do wielu” przez tabelę pośredniczącą z dwoma FK — jak
order_itemszorder_id+product_id - wyjaśniać, dlaczego zawartości zamówienia nie można przechowywać jako ciągu id bezpośrednio w
orders
Dziś QUERY wysuwa na główny stół cały inwentarz naraz. Pięć świecących płaszczyzn zawisa w powietrzu i powoli się obraca — mapa ocalałego świata. Obok migocze dziennik konserwacji dołączony do migawki, a jedna linijka jest w nim podkreślona: „Przekazuję pięć tabel i ślad szóstej. — K.” Przeliczasz płaszczyzny. Dokładnie pięć. Gdzie ślad?
QUERY: Nie rozpraszaj się śladami. Najpierw naucz się tych pięciu tak, żeby trafiać tu z zamkniętymi oczami — resztę archiwum pokaże samo, gdy uzna cię za gotowego.
Pięć tabel „Kotomarketu”
Dalej będziemy pracować z tą bazą — migawką sklepu internetowego z 2024 roku. Traktuj ją jak mapę sklepu: kto przyszedł, co leży na wystawie, co kupiono i co działo się przed zakupem.
| Tabela | Co przechowuje |
|---|---|
users | kupujących: id, imię i nazwisko, miasto oraz datę rejestracji |
products | towary z wystawy: id, nazwę, kategorię, cenę i stan magazynowy |
orders | zamówienia: id, user_id, datę, status i łączną kwotę |
order_items | zawartość zamówień: jaki towar, ile sztuk i po jakiej cenie |
events | zdarzenia użytkowników: wyświetlenia, dodania do koszyka i zakupy |
Powiązania czyta się tak: jeden user → wiele orders; jeden order → wiele order_items; jeden product → wiele order_items. Jeśli się pogubisz, otwórz schemat po prawej — działa jak plan sali sprzedaży.
Zajrzyjmy do tabeli zamówień: w każdym wierszu jest user_id — odwołanie do kupującego. Tak jedna tabela łączy się z drugą, a mapa przestaje być pięcioma osobnymi wyspami.

Kotomarket’s five tables
From here on we’ll be working with this database — a of an online shop from 2024. Hold it like a map of the store: who walked in, what’s on the shelves, what they bought, and what they did before buying.
| Table | What it holds |
|---|---|
users | buyers: id, name, city, and signup date |
products | storefront items: id, name, category, price, and stock |
orders | orders: id, user_id, date, status, and total |
order_items | order contents: which product, how many, and at what price |
events | behavioral events: views, add-to-carts, and purchases |
The links read like this: one user → many orders; one order → many order_items; one product → many order_items. If you get lost, open the schema on the right — it’s like the floor plan of the shop.
Let’s peek into the orders table: every row has a user_id — a reference to a buyer. That’s how one table links to another, and the map stops being five separate islands.
user_id:| id | user_id | status | total_amount |
|---|---|---|---|
| 1 | 18 | paid | 5980.00 |
| 2 | 10 | paid | 19750.00 |
| 3 | 26 | cancelled | 9560.00 |
| 4 | 26 | paid | 15530.00 |
| 5 | 8 | paid | 26710.00 |
| 6 | 37 | paid | 42110.00 |
Jak czytać diagram ER
Mapę, którą rozwinął QUERY, w branży nazywa się diagramem ER (entity–relationship): prostokąty to tabele, linie między nimi to powiązania po kluczach obcych. Najważniejsza na linii jest kardynalność: ile wierszy z jednej strony może odpowiadać ilu wierszom z drugiej.
- 1:N, jeden-do-wielu — najczęstsze powiązanie. Jeden kupujący — wiele zamówień. Klucz obcy zawsze leży po stronie „wielu”:
user_idprzechowuje się worders, a nie odwrotnie. To prosta reguła czytania: znalazłeś FK — znalazłeś stronę N. - N:M, wiele-do-wielu — w jednym zamówieniu może być wiele towarów, a jeden towar może pojawiać się w wielu zamówieniach. Bezpośrednio takiego powiązania w bazie relacyjnej wyrazić się nie da: klucz obcy nie ma gdzie się zmieścić. Rozwiązuje się je przez tabelę pośredniczącą — u nas to
order_items. Każdy jej wiersz niesie parę odwołańorder_id+product_idi zamienia jedno powiązanie N:M w dwa powiązania 1:N. Przy okazji samo powiązanie zyskuje atrybuty — liczbę sztuk i cenę w chwili zakupu. - 1:1, jeden-do-jednego — spotyka się rzadziej: na przykład ciężkie albo prywatne pola przenosi się do osobnej tabeli z tym samym kluczem.
-- Rozplątanie N:M w działaniu: pary „zamówienie — towar” z order_items
SELECT order_id, product_id, quantity
FROM order_items
LIMIT 6;
Pułapka: przechowywać zawartość zamówienia bezpośrednio w orders — jako ciąg '7,12,3' albo tablicę identyfikatorów. Takich danych nie da się ochronić kluczem obcym, rzetelnie policzyć ani połączyć z katalogiem bez akrobatyki. Widzisz relację „wiele do wielu” — twórz tabelę pośredniczącą z dwoma kluczami obcymi, jak order_items.
Interview question
Pytanie z rozmowy kwalifikacyjnej: jak w bazie relacyjnej zrealizować powiązanie „wiele do wielu”?
Mocna odpowiedź: przez tabelę pośredniczącą z dwoma kluczami obcymi do łączonych tabel — jak order_items z order_id i product_id: zamienia ona N:M w dwa powiązania 1:N. Przy okazji można przechowywać w niej atrybuty samego powiązania — liczbę sztuk, cenę w chwili zakupu. Klucz główny takiej tabeli jest albo złożony z dwóch FK, albo sztuczny id.