Podatkovne baze brez megle

Tabele, vrstice in ključi

11 min
What you'll learn
  • ločiti tabele, vrstice in stolpce ter razložiti, čemu vsaka vrstica potrebuje primarni ključ (običajno id)
  • najti povezave med tabelami prek tujega ključa: orders.user_id → users.id
  • ločiti nadomestni ključ (IDENTITY, ) od naravnega (email, ISBN) in utemeljiti, zakaj se primarni ključ ne sme spreminjati
  • z omejitvijo UNIQUE zagotoviti enoličnost polja, kot je email, ne da bi ga naredil za primarni ključ

Popis je odprt. QUERY nad delovno mizo razgrne hologram: tisoči zapisov obvisijo v zraku v enakomerni mreži, med nekaterimi pa se napenjajo tanke jantarne niti. Sežeš po eni — zazveni kot struna. To ni kup datotek. To je tkanina.

Tabele, vrstice, stolpci

Relacijska baza je podobna urejenemu katalogu: podatki so razporejeni po tabelah, znotraj vsake tabele pa so stolpci (katere lastnosti hranimo) in vrstice (konkretni zapisi).

Vzemi tabelo kupcev users: vsaka vrstica je en kupec stare Zemlje, stolpci pa opisujejo njegov id, full_name, email, country, city, signup_date.

Da ne bi zamenjeval ljudi z enakimi imeni, ima vsaka vrstica primarni ključ () — enolični identifikator, običajno stolpec id. Prek njega lahko druge tabele kažejo na to vrstico s pomočjo tujega ključa (). Na primer, v naročilu orders je user_id — tako se naročilo spomni svojega kupca. Prav tiste jantarne niti na hologramu so povezave prek ključev.

QUERY: Dokler je ključ cel, je cela nit. Minilo je poldrugo stoletje, vsako naročilo pa se še vedno spomni svojega človeka.

Zaženi poizvedbo in poglej, kako izgledajo kupci Kotomarketa — zapisi, ki jih ni nihče odprl od časov starega Omrežja:

Holografska tabela iz vrstic-kapsul in stolpcev; od zapisov naročil do zapisov ljudi se napenjajo jantarne niti ključev
Vrstice so zapisi, stolpci njihove lastnosti, nit od naročila do kupca pa je povezava prek ključa.

Tables, rows, columns

A relational database is like a tidy catalog: the data is sorted into tables, and inside each table there are columns (what properties we store) and rows (the individual records).

Take the buyers’ table users: each row is one buyer from old Earth, and the columns describe their id, full_name, email, country, city, signup_date.

So that people with the same name don’t get confused, every row has a — a unique identifier, usually the id column. Through it, other tables can reference this row using a . For example, an order in orders has a user_id — that’s how an order remembers its buyer. Those amber threads on the hologram are exactly these key-based links.

QUERY: As long as the key holds, the thread holds. A century and a half on, every order still remembers its person.

Run the query and see what Kotomarket’s buyers look like — records no one has opened since the days of the old Net:

Prvi kupci Kotomarketa v tabeli:
Query result
idfull_namecitysignup_date
1Артём ВолковСанкт-Петербург2024-10-20
2Екатерина АлексеевЕкатеринбург2025-01-25
3Николай НикитинАлматы2024-09-21
4Екатерина ИвановНовосибирск2024-05-04
5Елена ПетровКазань2025-01-05
6Ирина КузнецовНовосибирск2024-09-12

Primarni ključ pomaga brez napake najti eno vrstico (običajno id). Tuji ključ povezuje tabele: na primer orders.user_id → users.id pokaže, čigavo je naročilo. V nadaljevanju bo QUERY pred teboj razgrnil celoten zemljevid posnetka — vseh pet tabel.

usersidfull_namecityordersiduser_idstatususer_id → id
Tuji ključ orders.user_id se sklicuje na primarni ključ users.id — tako se naročilo spomni svojega kupca.

Naravni ali nadomestni ključ

Od kod izvira primarni ključ? Poti sta dve. Naravni ključ je resničen atribut, ki je itak enoličen: email kupca, ISBN knjige, koda valute. Nadomestni ključ je umeten identifikator brez pomena v zunanjem svetu: samodejno številčenje ali . V Kotomarketu se povsod uporabljajo nadomestni id — in to je tipska rešitev:

-- Nadomestni ključ: baza sama izda naslednjo številko (PostgreSQL)
CREATE TABLE users (
  id        BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  email     TEXT NOT NULL UNIQUE,  -- naravni kandidat živi ob njem kot UNIQUE
  full_name TEXT NOT NULL
);

Zakaj tako? Glavna lastnost primarnega ključa: ne sme se spreminjati. Na PK se sklicujejo tuji ključi drugih tabel, sprememba vrednosti pa bi za seboj potegnila posodobitev vseh niti naenkrat — v orders, v events, povsod. »Večnih« naravnih atributov pa skoraj ni: ljudje menjajo email in priimke, telefonske številke se preselijo, celo ISBN doživi ponatis. Nadomestni id se ne spremeni nikoli — prav zato, ker nič ne pomeni.

Zahteve za vsak primarni ključ: enoličen, ne NULL, stabilen. Naravne ključe prepusti majhnim nespremenljivim šifrantom — na primer kodi valute 'RUB' iz ISO 4217. Enoličnost naravnega kandidata, kot je email, pa zapni z ločeno omejitvijo UNIQUE, kot v zgornjem primeru: povezave se ohranijo, podatki ostanejo pošteni, in kupcu ni prepovedano zamenjati pošte.

Pogled naprej: sama sintaksa za ustvarjanje tabel in omejitev (CREATE TABLE, PRIMARY KEY, UNIQUE) je tema 9. poglavja. Tukaj glej zgradbo ključa, ne ukaza: da je nadomestni id postal primarni ključ, email pa živi ob njem kot UNIQUE.

Interview question

Vprašanje z razgovora: kako se nadomestni ključ razlikuje od naravnega in katerega boš izbral za tabelo uporabnikov?

Močan odgovor: naravni je resničen enoličen atribut (email, ISBN), nadomestni pa umeten identifikator (stolpec IDENTITY ali ). Za uporabnike — nadomestni: primarni ključ se ne sme spreminjati, ker se nanj sklicujejo tuji ključi, email pa ljudje menjajo. Enoličnost emaila pri tem zapneš z ločeno omejitvijo UNIQUE. Naravni ključ je upravičen v stabilnih šifrantih, kot so kode valut ISO 4217.

Check yourself
Čemu je v bazi namenjen tuji ključ (foreign key)?