Бази данни без мъгла

Схемата на «Kotomarket»

11 min
What you'll learn
  • да намираш нужната таблица сред петте в «Kotomarket»: users, products, orders, order_items, events
  • да четеш ER-диаграма: да определяш кардиналността на връзката (1:N, N:M, 1:1) по това къде лежи външният ключ
  • да разгръщаш връзка «много към много» през междинна таблица с два FK — като order_items с order_id + product_id
  • да обясняваш защо съставът на поръчката не може да се пази като низ от id направо в orders

Днес КВЕРИ извежда на главната маса целия опис наведнъж. Пет светещи плоскости увисват във въздуха и бавно се въртят — карта на оцелелия свят. Наблизо мъждука журналът за консервация, приложен към снимката, и един ред в него е подчертан: «Предавам пет таблици и следа от шеста. — K.» Преброяваш плоскостите. Точно пет. Къде е следата?

КВЕРИ: Не се отвличай по следи. Първо научи тези пет така, че да намираш пътя със затворени очи — останалото архивът ще ти покаже сам, когато те сметне за готов.

Петте таблици на «Kotomarket»

По-нататък ще работим с тази база — на онлайн магазин за 2024 година. Дръж я като карта на магазина: кой е дошъл, какво стои на витрината, какво са купили и какви действия са извършвали преди покупката.

ТаблицаКакво пази
usersкупувачите: id, име, град и дата на регистрация
productsстоките от витрината: id, название, категория, цена и наличност
ordersпоръчките: id, user_id, дата, статус и сума
order_itemsсъстава на поръчките: коя стока, колко бройки и на каква цена
eventsповеденческите събития: разглеждания, добавяния в количката и покупки

Връзките се четат така: един user → много orders; един order → много order_items; един product → много order_items. Ако се загубиш, отвори схемата вдясно — тя е като план на търговската зала.

Да надникнем в таблицата с поръчките: във всеки ред има user_id — препратка към купувача. Така една таблица се свързва с друга и картата престава да бъде пет отделни острова.

Пет холографски таблици-плоскости се въртят като съзвездие, свързани с нишки; встрани едва се забелязва пунктирна следа от шести контур
Картата на архива: пет таблици и връзките между тях. Журналът за консервация обещава и «следа от шеста» — но засега тя не се вижда.

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.

Поръчките и тяхната връзка с купувача през user_id:
Query result
iduser_idstatustotal_amount
118paid5980.00
210paid19750.00
326cancelled9560.00
426paid15530.00
58paid26710.00
637paid42110.00

Как се чете ER-диаграма

Картата, която разгърна КВЕРИ, в индустрията наричат ER-диаграма (entity–relationship): правоъгълниците са таблици, линиите между тях — връзки по външни ключове. Най-важното на линията е кардиналността: колко реда от едната страна съответстват на колко от другата.

  • 1:N, едно-към-много — най-честата връзка. Един купувач — много поръчки. Външният ключ винаги лежи откъм страната на «многото»: user_id се пази в orders, а не обратно. Това е правилото за четене: намери FK — намери страната N.
  • N:M, много-към-много — в една поръчка има много стоки, и една стока се среща в много поръчки. Такава връзка не може да се изрази направо в релационна база: външният ключ няма къде да се сложи. Тя се разгръща през междинна таблица — при нас това е order_items. Всеки неин ред носи двойка препратки order_id + product_id и превръща една връзка N:M в две връзки 1:N. Бонус: самата връзка получава атрибути — брой бройки и цената към момента на покупката.
  • 1:1, едно-към-едно — среща се по-рядко: например тежки или поверителни полета се изнасят в отделна таблица със същия ключ.
-- Развязка N:M в действии: пары «заказ — товар» из 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-диаграма на «Kotomarket»: връзки 1:N от users към orders и развръзка N:M между orders и products през order_items.

Капан: да пазиш състава на поръчката направо в orders — като низ '7,12,3' или масив от идентификатори. Такива данни не може да се защитят с външен ключ, да се преброят честно или да се съединят с витрината без акробатика. Видиш ли връзка «много към много» — създавай междинна таблица с два външни ключа, като order_items.

Interview question

Въпрос от интервю: как в релационна база да се реализира връзка «много към много»?

Силен отговор: през междинна таблица с два външни ключа към свързваните таблици — като order_items с order_id и product_id: тя превръща N:M в две връзки 1:N. Заедно с това в нея се пазят атрибутите на самата връзка — количество, цена към момента на покупката. Първичният ключ на такава таблица е или съставен от двата FK, или сурогатен id.

Check yourself
Къде в схемата се вижда коя стока е попаднала в коя поръчка?