SQL - Structured Query Language - II

Līdzās SQL "absolūtajam minimumam", ko aplūkojām iepriekšējā dokumentā, ir vēl vairākas ļoti noderīgas komandas. Webkursu veidotāji izsaka pateicību Gunāram Rodinam, kurš palīdzējis šī materiāla tapšanā.

Šajā dokumentā aplūkosim sekojošas komandas:

  • UPDATE
  • CREATE INDEX
  • ALTER TABLE
  • DROP TABLE
  • Komanda UPDATE

    UPDATE komanda ir paredzēta esošo datu koriģēšanai, izmainīšanai. Tās konstrukcija ir vienkārša:

    UPDATE [LOW_PRIORITY] tbl_name SET col_name1=expr1,col_name2=expr2,...
        [WHERE where_definition] [LIMIT #]
    

    Nākamais piemērs tabulā cilveks nomaina visus Ģedus Morozus uz Ziemassvētku Vecīšiem, kā arī pārsauc cilvēku kuram ir id_cilveks=1.

    UPDATE cilveks
        SET vards="Ziemassvētku",uzvards="Vecītis"
        WHERE (vards="Ģeds" AND uzvards="Morozs") OR id_cilveks=1
    

    Ar UPDATE komandu vajag uzmanīties, jo ar nepareiziem atlases parametriem (WHERE izteiksme) var viegli sabojāt lielu daudzumu datu. Tādēļ tad, ja jāmaina konkrēts ieraksts, parasti lieto unikālo identifikatoru jeb tabulas primāro atslēgu (parasti šo lauku sauc id_tabulasvārds).

    Atsauces

    1. UPDATE citas iespējas un parametrus sk. MySQL dokumentāciju UPDATE syntax.

    Komanda CREATE INDEX

    Šī komanda veido indeksus tabulām. Galvenais iemesls, kāpēc ir tāda iespēja - lai taupītu vietu un paārtrinātu meklēšanu. Tas izraisa zināmas grūtības meklēšanā ar SELECT kā arī datu sasaistes brīžos, bet ļoti atmaksājas jau tabulām, kurās ir vairāk kā 10 000 ieraksti. CREATE INDEX ir vecais stils kā definēt indeksus tabulai, tas ir SQL standarts:

    CREATE [UNIQUE] INDEX index_name ON tbl_name (col_name[(length)],... )
    

    piemēram,

    CREATE INDEX name ON cilveks (uzvards,vards)
    

    Bet ir arī drusku modernāks stils, tad indeksus definē tabulas veidošanas momentā. Tas tiek atbalstīts tikai jaunākajās datubāzu vadības sistēmu versijās:

    CREATE TABLE cilveks (
        id_cilveks INT NOT NULL,
        vards CHAR(30) NOT NULL,
        uzvards CHAR(30) NOT NULL,
        PRIMARY KEY (id_cilveks),
        INDEX name (uzvards,vards));

    Standartuzdevums, kuru risina tabulu indeksi, ir datu redundances novēršana, jeb, vienkārši sakot, datu neatkārtošanās. Kā pareizi dalīt informāciju, kā sasaistīt savā starpā šos datus, tā savukārt ir datu normalizācijas teorija. Otrs pamatuzdevums, ko risina indeksi, ir klasifikatoru uzturēšana. Klasifikators - ir maz mainīga datu kopa, kuru bieži lieto.

    Piemēram eksāmena novērtējums 10-ballu sistēmā (no 1-"bezcerīgs gadījums" līdz 10-"GURU"), katram eksāmena kārtotājam jābut obligāti kādai atzīmei, un lai nebūtu pārpratumu, novērtējot piemēram viens novērtējumu "LABI" raksta ar atzīmi 6, cits ar 7. Lai tā nenotiktu, var uztaisīt visiem vienotu vērtējumu sistēmu, kā izvēli no noteiktām vērtībām, un visi tad dabū vērtēt vienādi.

    Izklāstīšu pamatideju par tabulu veidošanu. Tipisks uzdevums - jums vajag glabāt cilvēku pierakstus pēc dzīvesvietas. Ienākošie dati ir sekojoši:

    1) Miki Mausis , Latvija, Rīga, Kino iela 1-1
    2) Donalds Daks , Latvija, Rīga, Kino iela 1-1
    

    Mēs šos datus mākam iztulkot un iesākumā tos varētu dalīt jēdzieniski loģiskās vienībās, uzskatot ka katrai personai noteikti ir adrese.

    NPKCILVEKSADRESE
    1Miki MausisLatvija, Rīga, Kino iela 1-1
    2Donalds Daks Latvija, Rīga, Kino iela 1-1

    Daudzi pie šāda sadalījuma arī apstājas un smalkāk šo informāciju nedala. Starp citu, parasti šo pirmatnējo sadalījumu izmanto, lai veidotu tabulu nosaukumus un satura skices (tas ir lai izdomātu kādas tabulas ko glabās), mūsu gadījumā ir viegli redzams, ka būs divas tabulas - viena par personu un otra par adresi. Šīs informācijas vienības viegli dalās apakšlīmeņos, jo tā ir pēc būtības strukturēta informācija. Mūsu mērķis ir izveidot pēc iespējams strukurētāku informācijas loģisko sadalījumu. No augstāk minētās informācijas mēs iegūstam sekojošu struktūras detalizāciju.

    ID_CILVEKSUZVARDSVARDSVALSTS PAGASTS/PILSETAIELANR_DZ
    1MikiMausisLatvijaRīgaKino1-1
    2DonaldsDaksLatvijaRīgaKino1-1

    No šīs iegūtās sadalījuma informācijas redzams, ka abām minētajām personām ir vienādas adreses. Tātad viena adrese uz 2 personām (to sauc par 1-N (lasās viens pret N) saiti). Tātad sasaiti veidojam tā , ka cilvēkam noteikti ir adrese, nevis adresei ir noteikti viens cilvēks. (Adrese var eksistēt arī bez tā ka tur kāds ir pierakstīts - neapdzīvota platība). Tātad taisam divas tabulas, kur cilvēks ir piesaistīts adresei:

    Tabula: cilveks
    ID_CILVEKSINT NOT NULL
    VARDSCHAR(30) NOT NULL
    UZVARDSCHAR(30) NOT NULL
    ID_ADRESEINT NOT NULL DEFAULT -1

    Jūs jautāsiet, kāpēc pie lauka ID_ADRESE ir noklusētā vērtība "-1". Tas tiek darīts tādēļ, lai paredzētu gadījumu, kad mēs nezinām konkrētu adresi kur pierakstīts cilvēks, bet piesaistītam viņam jābūt pēc atrunas. Tāpēc veidojot visus klasifikatorus (tabulas), tajos ieliek aizpildītu ierakstu ar indeksu -1. Teiksim jūs izveidotjat ierakstu par cilvēku, bet konkrētu adresi izvēlaties kaut kad vēlāk, kad adrese ir ievadīta vai arī noskaidrota ir cilvēka pieraksta vieta.

    Tabula: adrese
    ID_ADRESEINT NOT NULL
    VALSTSCHAR(50) NOT NULL
    PILSETACHAR(50) NOT NULL
    IELACHAR(50) NOT NULL
    NR_DZCHAR(10) NOT NULL

    Protams, normāli būtu, ka mēs turpinātu strukturēt informāciju, un teiksim izveidotu atseviški klasifikatorus (citas tabulas) priekš Valstu, Pilsētu, Ielu uzglabāšanas, lai ar šī informācija gan ir apjomīga, toties bieži atkārtojas. (Bet to mēs nedarīsim, jo esmu par slinku! :-) SQL skripts šīm tabulām izskatītos sekojoši:

    DROP TABLE IF EXISTS cilveks,adrese;
    CREATE TABLE adrese (
               id_adrese INT NOT NULL,
               valsts CHAR(50) NOT NULL,
               pilseta CHAR(50) NOT NULL,
               iela CHAR(50) NOT NULL,
               nr_dz CHAR(10),
               PRIMARY KEY (id_adrese));
    CREATE TABLE cilveks (
               id_cilveks INT NOT NULL,
               vards CHAR(30) NOT NULL,
               uzvards CHAR(30) NOT NULL,
               id_adrese INT REFERENCES adrese.id_adrese);
    
    INSERT INTO adrese (id_adrese,valsts,pilseta,iela,nr_dz)
           VALUES (1,"Latvija","Rīga","Kīno","1-1");
    
    INSERT INTO cilveks (id_cilveks,vards,uzvards,id_adrese)
           VALUES (1,"Miki","Mausis",1);
    
    INSERT INTO cilveks (id_cilveks,vards,uzvards,id_adrese)
           VALUES (2,"Donalds","Daks",1);
    

    Atsauces

    1. Indeksēšanas citas iespējas un parametrus sk. MySQL dokumentācijā: CREATE INDEX syntax.

    Komanda ALTER TABLE

    ALTER TABLE nodrošina esošo tabulu modificēšanu, tas ir pielikt, izmest laukus un ideksus, kā arī pamainīt visādus parametrus laukiem un indeksiem, kaut vai lauku nosaukumus. Var arī mainīt pašas tabulas nosaukumu, piemēram:

    ALTER TABLE cilveks RENAME persona;
    

    Vai, teiksim, nomainīt kādu lauku garumus (MODIFY maina parametrus nemainot nosaukumu, bet CHANGE maina lauka nosaukumu un reizē parametrus):

    ALTER TABLE persona MODIFY vards CHAR(50) NOT NULL, CHANGE uzvards uzv CHAR(50) NOT NULL;
    

    Lai varētu izmantot komandu ALTER TABLE, jums jābūt select, insert, delete, update, create, drop tiesībām. Parastie lietotāji izmanto ārkārtīgi reti, to parasti dara (tas atļauts) tikai datubāzu administrātoram, jo šīs strukturālās izmaiņas izraisīt datubāzes nobrukšanu, datu pazušanu vai sabojāšanos. Šādas izmaiņas, pirms tās tiek veiktas, rūpīgi analizē un apzina visas iespējamās problēmas, kas saistās ar šīm izmaiņām.

    Dažām datubāzēm ir iespaidīga papildiespēja (feature) - trigeri, tās ir SQL valodā rakstītas procedūras, kas glabājas uz SQL servera, un ko piesaista kaut kādiem notikumiem. Piemēram pie datu noglabāšanas, reģistrēt izmaiņas, kā arī tā datumu, laiku un lietotāju kas to veicis. Trigerus apšmaukt nevar, tāpēc tie ir ļoti labs mehānisms. Bet ja ir izmainīts kāds reģistrācijas lauka nosaukums vai tips, tad trigeris nespēj normāli bez modifikācijām strādāt radot milzu problēmas. Tāpēc ar datubāzes struktūrām parasti spēlējas tikai viens cilvēks - datubāzes administators.

    Atsauces

    1. ALTER TABLE citas iespējas un parametrus sk. MySQL dokumentācijā ALTER TABLE syntax.

    Komanda DROP TABLE

    DROP TABLE komanda ir paredzēta esošo tabulu iznīcināšanai. Iznīcinot tabulu, iznīcinās arī visi dati kas tajā glabājās. Komanda ir pati vienkāršākā un VISBĪSTAMĀKĀ SQL valodā, bet par laimi šī komanda parasti atļauta tikai datubāzes administratoram. Tās sintakse ir šāda:

    DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...]

    Opcija IF EXISTS bieži lieto, jo, ja kāda tabula no esošā saraksta neeksistē, tad SQL serveris neapstāsies ar kļūdas paziņojumu bet izmetīs tās tabulas, kuras eksistē, pretējā gadījumā visa komandas darbība tiek apurēta. Tā kā šo komandu parasti lieto administrēšanas skriptos/procedūrās/funkcijās, un ja kāda šī komanda nenostrādā, visa skripta/procedūras/funkcijas darbība tiek pārtraukta. Piemērs:

    DROP TABLE IF EXISTS cilveks,adrese
    

    Tāpat kā ar delete komandu, jums var rasties problēmas izdzēst tabulu dēļ indeksiem, ja uz kādu šīs tabulas lauku ir atsauce citā tabulā vai ierakstā (INDEXi), jums SQL serveris izdos kļūdu. Mūsu piemērā par cilvēku un adresi, nevarēs izdzēst tabulu adrese, jo uz to atsaucās cilvēka tabulā lauks id_adrese. Vienīgais veids kā šo problēmu risina ir, ka visas tabulas kas referējas uz šo dzēšamo tabulu, jānoņem sasaiste (INDEX). To parasti dara ar ALTER TABLE, jo tā ir datu bāzes strukturāla izmaiņa.

    ALTER TABLE cilveks DROP COLUMN id_adrese;
    DROP TABLE IF EXISTS adrese;
    

    Atsauces

    1. DROP TABLE citas iespējas un parametrus sk. MySQL dokumentācijā: DROP TABLE syntax.

    Lapa mainīta 2004-11-15 22:35:00