Databázy bez hmly

Prvý užitočný dotaz

21 min
What you'll learn
  • písať dotazy s explicitným zoznamom stĺpcov po SELECT a filtrom riadkov cez WHERE
  • prekladať obchodnú otázku do SQL po trase: entita → FROM, obmedzenia → WHERE (s AND), výstup → SELECT, poradie → ORDER BY
  • vysvetliť, prečo je SELECT * zlou praxou v pracovných dotazoch
  • overiť dotaz prerozprávaním nahlas: ak sa prerozprávanie zhoduje s pôvodnou otázkou, dotaz je významovo správny

Mapa je preštudovaná — a QUERY mení pravidlá. Doteraz si si prezeral celý archív ako turista; archivár pracuje inak. Na holopaneli zhasne všetko okrem jednej tabuľky a objaví sa zadanie: polož otázku tak, aby v odpovedi nebol ani jeden zbytočný riadok a ani jeden zbytočný stĺpec.

Vyberáme potrebné stĺpce a riadky

Brať všetko cez * je pri prvom zoznámení pohodlné, no v reálnej práci je to ako priniesť k pokladni celý sklad. Zvyčajne potrebuješ konkrétne polia: vymenuj ich oddelené čiarkou po SELECT.

S riadkami je to rovnako: namiesto celého výkladu vyber len potrebný segment cez WHERE. Napríklad si od «Kotomarketu» vypýtame len tovary z kategórie Knihy:

Kadet zužuje jantárovým lúčom-filtrom holografický výklad: lúčom prejde len niekoľko riadkov-kapsúl s knihami
Presná otázka k archívu: SELECT pomenúva potrebné stĺpce, WHERE prepustí len potrebné riadky.

Choosing the columns and rows you need

Grabbing everything with * is convenient for a first look, but in real work it’s like hauling the entire warehouse up to the checkout. Usually you need specific fields: list them, comma-separated, after SELECT.

It’s the same with rows: instead of the whole storefront, pick only the segment you need via WHERE. For example, let’s ask Kotomarket for only the products in the Books category:

Aké knihy sú vo výklade a koľko stoja:
Query result
nameprice
SQL для профи1290.00
Чистый код1490.00
Алгоритмы на практике1690.00

Z obchodnej otázky — do dotazu

Naozajstné otázky neprichádzajú k archivárovi v SQL: «aké knihy sú lacnejšie ako tisícpäťsto?», «čo z elektroniky je drahšie ako 5000?». Preklad ide vždy po jednej trase:

  1. Entita → tabuľka. O čom je otázka: o tovaroch, zákazníkoch, objednávkach? «Knihy lacnejšie ako 1500» je o tovaroch, takže FROM products.
  2. Obmedzenia → WHERE. Každá podmienka z otázky je samostatná podmienka filtra: kategória «Knihy», cena menej ako 1500.
  3. Čo zobraziť → SELECT. Čo chce človek vidieť v odpovedi? Názov a cenu — tie aj vymenúvame, zvyšok je šum.
  4. Forma odpovede → ORDER BY. «Od lacných k drahým» je zoradenie podľa ceny.
-- «Aké knihy sú lacnejšie ako 1500 a koľko stoja, od lacných k drahým?»
SELECT name, price
FROM products
WHERE category = 'Книги' AND price < 1500
ORDER BY price;

Niekoľko podmienok sa spája slovom AND — operátory filtra podrobne rozoberieme v nasledujúcej kapitole.

A opačný zvyk dobrého archivára: prečítaj si hotový dotaz nahlas ako vetu. «Z tovarov vziať knihy lacnejšie ako 1500, zobraziť názov a cenu, zoradiť podľa ceny» — ak sa prerozprávanie zhoduje s pôvodnou otázkou, dotaz je významovo správny. Ak sa v prerozprávaní vynorí «všetky stĺpce» alebo «celý výklad» — vráť sa a zúž.

Interview question

Otázka z pohovoru: prečo sa SELECT * považuje za zlú prax v pracovných dotazoch?

Silná odpoveď: po prvé, zbytočné dáta: sieť a pamäť sa míňajú na stĺpce, ktoré nie sú potrebné, a databáza stráca možnosť odpovedať len z indexu (index-only scan; indexy — Kapitola 10). Po druhé, krehkosť: pri pridaní alebo premenovaní stĺpcov sa lámu reporty a kód, ktorý počíta so zložením a poradím stĺpcov. Explicitný zoznam stĺpcov je kontrakt dotazu; SELECT * je namieste nanajvýš pri interaktívnom skúmaní dát.

Check yourself
Čo zobrazí dotaz SELECT name FROM products WHERE category = 'Книги'?

The index has been read: you know what’s in the five tables and which threads stitch them together. QUERY dims the map, and the next clearance level lights up on the holopanel — the reading terminal.

QUERY: Remember the cardinal property of this place: the archive answers only well-formed questions. From the next clearance on, we learn to ask precisely.