Andmebaasid ilma uduta

Tabelid, read ja võtmed

11 min
What you'll learn
  • eristama tabeleid, ridu ja veerge ning selgitama, milleks on igale reale vaja primaarvõtit (tavaliselt id)
  • leidma tabelite vahelisi seoseid välisvõtme järgi: orders.user_id → users.id
  • eristama surrogaatvõtit (IDENTITY, ) naturaalsest (email, ISBN) ja põhjendama, miks primaarvõti ei tohi muutuda
  • kinnistama välja nagu email unikaalsust piiranguga UNIQUE, tegemata seda primaarvõtmeks

Inventuur on avatud. QUERY avab töölaua kohale holograammi: tuhanded kirjed ripuvad õhus ühtlase võrguna ja mõnede vahel jooksevad õhukesed merevaigukollased niidid. Sirutad käe ühe poole — see heliseb nagu keel. See pole failihunnik. See on kangas.

Tabelid, read, veerud

Relatsiooniline andmebaas sarnaneb korraliku kataloogiga: andmed on jaotatud tabelitesse ja iga tabeli sees on veerud (milliseid omadusi me hoiame) ja read (konkreetsed kirjed).

Võta ostjate tabel users: iga rida on üks vana Maa ostja ja veerud kirjeldavad tema id, full_name, email, country, city, signup_date.

Et mitte segi ajada ühesuguste nimedega inimesi, on igal real primaarvõti () — unikaalne identifikaator, tavaliselt veerg id. Selle kaudu saavad teised tabelid sellele reale viidata välisvõtme () abil. Näiteks tellimuses orders on user_id — nii mäletab tellimus oma ostjat. Needsamad merevaigukollased niidid holograammil ongi seosed võtmete kaudu.

QUERY: Kuni võti on terve, on niit terve. Poolteist sajandit on möödunud, ja iga tellimus mäletab ikka veel oma inimest.

Käivita päring ja vaata, millised näevad välja „Kotomarketi“ ostjad — kirjed, mida keegi pole avanud vana Võrgu aegadest:

Holograafiline tabel kapsel-ridadest ja veergudest; tellimuste kirjetest inimeste kirjeteni jooksevad merevaigukollased võtmeniidid
Read on kirjed, veerud nende omadused, ja niit tellimusest ostjani on seos võtme kaudu.

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:

„Kotomarketi“ esimesed ostjad tabelis:
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

Primaarvõti aitab eksimatult leida ühe rea (tavaliselt id). Välisvõti seob tabeleid: näiteks orders.user_id → users.id näitab, kelle tellimus see on. Edasi avab QUERY su ees kogu tõmmise kaardi — viis tabelit tervikuna.

usersidfull_namecityordersiduser_idstatususer_id → id
Välisvõti orders.user_id viitab primaarvõtmele users.id — nii mäletab tellimus oma ostjat.

Naturaalne või surrogaatvõti

Kust tuleb primaarvõti? Teid on kaks. Naturaalne võti on reaalne atribuut, mis on niigi unikaalne: ostja email, raamatu ISBN, valuutakood. Surrogaatvõti on tehislik identifikaator, millel pole välismaailmas tähendust: automaatne nummerdus või . „Kotomarketis“ kasutatakse kõikjal surrogaatseid id-sid — ja see on tüüplahendus:

-- Surrogaatvõti: andmebaas annab ise välja järgmise numbri (PostgreSQL)
CREATE TABLE users (
  id        BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  email     TEXT NOT NULL UNIQUE,  -- натуральный кандидат живёт рядом как UNIQUE
  full_name TEXT NOT NULL
);

Miks nii? Primaarvõtme põhiomadus: see ei tohi muutuda. PK-le viitavad teiste tabelite välisvõtmed ja väärtuse muutmine tooks kaasa kõigi niitide korraga uuendamise — tabelis orders, tabelis events, kõikjal. „Igaveseid“ naturaalseid atribuute aga peaaegu polegi: inimesed muudavad emaili ja perekonnanime, telefonid kolivad, isegi ISBN-e antakse uuesti välja. Surrogaatne id ei muutu kunagi — just seepärast, et see ei tähenda midagi.

Nõuded igale primaarvõtmele: unikaalne, mitte NULL, stabiilne. Naturaalsed võtmed jäta väikestele muutumatutele teatmikele — näiteks valuutakoodile 'RUB' ISO 4217-st. Naturaalse kandidaadi nagu email unikaalsust aga fikseeri eraldi piiranguga UNIQUE, nagu ülaltoodud näites: seosed säilivad, andmed jäävad ausaks ja ostjal pole keelatud oma emaili muuta.

Vaatame ette: tabelite ja piirangute loomise süntaks ise (CREATE TABLE, PRIMARY KEY, UNIQUE) on 9. peatüki teema. Siin vaata võtme struktuuri, mitte käsku: et surrogaatne id sai primaarvõtmeks ja email elab kõrval kui UNIQUE.

Interview question

Küsimus vestlusel: mille poolest erineb surrogaatvõti naturaalsest ja millise sa valid kasutajate tabeli jaoks?

Tugev vastus: naturaalne — reaalne unikaalne atribuut (email, ISBN), surrogaatne — tehislik identifikaator (IDENTITY-veerg või ). Kasutajate jaoks — surrogaatne: primaarvõti ei tohi muutuda, sest sellele viitavad välisvõtmed, emaili aga inimesed muudavad. Emaili unikaalsus fikseeritakse seejuures eraldi UNIQUE-piiranguga. Naturaalne võti on õigustatud stabiilsetes teatmikes nagu ISO 4217 valuutakoodid.

Check yourself
Milleks on andmebaasis vaja välisvõtit (foreign key)?