ASP.NET pro zaΦßteΦnφky
7. Zßklady databßzφ
MENU
Databßze

Databßze jsou urΦeny k tomu, abychom v nich uchovßvali informace. Narozdφl od XML soubor∙ jsou zde data uchovßvßna ve form∞ tabulek. P°edstavme si nap°φklad databßzi pro knihu nßvÜt∞v. Ta bude mφt jednu tabulku, kterß bude obsahovat jednotlivΘ p°φsp∞vky. Tak₧e nap°φklad:

IDAutorMailWebNadpisP°φsp∞vek
0LukßÜ Lßnsk²lansky@czech-ware.nethttp://www.czech-ware.net/glosarPochybuji(n∞jak² dlouh² text)
1Ond°ej HavlφΦek------Myslφm si(n∞jak² krßtk² text)

To je dobr² zp∙sob uklßdßnφ dat, nemyslφte? K v∞tÜin∞ ·Φel∙ se perfektn∞ hodφ. Chceme zaznamenßvat urΦitΘ ·daje (jmΘno autor, jeho mail...) a podle toho si p°ipravφme tabulku. Ta bude mφt sloupce jmeno, mail atd.

Pak vytvo°φme n∞jak² formulß°, kter² umo₧nφ vklßdßnφ ·daj∙ u₧ivatelem a k n∞mu p°i°adφme program, kter² bude vklßdat do databßze novΘ zßznamy. Zßznam je jeden °ßdek tabulky a v∞tÜinou je jich v jednΘ tabulce mnoho.

Je to velmi jednoduchΘ, takovou databßzi si pak m∙₧ete p°edstavit jako mnoho tabulek ve kter²ch je ulo₧eno mno₧stvφ zßznam∙. Modernφ databßze se ale honosφ p°φvlastkem relaΦnφ a je pot°ebnΘ dozv∞d∞t se, co to vlastn∞ znamenß.

Pokud si prohlΘdnete libovolnou diskusi na n∞jakΘm odbornΘm poΦφtaΦovΘm serveru, zjistφte, ₧e u₧ivatelΘ nemluvφ ani tak o obsahu Φlßnku jako o jin²ch p°φsp∞vcφch komentßtor∙. Vznikajφ dlouhΘ plamennΘ diskuse, kdy se dva moud°φ lidΘ usilovn∞ hßdajφ o tom, jestli je lepÜφ Linux nebo Windows. My, co vφme, ₧e Windows se tomu jen up°φmn∞ sm∞jeme. Tabulka pak m∙₧e vypadat takto:

IDAutorMailWebNadpisP°φsp∞vek
0LukßÜ Lßnsk²lansky@czech-ware.nethttp://www.czech-ware.net/glosarNemohu souhlasits ideφ, ₧e WMP je zastaral² nepou₧iteln² Üunt.
1Ond°ej HavlφΦek------pane Lßnsk²niΦemu nerouzumφte - WMP je Üunt.
2LukßÜ Lßnsk²lansky@czech-ware.nethttp://www.czech-ware.net/glosarNenφ.
3Ond°ej HavlφΦek------Je.
4LukßÜ Lßnsk²lansky@czech-ware.nethttp://www.czech-ware.net/glosarNenφ.
5Ond°ej HavlφΦek------Je.

V tabulkßch se nßm hromadφ hromady stejn²ch dat. A p°itom je diskuse tak podn∞tnß a my ji nechceme ruÜit. Co ud∞lßme? Vytvo°φme si novou tabulku. Nazveme ji users a nßvÜt∞vnφky donutφme k registraci. Budeme do nφ uklßdat jejich data:

IDJmenoHesloMailWeb
0LukßÜ Lßnsk²DracoDormiensNunquamTitillanduslansky@czech-ware.nethttp://www.czech-ware.net/glosar
1Ond°ej HavlφΦekosel------

P∙vodnφ tabulky pozm∞nφme. U₧ nenφ t°eba uklßdat tolik dat.

IDAutorIDNadpisP°φsp∞vek
00Nemohu souhlasits ideφ, ₧e WMP je zastaral² nepou₧iteln² Üunt.
11pane Lßnsk²niΦemu nerouzumφte - WMP je Üunt.
20Nenφ.
31Je.
40Nenφ.
51Je.

StaΦilo nßm sem ulo₧it odkazy na autory ulo₧enΘ v p∙vodnφ tabulce a p°i zobrazovßnφ diskuse budeme data vybφrat z obou. To je princip relaΦnφch databßzφ - relace je v p°ekladu "vztah" a takovß databßze je plnß vztah∙ mezi jednotliv²mi tabulkami. Je to u₧iteΦnΘ nejen dφky snφ₧enφ datovΘho objemu, kter² bude databßze zabφrat, ale i kv∙li p°eklep∙m. Pokud by se u₧ivatel v prvnφm p°φklad∞ jednou omylem podepsal jako "LukÜß Lßnsk²", nezahrnovalo by nßsledn∞ hledßno toto jmΘno.

JeÜt∞ pßr pojm∙. "Sloupec identity" je sloupec tabulky, podle kterΘho m∙₧eme rozliÜit jeden zßznam od druhΘho. V naÜem p°φpad∞ je to ID - ₧ßdnΘ dva p°φsp∞vky v tabulce nebudou mφt stejnΘ pole ID a proto ho m∙₧eme za sloupec identity oznaΦit. Obvykle se pou₧φvß ve volßnφch typu prispevek.aspx?diskuse=187&prispevek=15. S tφm souvisφ tzv. "primßrnφ klφΦ" tabulky. Je to sada ·daj∙, kterΘ jsou nutnΘ k jednoznaΦnΘ identifikaci zßznamu. Pokud si vytvo°φme sloupec identity, bohat∞ staΦφ on, proto₧e u n∞j duplicita nehrozφ, jinak se vÜak musφme rozmyslet, jakΘ pole do primßrnφho klφΦe za°adit, aby nikdy nemohla nastat duplicita.

Normalizace databßze

ObΦas je slo₧itΘ p°ijφt na nejlepÜφ rozvr₧enφ dat v tabulkßch. Postupu, p°i kterΘm se navrhuje optimßlnφ struktura databßze, se °φkß normalizace. Nebudu se jφm zde p°φliÜ zab²vat, proto₧e na v∞tÜinu ·loh staΦφ troÜka selskΘho rozumu, ale pokud se chcete pouΦit, prostudujte si nap°φklad dokument Normalizace databßze.

DatabßzovΘ systΘmy

Jsou r∙znß °eÜenφ. Projd∞me si n∞kterΘ.

SQL p°φkazy

Databßzov² program je samostatn² systΘmem, ke kterΘmu se z vaÜφ strßnky p°ipojφte, zaÜlete p°φkazy a oΦekßvßte odpov∞∩. M∙₧e b∞₧et i na jinΘm poΦφtaΦi - b∞₧n∞ se to tak d∞je. Otßzkou je, v jakΘm ₧e jazyce budete databßzi zasφlat po°adavky.

V SQL - Structured Query Language (strukturovan² dotazovacφ jazyk). Trochu se podobß anglickΘ mluvenΘ °eΦi, je opravdu docela "lidsk²". Projdeme si pßr zßkladnφch p°φkaz∙:

SELECT sloupce k navrßcenφ FROM nßzev tabulky WHERE podmφnka v²b∞ru zßznam∙ ORDER BY °adφcφ v²raz

SELECT je patrn∞ nejpou₧φvan∞jÜφ p°φkaz, se kter²m se budete setkßvat. Vybφrß data z databßze. Mß Φty°i hlavnφ parametry:

Tak₧e nap°φklad chceme zφskat ID a mail u₧ivatele se jmΘnem "LukßÜ Lßnsk²" z tabulky users se°azenΘ podle ID:

  SELECT ID, mail FROM users WHERE jmeno = 'LukßÜ Lßnsk²' ORDER BY ID ASC

INSERT INTO nßzev tabulky (seznam sloupc∙) VALUE (seznam nov²ch hodnot)

Insertem vlo₧φte nov² zßznam do databßze. Tady bude myslφm staΦit p°φklad:

  INSERT INTO users (jmeno, heslo, mail, web)
        VALUES ('LukßÜ Lßnsk²','DracoDormiensNunquamTitillandus',
                'lansky@czech-ware.net','http://www.czech-ware.net/glosar')

UPDATE nßzev tabulky SET nßzev sloupce = novß hodnota WHERE podmφnka

P°φkaz Update provßdφ samoz°ejm∞ aktualizici ji₧ existujφcφch zßznam∙. Op∞t p°φklad mluvφ za vÜe:

  UPDATE users SET mail = 'lansky@ware-czech.net', web = 'www.ware-czech.net/glosar'
        WHERE jmeno = 'LukßÜ Lßnsk²'

DELETE FROM nßzev tabulky WHERE podmφnka

Pokud vynechßte Φßst WHERE, sma₧ete si celou tabulku. Jinak budou samoz°ejm∞ smazßny pouze zßznamy vyhovujφcφ podmφnce ... mazßnφ je tedy asi ta nejjednoduÜÜφ Φinnost.

  DELETE users WHERE jmeno = 'LukßÜ Lßnsk²'
Pracujeme s databßzφ v ASP.NET

Pro prßci s nφ musφme nejd°φve vytvo°it spojenφ. ZaprvΘ pot°ebujeme tzv. connection string. To je °et∞zec obsahujφcφ ·daje pot°ebnΘ k p°ipojenφ se k databßzi. My jsme si v prvnφm dφle naÜeho serißlu nainstalovali MSDE, nßÜ conn. string pro p°ipojenφ k lokßlnφ databßzi bude vypadat asi takto:

Data source=localhost;initial catalog=chip;user id=sa;
                  password=DracoDormiensNunquamTitillandus

Password (heslo) jste nastavili p°i instalaci MSDE. Initial catalog znaΦφ jmΘno databßze, s kterou budeme pracovat - vytvo°ili jsme ji v prvnφm dφle. Musφme takΘ spustit MSDE engine, SQL Server Service Manager najdeme p°ibli₧n∞ na tΘto cest∞: D:\Program Files\Microsoft SQL Server\80\Tools\Binn\sqlmangr.exe.

Kdy₧ u₧ jsme u toho, rovnou spus¥te program ASP.NET Web Matrix, kterß jsem takΘ tehdy instalovali. Ten vßm umo₧nφ vytvo°it prvnφ zkuÜebnφ tabulku. JakΘ to bude p°ekvapenφ, ₧e bude pojmenovanß "users". StaΦφ rozbalit databßzi, kliknout na slo₧ku Tables a zvolit p°φkaz New Database Object. Podφvejte se na nastavenφ jejφch sloupc∙:

Dialog uzav°eme a u₧ se opravdu m∙₧eme v∞novat .NETu. ConectionString vyu₧ijeme takto:

   Dim conn As System.Data.SqlClient.SqlConnection = New
       System.Data.SqlClient.SqlConnection("Data source=localhost;initial catalog=chip;
       user id=sa;password=DracoDormiensNunquamTitillandus")
   conn.Open()

Vytvo°enφm objektu SqlConnection a zavolßnφm jeho metody Open jsme otev°eli danou databßzi. Pokud bychom nevyu₧φvali MS SQL, vyu₧φvali bychom namespace System.Data.OleDb - vÜechno by ale bylo velmi podobnΘ.

Co dßl? Nabφzφ se vφce mo₧nostφ pro prßci s databßzφ. Dnes si projdeme jenom ten prvnφ, kter² je z nich nejrychlejÜφ, ale nenabφzφ mnoho komfortu pro programßtora. P°φÜt∞ si ukßzeme DataSet a jeho svßzßnφ se serverov²mi ovlßdacφmi prvky.

Tak₧e te∩ vytvo°φme objekt SqlCommand, kter² stejn∞ jako SqlConnection najdeme ve jmennΘm prostoru System.Data.SqlClient. Mß n∞kolik p°etφ₧enφ konstruktoru, nejpou₧φvan∞jÜφ je asi takovßto kontrukce:

  Dim cmd As SqlCommand = new SqlCommand("SELECT * FROM users WHERE id = 1", conn)

Jako prvnφ parametr tedy String obsahujφcφ SQL dotaz, jako druh² objekt p°ipojenφ k databßzi. Co dßle? Otßzkou je, jak² typ p°φkazu jsme uvedli. Pokud jde o Select, budou vrßcena n∞jakß d∙le₧itß data a zavolßme metodu ExecuteReader, kterß je bez parametr∙. Vracφ objekt SqlDataReader, co₧ je prßv∞ ta nejrychlejÜφ a nejprimitvn∞jÜφ cesta Φtenφ tabulky.

Pokud jsme vÜak uvedli INSERT, UPDATE nebo DELETE, nebudou vrßcena ₧ßdnß data. Zavolßme tedy metodu ExecuteNonQuery, kterß je taktΘ₧ bez parametru a vracφ poΦet zßznam∙, kter²ch se dotkl nßÜ p°φkaz.

Nezapomφnejte vÜak na uzav°enφ objektu p°ipojenφ k databßzi v₧dy po skonΦenφ prßce. Tedy zavolßnφ metody Close. Pokud byste tak neuΦinili, hromadila by se ve vaÜφ aplikaci neaktivnφ p°ipojenφ, co₧ by vedlo k snφ₧enφ jejφho v²konu.

JeÜt∞ se vrßtφme k objektu SqlDataReader. Jak se z n∞j Φtou data? KlφΦovß je metoda Read, po jejφm₧ zavolßnφ se p°i prvnφm pou₧itφ naΦte prvnφ zßznam a p°i dalÜφch se p°esuneme na zßznamy dalÜφ. Metoda vracφ hodnotu boolean, kterß znaΦφ, jestli jsme se opravdu p°esunuli dßle (true) nebo zda u₧ nenφ ₧ßdn² dalÜφ zßznam (false). Toho se nechß dob°e vyu₧φt v cyklu While, kde m∙₧eme testovat na tuto hodnotu a zßrove≥ se posouvat k dalÜφm zßznam∙m.

Pokud mßme naΦten² n∞kter² zßznam, jak ale zjistφme hodnoty jednotliv²ch polφ? Objekt mß navφc jeÜt∞ mno₧stvφ metod typu GetByte, GetDouble, GetBoolean, GetString atp. Ty majφ v parametru jednu funkci, kterou sd∞lφme, kter² ₧e sloupec tabulky nßs zajφmß. Tak₧e p°φklad v²pisu z tabulky users:

  Dim conn As SqlConnection = new SqlConnection(connStr)
  Dim cmd As SqlCommand = new SqlCommand("SELECT * FROM users", conn)
  Dim reader As SqlDataReader = SqlCommand.ExecuteReader()
  
  Response.Write("<table>")
  While reader.Read()
    Response.Write("<tr><td>" + reader.GetInt32(0))
       ' ID u₧ivatele
    Response.Write("<td>" + reader.GetString(1))
       ' U₧ivatelskΘ jmΘno
    Response.Write("<td>" + reader.GetString(2))
       ' Heslo
    Response.Write("<td>" + reader.GetString(3))
       ' Mailovß adresa
    Response.Write("<td>" + reader.GetString(4))
       ' Webovß adresa
  End While
  Response.Write("</table>")
  
  conn.Close()

Tak, to by staΦilo. Tento typ v²stup∙ byl b∞₧n² v ASP programech, v .NETu se ji₧ k t∞mto ·Φel∙m pou₧φvajφ sofistikovan∞jÜφ metody. Pokud jde o zobrazovßnφ dat, je mnohem mnohem v²hodn∞jÜφ pou₧φvat serverovΘ ovlßdacφ prvky. SqlDataReader pou₧φvejte jen v situacφch, kdy vaÜe aplikace pot°ebuje rychle pro svoji pot°ebu natßhnout z databßze n∞jak² ·daj.

Zßv∞rem

V dneÜnφ Φßsti jsme se jen lehce dotkli problematiky databßzφ a prakticky v∙bec jsme neodkryli novΘ .NET metody k p°φstupu a hlavn∞ zobrazovßnφ dat. Ty si p°edstavφme p°φÜt∞.

LukßÜ Lßnsk²
VeÜkerΘ nßm∞ty, dotazy a p°ipomφnky piÜte na adresu lansky@czech-ware.net.