Podatkovne baze brez megle

Shema Kotomarketa

11 min
What you'll learn
  • najti pravo tabelo med petimi v Kotomarketu: users, products, orders, order_items, events
  • brati ER-diagram: določiti kardinalnost povezave (1:N, N:M, 1:1) po tem, kje leži tuji ključ
  • razgrniti povezavo »mnogo proti mnogo« skozi vmesno tabelo z dvema FK — kot order_items z order_id + product_id
  • razložiti, zakaj sestave naročila ni mogoče hraniti kot niz id-jev kar v orders

Danes QUERY na glavno mizo naenkrat prikaže ves popis. Pet svetlečih ploskev obvisi v zraku in se počasi vrti — zemljevid preživelega sveta. Zraven utripa dnevnik konservacije, priložen posnetku, ena vrstica v njem pa je podčrtana: »Izročam pet tabel in sled šeste. — K.« Prešteješ ploskve. Točno pet. Kje je sled?

QUERY: Ne ukvarjaj se s sledmi. Najprej se nauči teh pet tako dobro, da boš pot našel z zaprtimi očmi — ostalo ti bo arhiv pokazal sam, ko bo presodil, da si pripravljen.

Pet tabel Kotomarketa

V nadaljevanju bomo delali s to bazo — posnetkom spletne trgovine iz leta 2024. Imej jo kot zemljevid trgovine: kdo je prišel, kaj leži na izložbi, kaj so kupili in katera dejanja so opravili pred nakupom.

TabelaKaj hrani
userskupce: id, ime, mesto in datum registracije
productsizdelke izložbe: id, naziv, kategorijo, ceno in zalogo
ordersnaročila: id, user_id, datum, status in znesek
order_itemssestavo naročil: kateri izdelek, koliko kosov in po kateri ceni
eventsvedenjske dogodke: oglede, dodajanja v košarico in nakupe

Povezave se berejo takole: en user → mnogo orders; en order → mnogo order_items; en product → mnogo order_items. Če se izgubiš, odpri shemo na desni — je kot tloris prodajnega prostora.

Pokukajmo v tabelo naročil: v vsaki vrstici je user_id — sklic na kupca. Tako se ena tabela poveže z drugo in zemljevid neha biti pet ločenih otokov.

Pet holografskih tabel-ploskev se vrti kot ozvezdje, povezanih z nitmi; ob strani je komaj viden pikčast obris šestega
Zemljevid arhiva: pet tabel in povezave med njimi. Dnevnik konservacije obeta tudi »sled šeste« — a je za zdaj ni videti.

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.

TableWhat it holds
usersbuyers: id, name, city, and signup date
productsstorefront items: id, name, category, price, and stock
ordersorders: id, user_id, date, status, and total
order_itemsorder contents: which product, how many, and at what price
eventsbehavioral 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.

Naročila in njihova povezava s kupcem prek user_id:
Query result
iduser_idstatustotal_amount
118paid5980.00
210paid19750.00
326cancelled9560.00
426paid15530.00
58paid26710.00
637paid42110.00

Kako brati ER-diagram

Zemljevidu, ki ga je razgrnil QUERY, v industriji pravijo ER-diagram (entity–relationship): pravokotniki so tabele, črte med njimi pa povezave prek tujih ključev. Najpomembnejša na črti je kardinalnost: koliko vrstic z ene strani ustreza kolikim z druge.

  • 1:N, eden proti mnogim — najpogostejša povezava. En kupec — mnogo naročil. Tuji ključ vedno leži na strani »mnogih«: user_id se hrani v orders, ne pa obratno. To je pravilo branja: našel si FK — našel si stran N.
  • N:M, mnogo proti mnogim — v enem naročilu je mnogo izdelkov, en izdelek pa se pojavlja v mnogih naročilih. Take povezave v relacijski bazi ni mogoče izraziti neposredno: tujega ključa ni kam položiti. Razgrne se skozi vmesno tabelo — pri nas je to order_items. Vsaka njena vrstica nosi par sklicev order_id + product_id in spremeni eno povezavo N:M v dve povezavi 1:N. Bonus: sama povezava dobi atribute — število kosov in ceno v trenutku nakupa.
  • 1:1, eden proti enemu — pojavlja se redkeje: na primer težka ali zasebna polja prestavimo v ločeno tabelo z istim ključem.
-- Razvozlanje N:M v praksi: pari »naročilo — izdelek« iz order_items
SELECT order_id, product_id, quantity
FROM order_items
LIMIT 6;
usersidnameproductsidpriceordersiduser_ideventsuser_idproduct_idorder_itemsorder_idproduct_iduser_id → idproduct_id → idPKFK (reference)
ER-diagram Kotomarketa: povezave 1:N od users do orders in razvozlanje N:M med orders in products prek order_items.

Pasti: hraniti sestavo naročila kar v orders — kot niz '7,12,3' ali polje identifikatorjev. Takih podatkov ni mogoče zaščititi s tujim ključem, jih pošteno prešteti ali spojiti z izložbo brez akrobatike. Ko vidiš povezavo »mnogo proti mnogo«, ustvari vmesno tabelo z dvema tujima ključema, kot je order_items.

Interview question

Vprašanje z razgovora: kako v relacijski bazi izvesti povezavo »mnogo proti mnogo«?

Močan odgovor: skozi vmesno tabelo z dvema tujima ključema na povezovani tabeli — kot order_items z order_id in product_id: ta spremeni N:M v dve povezavi 1:N. Obenem v njej hranimo atribute same povezave — količino, ceno v trenutku nakupa. Primarni ključ take tabele je bodisi sestavljen iz obeh FK bodisi nadomestni id.

Check yourself
Kje v shemi je videti, kateri izdelek je prišel v katero naročilo?