Žymos archyvas: sql

Universalūs darbo su dbvs įrankiai

Programuojant dažnai tenka naudoti įrankius, palengvinančius darbą su duomenų bazėmis: sql užklausų rašymui ir vykdymui, db struktūros analizei, duomenų, saugomų db, peržiūrai. Duomenų bazių valdymo sistemų gamintojai pateikia įrankius, skirtus dirbti su jų kūriamomis sistemomis, tačiau programuotojui dažnai to nepakanka: jam tenka atlikti veiksmus su skirtingų gamintojų dbvs, todėl ieškoma universalių įrankių. Šiame straipsnelyje aptarsime vertus dėmesio įrankius, skirtus darbui su duomenų bazėmis.

1. DbVisualizer – universalus Java kalba parašytas, taigi nepriklausomas nuo sisteminės platformos įrankis, palaikantis populiariausias dbvs: MySQL, Oracle, SQL Server, DB2, JavaDB, Sybase, PostgreSQL ir daugelį kitų, tereikia turėti duomenų bazės, su kuria norime dirbti Java tvarkykles (populiariausių dbvs tvarkyklės eina kartu su DbVisualizer programa).
Savybės:
sql sakinių valdymas (nemokamoje versijoje vienu metu galima vykdyti tik vieną sakinį):

db lentelių savybių peržiūra (bendra informacija, stulpeliai, duomenys, raktai, indeksai, sąryšiai):
db bazės struktūros peržiūra: sąryšiai tarp visų, arba pasirinktų lentelių, pateikiami redaguojama diagrama, kurią galima eksportuoti kaip paveikslėlį:DbVizualizer patogu naudoti, kai turime priėjimą prie duomenų bazės, arba pakanka išeksportuoti db schemą kaip paveikslėlį.

2. SchemaSpy – įrankis taip pat parašytas Java kalba, taigi nepriklausomas nuo naudojamos os, platinamas kaip atskira jar byla (nereikalingas diegimas). Tai įrankis veikiantis iš komandinės eilutės, kurio rezultatas yra katalogas su html bylomis, kuriose išeksportuojama db struktūra, sąryšiai tarp lentelių (jei norime vizualių, reikia turėti įsidiegus papildomą įrankį). Tam, kad būtų atliktas eksportas tereikia paleisti komandinę eilutę ir joje įvykdyti panašią komandą:

java -jar schemaSpy_3.1.1.jar -cp kelias_iki_db_draiverio -t db_tipas -o rezultatų_vieta -host serveris -db db_vardas -u vartotojas -p slaptazodis

greita ir patogu, ypač tada, kai dažnai tenka keisti db struktūrą, arba reikia turėti informaciją apie db, neturint tiesioginio prisijungimo prie jos.

Pagrindinis SchemaSpy sugeneruotas puslapis:

Schema spy sugeneruotas lentelės sąryšių vaizdas:

3. SQL Explorer – pačios geriausios pasaulyje IDE Eclipse plugin’sas, skirtas darbui su duomenų bazėmis :) Įrankis, kurio, kaip ir aukščiau minėtų sistemų palaikomų db sąrašas ribojamas tik turimų dbvs tvarkyklių rinkinys. Leidžia vykdyti sql sakinius, peržiūrėti db struktūrą, nepaliekant gimtosios IDE – labai patogu ir paprasta!

Straipsnyje paminėti įrankiai, labiausiai bus priimtini programuotojams, dirbantiems su Java, kalba – juk jie geriausiai nusimano apie JDBC tvarkykles, tačiau, manau, visai verta būtų juos pabandyti ir kitiems, pavyzdžiui, php programuotojams, kurie taip myli phpMyAdmin :)

sudėtiniai pirminiai lentelių raktai

Kuriant duomenų bazės struktūrą, verta nurodyti pirminius lentelių raktus. Didžioji dalis taip ir daro: sukuria sveikojo skaičiaus tipo stulpelį, pavadina jį „id“, arba „lenteleles_pavadinimas_id“, ir nurodo, jog į jį bus rašomos automatiškai inkrementuojamos reikšmės. Pavyzdžiui (mySQL):

create table customers(
id int not null auto_increment,
/* ...*/
primary key(id)
);

viskas atrodo gražu ir paprasta, tačiau ar visada prasminga ir efektyvu? Pirminis raktas turi vienareikšmiškai apibūdinti DB lentelės eilutę. Automatiškai sugeneruotas id tai daro, tačiau tai yra sintetinis būdas padaryti duomenys unikaliais. Reikia nepamiršti, kad pirminis raktas gali būti ne tik natūralus skaičius, tačiau ir tekstiniai duomenys, data, bei kelių stulpelių rinkinys (šiuo atveju raktas vadinamas sudėtiniu), vienareikšmiškai apibūdinantis esybę:

/* .. */
primary key(col1, col2);
/* .. */

Panagrinėkime realią, dažnai praktikoje sutinkamą situaciją: turime lentelę, kurioje saugome klientų duomenis (apibrėžta aukščiau) ir produktų lentelę:

create table products(
/* .. */
primary key(id)
);

mums šiuo atveju visiškai neįdomu, kaip sudaryti šių lentelių pirminiai raktai. Norime suprojektuoti duomenų bazės lentelę, skirtą saugoti, tarkime apribojimams, kuriuos turi klientai, norintys įsigyti mūsų produkcijos. Čia turime sąryšį daug su daug (m su n). Natūralu, kad šiems duomenims saugoti kursime atskirą sąryšio lentelę products_customers, kurioje yra apibrėžti išoriniai raktai į produktų ir klientų lenteles, bei stulpelis, skirtas saugoti mus dominantiems apribojimams. Taikydami aukščiau aprašytą praktiką naudoti automatiškai generuojamą pirminį raktą, gausime lentelę, aprašomą tokiais DDT sakiniais:

create table products_customers(
id int not null auto_increment,
product_id int not null,
customer_id int not null,
limit_ int not null,
foreign key (product_id) references products(id),
foreign key (customer_id) references customers(id),
primary key(id)
);

sukuriame išorinius raktus, pirminį raktą, atrodo lyg ir užtikriname duomenų vientisumą. Deja.. Tarkime, turime tokius duomenis lentelėje „products_customers“:

id | product_id | customer_id | limit_
—————————————
1 | 25 | 100 | 200
2 | 25 | 100 | 259

produktas tas pats, klientas taip pat, taigi, koks jo apribojimas? negalime vienareikšmiškai pasakyti.. galime tik spėlioti. Kodėl taip atsitiko? Atsakymas paprastas: mūsų DB struktūra neužtikrina duomenų neprieštaringumo. Kaip to išvengti? Paprasta: pakeisti pirminį lentelės raktą į štai tokį:

/* .. */
primary key (product_id, customer_id);
/* .. */

toks pirminis raktas įpareigos DBVS prižiūrėti, jog nagrinėjamoje lentelėje būtų užtikrinama unikali rinkinio (product_id, customer_id) reikšmė įterpiant, arba keičiant duomenis. Ko visiškai pakanka, kad neatsirastų minėtos duomenų anomalijos. Be to, greičiausiai, mums jau nebereikia stulpelio id, taip padarome DB struktūrą dar paprastesne. Taigi galutinis lentelės struktūros kūrimo sakinio variantas būtų toks:

create table products_customers(
product_id int not null,
customer_id int not null,
limit_ int not null,
foreign key (product_id) references products(id),
foreign key (customer_id) references customers(id),
primary key(product_id, customer_id)
);

Taigi, panaudodami sudėtinį raktą:

  • išsprendėme vieną duomenų anomaliją,
  • supaprastinome DB schemą.

Sakyčiau neblogas rezultatas :)