Duomenų bazės be miglos

„Kotomarket“ schema

11 min
What you'll learn
  • rasti reikalingą lentelę tarp penkių „Kotomarket“: users, products, orders, order_items, events
  • skaityti ER diagramą: nustatyti ryšio kardinalumą (1:N, N:M, 1:1) pagal tai, kur yra išorinis raktas
  • išskleisti ryšį „daug su daug“ per tarpinę lentelę su dviem FK — kaip order_items su order_id + product_id
  • paaiškinti, kodėl užsakymo sudėties negalima saugoti id eilute tiesiog orders lentelėje

Šiandien QUERY ant pagrindinio stalo iškart išveda visą aprašą. Penkios švytinčios plokštumos pakimba ore ir lėtai sukasi — išlikusio pasaulio žemėlapis. Greta mirga prie kopijos pridėtas konservavimo žurnalas, ir viena eilutė jame pabraukta: „Perduodu penkias lenteles ir šeštosios pėdsaką. — K.“ Tu perskaičiuoji plokštumas. Lygiai penkios. Kur pėdsakas?

QUERY: Neblaškyk dėmesio į pėdsakus. Pirmiausia išmok šias penkias taip, kad rastum kelią užsimerkęs, — likusią archyvas parodys pats, kai nuspręs, kad esi pasiruošęs.

Penkios „Kotomarket“ lentelės

Toliau dirbsime su šia baze — 2024 metų internetinės parduotuvės kopija. Laikyk ją kaip parduotuvės žemėlapį: kas atėjo, kas guli ant vitrinos, ką nupirko ir kokius veiksmus atliko prieš pirkimą.

LentelėKą saugo
userspirkėjus: id, vardą, miestą ir registracijos datą
productsvitrinos prekes: id, pavadinimą, kategoriją, kainą ir likutį
ordersužsakymus: id, user_id, datą, statusą ir sumą
order_itemsužsakymų sudėtį: kokia prekė, kiek vienetų ir kokia kaina
eventselgsenos įvykius: peržiūras, įdėjimus į krepšelį ir pirkimus

Ryšiai skaitomi taip: vienas user → daug orders; vienas order → daug order_items; vienas product → daug order_items. Jei pasiklysi, atsiversk schemą dešinėje — ji it prekybos salės planas.

Užmesim akį į užsakymų lentelę: kiekvienoje eilutėje yra user_id — nuoroda į pirkėją. Taip viena lentelė susiejama su kita, ir žemėlapis nustoja būti penkiomis atskiromis salomis.

Penkios holografinės lentelės-plokštumos sukasi kaip žvaigždynas, sujungtos gijomis; nuošalyje vos įžiūrimas punktyrinis šeštojo kontūro pėdsakas
Archyvo žemėlapis: penkios lentelės ir ryšiai tarp jų. Konservavimo žurnalas žada dar ir „šeštosios pėdsaką“ — bet kol kas jo nematyti.

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.

Užsakymai ir jų ryšys su pirkėju per user_id:
Query result
iduser_idstatustotal_amount
118paid5980.00
210paid19750.00
326cancelled9560.00
426paid15530.00
58paid26710.00
637paid42110.00

Kaip skaityti ER diagramą

Žemėlapį, kurį išskleidė QUERY, industrijoje vadina ER diagrama (entity–relationship): stačiakampiai — lentelės, linijos tarp jų — ryšiai per išorinius raktus. Svarbiausia linijoje — kardinalumas: kiek eilučių iš vienos pusės atitinka kiek eilučių iš kitos.

  • 1:N, vienas su daugeliu — dažniausias ryšys. Vienas pirkėjas — daug užsakymų. Išorinis raktas visada guli „daugelio“ pusėje: user_id saugomas orders, o ne atvirkščiai. Tai ir yra skaitymo taisyklė: radai FK — radai N pusę.
  • N:M, daug su daugeliu — viename užsakyme daug prekių, ir viena prekė pasitaiko daugelyje užsakymų. Tiesiogiai tokio ryšio reliacinėje bazėje išreikšti negalima: išorinio rakto nėra kur padėti. Jis išskleidžiamas per tarpinę lentelę — pas mus tai order_items. Kiekviena jos eilutė neša porą nuorodų order_id + product_id ir paverčia vieną N:M ryšį dviem 1:N ryšiais. Premija: pats ryšys įgyja atributų — vienetų kiekį ir kainą pirkimo metu.
  • 1:1, vienas su vienu — pasitaiko rečiau: pavyzdžiui, sunkūs ar privatūs laukai iškeliami į atskirą lentelę su tuo pačiu raktu.
-- N:M išrišimas veikiant: poros „užsakymas — prekė“ iš 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)
„Kotomarket“ ER diagrama: 1:N ryšiai nuo users prie orders ir N:M išrišimas tarp orders ir products per order_items.

Spąstai: saugoti užsakymo sudėtį tiesiog orders — eilute '7,12,3' arba identifikatorių masyvu. Tokių duomenų negalima apsaugoti išoriniu raktu, sąžiningai suskaičiuoti ar sujungti su vitrina be akrobatikos. Matai ryšį „daug su daug“ — kurk tarpinę lentelę su dviem išoriniais raktais, kaip order_items.

Interview question

Klausimas iš pokalbio: kaip reliacinėje bazėje įgyvendinti ryšį „daug su daug“?

Stiprus atsakymas: per tarpinę lentelę su dviem išoriniais raktais į siejamas lenteles — kaip order_items su order_id ir product_id: ji paverčia N:M dviem 1:N ryšiais. Kartu joje saugomi paties ryšio atributai — kiekis, kaina pirkimo metu. Tokios lentelės pirminis raktas — arba sudėtinis iš dviejų FK, arba surogatinis id.

Check yourself
Kur schemoje matyti, kokia prekė pateko į kokį užsakymą?