Fara í innihald

SQL

Úr Wikipediu, frjálsa alfræðiritinu

SQL (skammstöfun fyrir „Structured Query Language“) er mjög algengt fyrirspurnarmál sem notað er til að búa til, vinna með og sækja gögn úr gagnagrunnum.

Auk grunn SQL bjóða margir framleiðendur gagnagrunnskerfa sérstök stefjumál mál svo sem Transact-SQL fyrir Microsoft SQL Server, PL/SQL fyrir Oracle og PostgreSQL hefur mál, PL/pgSQL, keimlíkt þeirra. Líka hefur mál, SQL/PSM, verið staðlað. Þessi mál eru stundum notuð til að búa til föll og stefjur sem keyra í grunninum sjálfum. IBM Db2 hefur eigið mál, sem er líkt þeim staðli. Sumir grunnar, hafa ekki haft stefjumál um árabil, enda er hægt í flestum tilvikum að komast hjá því að nota, og nota grunn SQL eingöngu. Þetta átti við um MySQL, sem á endanum fékk stefjumál.

SQL málið er ANSI og ISO staðlað (fyrst staðlað 1986, svo í mörgum útgáfum: t.d. SQL-92, þá án t.d. stefjumálsins). Framleiðendur gagnagrunnskerfa útfæra SQL oft á mismunandi hátt (flest kerfi uppfylla SQL-92 hið minnsta, en sennilega nær enginn nýjustu staðla fá að fullu upp í SQL:2016), jafnvel sama gamla staðalinn eða hafa hið minnsta ekki tekið inn nýlegar breytingar, og stundum með því að bæta við eiginleikum sem ekki eru tilgreindir í stöðlunum (sem gerir færanleika forrita milli gagnagrunna erfiðan, hið minnsta ef nýlegir fídusar eru notaður sem aðrir hafa ekki enn uppfyllt).

SQL notast við þrígilda lógik (e. three-valued logic (3VL) (true/false/unknown)) þ.e. ekki "Boolean" (ísl. Búlska) lógík (eingöngu), sem notast bara við satt og ósatt. Þriðju möguleikinn, sá "óþekkti", sem er ekki í Boolean lógík, gengur undir nafninu NULL í SQL. Þ.e. hægt er að athuga sem dæmi, ekki aðeins er_í_sambúð = true, eða er_í_sambúð = false (sumir grunnar leyfa t.d. 't' og 'f' í stað true og false), heldur líka er_í_sambúð IS NULL (eða er_í_sambúð IS NOT NULL), og fá þannig fram þá sem ekki er vitað um (eða hefur ekki enn verið skráð um í gagnagrunninn). Í mörgm tilvikum viljum við ekki þurfa að huga að þeim möguleika, sem flækir réttar fyrirspurnir; þá þvingum við fram að ekki sé hægt að skrá NULL (sem sjálfgefið gildi ef ekki talið upp í INSERT skipun, en skilar annars villu með þessum fyrirvara, sem forrit ætti að grípa), til að byrja með, í viðkomandi svæði í grunninum, með því að skilgreina þau sem NOT NULL í CREATE skipun (eða breyta eftirá með ALTER). NOT NULL er sjálfgefið fyrir PRIMARY KEY svæði, svæði sem töflur ættu að hafa skilgreint (annars er réttleiki ekki tryggður). Einnig er hægt að skilgreina önnur einkvæm svæði með UNIQUE skigreiningu.

Flestir SQL gagnagrunnar eru "strang-tagaðir", ein af fáum undantekningum er SQLite. Hann er líka sérhæfður "embedded" gagnagrunnur (látinn fylgja með öðrum forritum, jafnvel stýrikerfum, sem nota, t.d. macOS í tilfelli SQLite), ekki hugsaður sem "fjölnotenda" (ólíkt flestum SQL grunnum), þ.e. hver grunnur er ekki notaður af mörgum notendum í einu. Hins vegar er eitt eintak keyrandi t.d. í mörgum vöfrum, og þar með t.d. í nær öllum smartsímum, svo samanlagður notendafjöldi er himinhár og SQLite vinsælasti gagnagrunnur í heimi, meira notaður en þessir hefbundu (sem eru t.d. notaðir af bönkum út um allan heim).

SQL skipanir skilgreina ekki hvernig á að framkvænma ákveðnar aðgerðir, heldur hvað eigi að gera. Samkvæmt SQL staðli verða þær að enda á semíkommu (en þó krefjast ekki allir gagnagrunnar að þær fylgi með).

Dæmi um mjög einfalda SQL skipun er

SELECT nafn, heimili, postnumer 
FROM vidskiptamenn;

Ofangreind skipun sækir gögn úr töflunni vidskiptamenn. Engar takmarkanir eru setta við því hvaða færslur eru sóttar, þannig að allar færslurnar sem eru í töflunni verða sóttar. Ekki er gerð nein krafa um í hvaða röð færslurnar eiga að koma þannig að þær geta komið í hvaða röð sem er, og röðin getur hæglega breyst frá fyrirspurn til fyrirspurnar.

Fyrirspurnin:

SELECT nafn, heimili, postnumer 
FROM vidskiptamenn
WHERE postnumer = '101'
ORDER BY heimili, nafn;

myndi hins vegar alltaf skila færslum í röð eftir heimili og innan heimilisfangs í nafnaröð. Einnig takmarkar þessi fyrirspurn færslur við þá sem búa í póstnúmeri 101.

Til þess að útbúa töflur notum við CREATE skipunina:

CREATE TABLE vidskiptamenn
(vskm_numer varchar(10) CONSTRAINT pk_vskm PRIMARY KEY,
 nafn varchar(100) NOT NULL,
 heimili varchar(100), 
 postnumer char(3)
);

Lykilorð eins og CREATE geta verið hvort heldur sem er í há eða lágstöfum. Hér er búin tafla sem heitir vidskiptamenn og sett á hana þau skilyrði að dálkur sem kallast vskm_numer sé lykill að færslum í töflunni. Einnig er sett það skilyrði að nafn verður alltaf að vera tilgreint.

Gögn eru sett inn í töflur með INSERT skipunum. Dæmi.

INSERT INTO vidskiptamenn (vskm_numer, nafn, heimili, postnumer)
VALUES ('VSK001', 'Nýja Búðin', 'Austurstræti 1', '101');

Engin skylda er að lykilorðin séu með stórum staf, en margir vilja að þau séu áberandi. Gagnatögin ("gagnatýpurnar") t.d. CHAR or VARCHAR (strangt til tekið ekki lykilorð), er smekksatriði hvort séu líka með stórum en oft haft með litlum líkt of dálkaheitin. Flestir grunnar hafa VARCHAR, alla vega undir öðru nafni, en t.d. nafn hér að ofan geymir þannig ekki alltaf jafn mörg bæti til að spara pláss, á meðan CHAR fyllir upp í aftan á strengi með bilum og eyðir diskplássi. Sumir grunnar, t.d. PostgreSQL, leyfa að skilgreina ný gagnatög; sem dæmi gæti "kennitala" verið notað í stað char(10), sem þó er mjög algengt að nota (en aldrei gagnatag fyrir tölur, því þær tína núllum framan af "textastrengjum"). Meira gagnleg ný gagnatög væri POINT (sem geymir x, y eða x, y og z), ekki af því að miklu máli skiptir að geyma hnit sem "object" upp á hraða við t.d. skráningu, eða að sem object tækju gögn minna pláss (gerir það sennilega ekki), heldur í sumum grunnum, eru til dæmis indexar á meira en gögn í einni vídd. Það getur skipt miklu máli við uppflettingu á gögnum í sérhæfðum kerfum, t.d. landupplýsingakerfum.

Valkostir í stað SQL (sem sumir hverjir virka með sömu SQL gagnagrunnunum því þeir "þýða" yfir í SQL), eru t.d. LINQ, Java Persistence Query Language (JPQL), Object Query Language, XQuery og fleiri. Margir staðlanna eru sögulega áhugaveðir mögulega úreldir eða voru gerðir til að leysa SQL af hólmi en hafa ekki enn gert að nokkru ráði: Tutorial D, Datalog, IBM Business System 12 (IBM BS12), QBE (Query By Example) búið til af Moshè Zloof hjá IBM 1977 og Quel (frá 1974; U.C. Berkeley Ingres project).

Til eru svokallaðir NoSQL gagnagrunnar (nýrri en SQL grunnar, en "fræðin" á bak við þá ef svo má kalla, er í einhverjum tilvikum lík "network" grunnum sem SQL/venslagrunnarnir leystu af hólmi), stundum kallaðir not only SQL, því sumir "noSQL" grunnar styðja nú líka SQL. Þetta er flokkur mismunandi gagnagrunna (t.d. "key-value" ein tegund og "graph" önnur), sem upphaflega studdu ekki SQL, og hefðbundið innihalda "unstructured" gögn. Sem flokkur hafnaði þessi tegund grunna SQL og að einhverju eða öllu leiti, venslagrunnsfræðum (og "normaliseringu"), sem óþörfum, eða að þau ættu aðeins vel við fyrir gögn á ákvenu formi ("structured" gögn). Uppbygging þeirra er önnur og notendur/forritarar nálgast þá/hanna á annan hátt. T.d. er fyrirspurnamálið (frá þeirra upphafsdögum) ekki SQL, og niðurstaðan úr fyrirspurn í þá hefbundið ekki "tafla" (sem SQL grunnar skila), en getur verið á nokkrum mismunandi formum eftir tegund þeirra, en oftast er boðið upp á eina tegund niðursöðu sem líklegast á JSON (eða álíka) formi. Þar sem SQL fyrirspurnamálið hefur sína kosti, er í auknum mæli að framleiðendur bæti þeim möguleika við. Á sama hátt hafa framleiðendur SQL/venslagrunna bætt við "noSQL" möguleika. Annað hvort einhverju með svipað notagildi eða með sömu forritaskilum (og t.d. MongoDB, einum af vinsælu noSQL grunnunum, einn af upphaflegu). PostgreSQL hefur t.d. bætti við JSON gagnatagi (og JSONB, B fyrir "binary", hliðstætt við BSON í MongoDB).