Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Aplikační a programové vybavení

Podobné prezentace


Prezentace na téma: "Aplikační a programové vybavení"— Transkript prezentace:

1 Aplikační a programové vybavení
S relačními databázovými systémy se komunikuje prostřednictvím jazyka SQL. Přestože je tento jazyk standardizovaný, existuje řada funkcí, které jsou specifické pro jednotlivé servery, anebo na každém serveru fungují trošku jinak. Následující přednáška se zabývá právě těmito specialitami, nejedná se rozhodně o vyčerpávající přehled, jsou uvedeny pouze ty nejčastější a nejviditelnější rozdíly. Databáze – speciality šéfkuchařů

2 Databázové systémy Nejpoužívanější relační databázové systémy:
Adaptive Server Enterprise (Sybase) (IBM) DB2 Firebird MySQL Oracle Database PostgreSQL (Microsoft) SQL Server SQLite Každý systém implementuje jazyk SQL jinak a žádný úplně. Mezi jednotlivými DBS bývají velké rozdíly. Seznam DBS je zcela nestraně seřazen podle abecedy :) Rozdíly v implementacích DB serverů se často vykládají jako zlá vůle společností, které tyto systémy vyvíjí. Ve skutečnosti jsou důvody různé a mnohem jednodušší. U nejstarších DBS (DB2, Oracle, SQL Server) jsou to historické důvody – řada funkcí byla implementována dávno před tím, než se staly součástí standardu a dodatečně je obtížné je změnit (je nutné zachovávat kompatibilitu se staršími verzemi). Naproti tomu Firebird a SQLite se zaměřují na tzv. embedded použití, to znamená, že se používají jako součást (knihovna) jiné aplikace. SQLite databáze je například poměrně standardní součástí OS chytrých telefonů. Tyto DBS jsou z podstaty věci jednoduché a některé složitější funkce neimplementují vůbec a některé jen v jakési zjednodušené formě.

3 Rozhraní Pro práci s databázovým systémem se vždy používá nějaké rozhraní: Firemní pouze pro jeden konkrétní DB systém zpravidla více funkcí optimální výkon Obecná obvykle větší podpora standardů použitelné z různých aplikací a pro různé DBS ODBC, ADODB, JDBC, PDO … Každé rozhraní poskytuje funkce pro připojení k databázi, vykonání dotazu, vypsání výsledku dotazu a zjištění chyb. Databázových rozhraní je celá řada a nelze se je nijak rozumně učit, podstatné je vědět, co databázové rozhraní musí umět (poslední odrážka) a potom už je potřeba jen číst manuál, abyste se dozvěděli, jak přesně ho používat. Na cvičeních se používá (a je to doporučené i pro projekt) rozhrání PDO, které je obecné pro více databázových systémů, ale je vázané na PHP (není tedy zcela obecné). Jedná se o celkem dobrý kompromis mezi snadností použití a univerzalitou.

4 Datové typy - řetězce character_varying(mohutnost) / varchar(mohutnost) / nvarchar(mohutnost) standardní řetězec, omezený délkou mohutnost se udává v byte [B] char(mohutnost) / character(mohutnost) / nchar(mohutnost) řetězec omezený délkou doplňuje se mezerami operátor LIKE porovnává řetězce bez mezer text / ntext „neomezený“ řetězec Datový typ char je poměrně málo užitečný a je zde uvedený zejména pro to, že kdyby se vám někdy stalo, že se texty v DB doplňují mezerami, tak abyste věděli, odkud vítr vane. Mohutnost datového typu se někde udává v bytech (na serverech, které příliš neberou v úvahu Unicode), jinde ve znacích (např. pro MSSQL datové typy nchar a nvarchar). Datový typ text má zpravidla maximální velikost v řádech terabytů. Výměnou za to ale nepodporuje některé funkce, například se podle sloupce typu text nedá řadit, někdy na něm nelze použít operátory jako LIKE apod.

5 Datové typy – celá čísla
bigint(šířka) – 8B – 263 = integer(šířka) – 4B – mediumint(šířka) – 3B – smallint(šířka) – 2B – tinyint(šířka) – 1B – celé číslo signed (se znaménkem) – záporné rozsahy unsigned (bez znaménka) – pouze kladná čísla pozor na převod mezi signed a unsigned Při převodu ze signed na unsigned se z velkých čísel stanou záporné hodnoty a naopak. Šířka je řetězcová délka integeru na kterou je hodnota doplněna nulami zleva. Ne všechny DB servery tuto funkci podporují. Vzhledem k rozsahu integeru, je výhodné použít ve všech sloupcích aplikace stejný typ. Obvykle nemá nejmenší smysl „šetřit místo“ a používat menší integer. Např. pokud místo integer použijete smallint a budete mít v tabulce řádků (což není úplně málo), ušetříte 2 MB místa, což naprosto nestojí za problémy s nekompatibilitou datových typů.

6 Datové typy – desetinná čísla
real / float(velikost) plovoucí desetinná čárka velikost <= 24 – 7 číslic, 4 byty velikost > 24 – 15 číslic, 8 bytů number / numeric / decimal(přesnost, měřítko) pevná desetinná čárka přesnost – maximální počet platných číslic měřítko – počet číslic za desetinnou čárkou velikost – bytů podle nastavení money = ,5808 Pokud je to možné, je dobré se vyhnout datovému typu float. V tomto datovém typu jsou čísla uložena „nepřesně“, tj. může se snadno stát, že 1 se uloží jako a 2 se uloží jako Potom se může snadno stát, že <> 10, což většinu lidí překvapí. Datové typy typu DECIMAL sice zabírají víc místa v databázi, ale netrpí tímto neduhem.

7 Datové typy – datum a čas
timestamp Datum a čas se ukládá jako časové razítko. Časové razítko je počet milisekund od platné pouze do :14:07 Převod na běžný formát data je velice složitý, je nutné počítat se přestupnými dny a sekundami. Timestamp není možné použít k uložení intervalu (rok, měsíc, den, …). Podle SQL standardu by měl typ timestamp obsahovat i časovou zónu. datetime / date / time větší rozsah a přesnost uložení intervalu komplexní datový typ Nezapomeňte na to, že není do timestamp možné uložit například jen datum nebo jen čas. Přesněji, datum se dá uložit například s časem 0:00, to samozřejmě lze. Problém je, že při přechodu mezi časovými zónami se odečtením nebo přičtením několika hodin datum změní. Tedy datum samotné opravdu do timestamp uložit nelze a časová složka může způsobovat poměrně velké problémy. Některé DB servery pro tyto účely mají speciální datové typy date a time. Podobně nelze do datumového sloupce uložit nepřesně zadané datum, například: „červen 2015“. Nikdy se nepokoušejte psát převodní funkce mezi timestamp (počet milisekund odkudkoliv kamkoliv), na datum. Problém je, že tyto funkce nebudou nikdy fungovat správně. Do toho se počítá i předpoklad, že hodina má 3600 sekund, protože prostě během roku existují i hodiny u kterých to neplatí. U nás jsou to běžně dvě hodiny, při přechodu na letní a zimní čas (jedna z nich má 0 sekund a druhá má 7200 sekund).

8 Datové typy – datum je možné použít také formát data aplikace – např.
pg_query("UPDATE osoby SET datum_narozeni=". time()); datový typ sloupce je integer výhody: jednoduché, pro jednu aplikaci bezproblémové nevýhody: není atomické, nelze vyhledávat podle části data (lze pouze řadit) obtížně se zobrazuje interval – respektive závisí to na aplikaci vracíme se k problému závislosti dat a aplikace nespolehlivé pokud k databázi přistupuje více aplikací

9 Datové typy – binární data
bit / boolean / binary – jedna hodnota BLOB / image – binární data BLOB – binary large object Detaily práce s binárními daty závisí na použitém rozhraní. Jednodušší případ: Data je možno odesílat (po správném escapování) SQL dotazem a přijímat v rámci jeho výsledků. Od určité velikosti nemusí fungovat správně. Složitější případ: Binární data (může zahrnovat i typ text) je nutné odesílat a přijímat speciálními funkcemi. Většinou je možné binární data odesílat v rámci SQL dotazů, zejména pro velké objemy dat je však stejně výhodnější použít speciální funkce.

10 Definice struktury databáze
SQL příkaz CREATE CREATE TABLE nazev_tabulky ( sloupec datovy_typ [NOT NULL] [DEFAULT hodnota] [PRIMARY KEY] [,sloupec datovy_typ …] ) CREATE TABLE kontakty ( id serial PRIMARY KEY, osoba integer NOT NULL REFERENCES osoby, typ integer REFERENCES typy_kontaktu, kontakt varchar(200) NOT NULL ) Vzhledem k tomu, že definice struktury databáze vyžaduje zadání datových typů a tyto datové typy se liší pro jednotlivé DB servery, jsou i dotazy pro vytvoření struktury databáze obvykle nekompatibilní. Fakt ovšem je, že se situace neustále zlepšuje, a zejména u nových verzí DBS je přenositelné ledacos. Nicméně přenositelnost DB aplikace není otázka jen spouštění SQL dotazů. Různé servery mají různé přístupy k vykonávání dotazů a to, co může na jednom serveru běžet bezproblémově, může na jiném serveru způsobovat extrémní zatížení HW.

11 Definice struktury databáze
Prakticky není možné využívat SQL pro definici databáze mezi jednotlivými DBS. Každý DB systém používá jiné datové typy Generovaný primární klíč je implementován různě Jednotlivé DBS používají rozšíření, která významně ovlivňují práci s DB (např. MySQL – MyISAM × InnoDB) SQL pro definici struktury se používá nejčastěji pro import a export struktury v rámci jednoho DBS. Pro převod dat mezi DB systémy je nutné používat nástroje pro migraci (migration toolkit) MySQL server je poměrně specifický v tom, že umožňuje používat interně různé DB systémy. V podstatě je MySQL server jen obálka okolo DB enginu. Pokud to, ale programátor neví, může se dost divit tomu, že vytvořená tabulka například nepodporuje cizí klíče (engine MyISAM), nebo se při restartování serveru vymaže (engine Memory).

12 Automatický generovaný klíč (ID)
nejčastěji používaný typ primárního klíče abstraktní identifikátor záznamu nezávislý na vnějších podmínkách odpadají problémy se složeným klíčem kromě něj by měl existovat ještě jiný klíč (definice relace) Žádný databázový systém neodpovídá přesně standardu. Mezi jednotlivými databázovými systémy jsou velké rozdíly. Problémy se složeným klíčem zahrnují zejména odkazování na konkrétní záznam. Složený klíč znamená, že kombinace hodnot ve všech sloupcích uvedených v klíči musí být unikátní. Tedy například při editaci vlastností osoby je nutné do podmínky WHERE vložit jmeno='x' AND prijmeni='y' AND prezdivka='z' k plné identifikaci osoby. Zapomenutí kterékoliv položky vede k tomu, že se zobrazí/změní/smaže více záznamů, což je dost zásadní chyba aplikace. Použití (automaticky generovaného) ID tedy zjednodušuje program. Žádný DB systém neodpovídá přesně standardu z toho důvodu, že tato funkce DB systému byla standardizovaná podstatně později než byla implementovaná.

13 ID - MySQL sloupci se přiřadí speciální atribut auto_increment
při vložení dat INSERT dotazem se klíč automaticky aktualizuje i v případě, že je hodnota zadaná (např. při importování) SELECT LAST_INSERT_ID(); pouze jeden sloupec v tabulce může mít atribut nastaven musí být klíčem CREATE TABLE tabulka ( id int(5) unsigned NOT NULL auto_increment) Automaticky generovaný klíč na MySQL serveru se chová asi nejpřirozenějším způsobem, chová se tak, jakoby vzal vždy maximální hodnotu ID z tabulky, a zvětšil ji o jedničku.

14 ID – MS SQL sloupci se přiřadí speciální atribut is_identity
při vložení dat INSERT dotazem se klíč automaticky aktualizuje SELECT IDENT_CURRENT('nazev_tabulky'); v případě, že je hodnota sloupce zadaná, je nutné použít příkazy: SET IDENTITY INSERT on – povolí vkládání dat SET IDENTITY INSERT off – ukončí vkládání dat vkládání dat do generovaného klíče může být povoleno pouze pro jednu tabulku CREATE TABLE tabulka ( id int(5) unsigned NOT NULL is_identity, Na SQL serveru se chová automaticky generovaný klíč podobně, ale je chráněn proti přímému zápisu. Standardně nelze hodnoty ve sloupci s automaticky generovaným klíčem ani měnit, ani vkládat (což je dobře). Příkaz SET IDENTITY INSERT se používá jen pro hromadný import dat do databáze.

15 ID - PostgreSQL Sloupci se přiřadí speciální datový typ SERIAL
Automaticky se vytvoří sekvence pro generování hodnot klíče. Při vložení dat INSERT dotazem se klíč automaticky aktualizuje. SELECT currval('nazev_sekvence') V případě, že je hodnota sloupce explicitně zadaná se klíč neaktualizuje! CREATE TABLE tabulka ( id serial NOT NULL, PostgreSQL generuje klíč pomocí sekvence, což vede k tomu, že při ručním zápisu do tabulky se nezmění hodnota sekvence. Neboli, bez ohledu na to, které hodnoty jsou v tabulce skutečně použité, generuje sekvence posloupnost čísel. To znamená, že při ručním vložení hodnoty, přestane tento systém fungovat v okamžiku, kdy sekvence dojde k ručně vložené hodnotě. Tu se nepodaří vložit, protože je již v tabulce vložena (a ID musí být unikátní). V tom případě je nutné ručně změnit hodnotu sekvence na vyšší číslo.

16 Autoincrement, Identiy, Currval ?
Pro zjištění hodnoty ID posledního vloženého záznamu se musí používat předdefinované funkce. Nefunguje: SELECT MAX(id) FROM tabulka Funguje: SELECT currval(‘nazev_sekvence’) Funguje: $db->lastInsertId Zjištění hodnoty musí být thread-safe viz Obrázky: Verze $db->lastInsertId je použitelná pouze v PHP s použitím DB rozhraní PDO, jedná se o abstrakci konkrétních funkcí nutných pro zjištění ID. Ve skutečnosti se na různých DB serverech provádí dotazy uvedené v předchozích slajdech (tj. na PostgreSql je to např. SELECT currval(‘osoby_id_osoby_seq’) pro zjištění ID osoby). Stručně řečeno: Všechny webové (a většina databázových) aplikace jsou aplikace, u kterých se předpokládá současná (souběžná) práce více uživatelů. Většina operací, je v DBS ošetřena interně (systémem transakcí) a není nutné se o ně příliš starat. O generování automatických klíčů také není nutné se příliš starat, ale je nutné použít správné funkce. Zdánlivě jednodušší řešení s pomocí maximální hodnoty ID v tabulce, není funkční. Problém této nefunkčnosti je, že na ni nikdy nepřijdete při testování aplikace. Projeví se pouze v reálném provozu a to navíc jen někdy a zcela nahodile. Z toho plyne velké poučení do života: pokud si nejste jistí, jak to funguje, postupujte podle návodu. Poznámka k automaticky generovaným klíčům: Nejčastějším typem automaticky generovaného klíče je zvyšující se integer. který začíná od 1. Nula se vynechává, aby se snadno dalo zjistit, jestli je hodnota zadaná. U klíče je podstatná vlastnost unikátnost. Tj. vůbec nezáleží na tom, že sekvence není spojitá (jsou v ní vynechaná čísla), reálně tato situace nastává z různých důvodů (smazání záznamu, zrušená transakce) poměrně často a vůbec ničemu to nevadí. Nezabývejte se tedy tím, že posloupnost ID vynechává některá čísla, nevadí to, a nelze se spoléhat na to, že čísla vynechávat nebude. Druhým typem jsou tzv. GUID ( GUID se používá v systémech, ve kterých chybí centrální autorita pro generování posloupnosti čísel. Mohou to být distribuované databáze, anebo aplikace, které pracují v offline režimu. GUID je natolik složitý identifikátor, že za běžných podmínek je velmi nepravděpodobné, že by na dvou místech vznikla stejná hodnota, je tedy opět (v rámci potřeba aplikace) zajištěna unikátnost. Prakticky to funguje tak, že například klient, který je offline vloží do lokální kopie databáze nějaký záznam, kterému se vytvoří GUID. Po připojení k centrálnímu serveru se záznamy synchronizují a protože se v lokální databázi objevil záznam s GUID, které v centrální DB není, zkopíruje se tento záznam do centrální databáze. Sekvenci čísel by zde nešlo použít, protože offline klient se nemá koho zeptat na poslední hodnotu sekvence, může použít pouze tu, kterou má u sebe v lokální databázi, ale hrozí zde nebezpečí, že mezitím jiný klient již tuto hodnotu použil. Celá problematika synchronizace databází je však dost komplikovaná a úplně mimo rozsah APV. Já jen, abyste věděli, že existuje i něco jiného.

17 Referenční integritní omezení
integritní omezení – NOT NULL, UNIQUE, PRIMARY KEY, CHECK cizí klíč zpravidla představuje referenční integritní omezení nelze změnit záznam v jedné tabulce bez aktualizace záznamů, které se na něj odkazují Příklad: sloupec osoba v tabulce kontakty se odkazuje na tabulku osoby při smazání osoby je žádoucí upravit i všechny připojené kontakty CASCADE – smazat RESTRICT / NO ACTION - nepovolit smazání osoby SET NULL – nastavit hodnoty ve sloupci na NULL CREATE TABLE kontakty ( osoba integer NOT NULL REFERENCES osoby ON DELETE CASCADE osoby-kontakty vs. osoby- adresy NOT NULL – není povoleno nezadání hodnoty. Tedy sloupec musí být vždy uveden v INSERT dotazu, nebo musí mít nastavenou výchozí hodnotu. Problém, je že toto neřeší, jestli je uvedená hodnota neprázdná – tedy prázdný řetězec je přípustný. UNIQUE – hodnoty ve sloupci jsou unikátní, tedy sloupec je klíčem. PRIMARY KEY – sloupec je primární klíč, je automaticky unikátní.

18 Referenční integritní omezení
Adresy Při odstranění adresy se stane id_adresy=11 neplatné. ON DELETE SET NULL smaže pouze referenci, pravděpodobně není žádoucí smazat odkazující se záznam. id_adresy mesto ulice 11 Brno Polní 12 Praha Jarní Osoby id_osoby jmeno id_adresy 1 Pavel 11 NULL 2 Karel 12 Při odstranění Karla z databáze se stane id_osoby=2 neplatné. ON DELETE CASCADE smaže i záznamy, které se na tuto hodnotu odkazují. Při odstranění adresy zřejmě nechceme smazat osobu, protože by to odpovídalo tomu, že když se někdo přestěhuje a nevíme kam, tak ho vymažeme z databáze. U kontaktů je asi logické, že pokud odstraníme osobu z databáze, tak se odstraní i její kontaktní údaje (neměly by bez osoby žádný smysl). Co udělat se závislým záznamem v databázi však záleží jen a pouze na funkcionalitě aplikace, respektive na požadavcích zákazníka. Proto jsou cizí klíče v databázi nastaveny ve výchozím stavu na NO ACTION, protože nelze nijak automatizovaně rozhodnout jak se má cizí klíč chovat. Některé případy jsou řešitelné nastavením cizích klíčů, tj. zařídí to DB server sám o sobě (pokud mu řekneme jak). Jsou případy, kdy to takto snadno řešitelné není. Například firma může mít podnikové pravidlo, které říká, že za každé firemní auto musí být někdo zodpovědný. To znamená, že každé auto musí mít přiřazeného jednoho zodpovědného zaměstnance. Pokud zodpovědný zaměstnanec odejde (nebo je vyhozen pro nezodpovědnost), tak je otázka co dál. Podnik tedy má další pravidlo, které říká, že v takovém případě vůz automaticky přechází na nejbližšího nadřízeného. Implementaci tohoto pravidla je nutné řešit v aplikaci, nelze ji udělat jen v databázi. Ještě obecněji: mazání záznamů v databází je poměrně složitý problém, který se typicky řeší tak, že se záznamy z databáze nemažou vůbec, nebo jen v některých případech, nebo až po nějaké době od smazání uživatelem. Pokud například odjede z firmy zaměstnanec, a chtěli bychom mu v informačním systému smazat účet, přijdeme tím o veškerou historii operací, které zaměstnanec provedl, což je velmi nežádoucí. Účet se proto nemaže, ale zablokuje. To s sebou však přináší další problémy, například není možné uživatelské jméno znovu někomu přidělit, nebo současně s účtem se zablokuje i ová schránka a podobně. Opět se jedná o poměrně složitou problematiku, která ale závisí velmi na požadavcích zákazníka a její řešení se liší systém od systému. Kontakty id_kontakty kontakt id_osoby 21 2 22 23 1

19 Úprava struktury databáze
Struktura databáze je uložena ve speciální databázi INFORMATION_SCHEMA Pro DBS, které INFORMATION_SCHEMA nepodporují je možné použít příkazů DESCRIBE, SHOW, LIST, ALTER, RENAME, DROP, MODIFY, ADD… Příklad: SHOW TABLES FROM databaze; SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' ; Dlužno podotknout, že dříve ve standardu příkazy pro úpravy databáze nebyly (a ani dnes není situace jasná), takže to různé firmy řešily různě a těžko dnes někomu vyčítat, že jeho řešení neodpovídá standardu. Pokud je to jen trochu možné, měla by se v aplikacích používat databáze INFORMATION_SCHEMA. Databázi, ve které je uložena struktura databáze, se říká datový slovník (data dictionary). Je to sice podivný název, ale je velmi používaný.

20 Omezení počtu řádků dotazu
Nestandardní (PgSQL, MySQL): SELECT ... LIMIT n; SELECT vyska FROM osoby ORDER BY vyska DESC LIMIT 10; Standardní (SQL Server): SELECT [TOP | BOTTOM n] FROM ... SELECT TOP 10 vyska FROM osoby ORDER BY vyska DESC; A další: SELECT vyska FROM osoby ORDER BY vyska DESC WHERE ROWNUM <= 10; Omezení počtu řádků dotazu je funkce sice užitečná, ale velmi často zneužívaná. Jedno využití je možné pro stránkování výsledků SELECT dotazu, což je využití zcela správné a legitimní. Problém je, že samotná podstata stránkování je diskutabilní. Stránkování se používá v případech, kdy výběrový dotaz vrací tolik výsledků, že by zobrazené na jedné stránce byly nepřehledné. Potíž je v tom, že stránkováním se přehlednost nijak nezvýší – uživatel stejně musí proklikat všechny stránky. Pokud se budete pozorně dívat, zjistíte, že řada aplikací se od stránkování už odklonila (např. facebook, google images). Druhým případem omezení počtu řádků dotazu jsou dotazy typu TOP n. Např. vyber 10 nejvyšších lidí, vyber 5 nejlepších zákazníků, vyber 3 nejhorší obchodníky, atd. Zde je ale potřeba dát pozor na to, že takový dotaz nemusí vracet úplně dobrý výsledek. Pokud chceme například, zjistit 3 nejhorší obchodníky (podle počtu uzavřených obchodů) a spustíme dotaz SELECT * FROM obchodnici ORDER BY pocet_obchodu ASC LIMIT 3; Dostaneme skutečně 3 nejhorší obchodníky. Problém je, že pokud bude v systému 10 obchodníků s jednou jedinou objednávkou, tak výše uvedený dotaz vrátí 3 náhodné obchodníky z těchto 10 nejhorších. To obvykle není to, co uživatel požaduje. Třetí využití LIMIT najdete v mnoha příkladech na internetu ve formě DELETE FROM osoby WHERE id_osoby = 42 LIMIT 1; Toto využití nedává vůbec žádný smysl. Pokud je id_osoby klíč (což doufáme, že je), smaže se vždy maximálně jedna osoba (protože ID 42 nemůže mít více jak jedna osoba, protože ID je unikátní, protože je to klíč). Pokud id_osoby klíč není, smaže se jedna náhodná osoba ze všech osob, které mají id_osoby = 42, což většinou nedává smysl.

21 Index volba primárního klíče souvisí se způsobem ukládání dat v DBS
ISAM (Index Sequential Access Method) využívá se indexových souborů (telefonní seznam) u moderních DBS už se využívají jiné metody, pro snížení časové složitosti operací datový soubor index jméno příjmení rodné číslo Chlastislav Peruňka 647423/3452 Sosna Orbnicová 624783/7332 Růžeslav Mekota 737902/7145 id pozice 1 2 563 3 1124 Datový soubor tabulky může být velký (několik GB), hledání určitého záznamu v takovém souboru by trvalo neúměrně dlouho. Proto se vytváří pomocný indexový soubor, který obsahuje pouze odkazy na místo kde jsou skutečná data. Indexový soubor se vytváří pro klíče relace. V současnosti se tento způsob ukládání dat již moc nepoužívá, ale metody které se používají dnes mají v zásadě stejné praktické důsledky pro používání. Jedná se tedy o to, že na sloupci, který je často používán k vyhledávání řádků v tabulce se vytvoří index, čímž se vyhledávání značně zrychlí. Indexy je potřeba vytvářet opravdu pouze tam, kde jsou nutné, protože zbytečné indexy 1) znamenají nezanedbatelné plýtvání místem 2) výrazně zpomalují aktualizace DB (protože každý vložený záznam se musí vkládat i do indexových souborů). Na druhou stranu je potřeba říct, že tento přístup – ukládání dat po řádcích (záznamech) – je do jisté míry překonaný zcela jinými typy databází ( nicméně na podstatu analýzy dat, jazyka SQL a dotazování na data to má překvapivě malý vliv.

22 Nadstavby SQL Doctrine Query Language (DQL), Hibernate Query Language (HQL), Java Persistence Query Language (JPQL), JOOQ, … Obvykle ORM (Object-Relational Mapping) vrstva a jazyk, který se dotazuje objektového modelu. Pro určité typy (části) aplikací je ORM úžasné, pro jiné je dost nevhodné. $query = $em->createQuery('SELECT COUNT(a.id) FROM CmsUser u LEFT JOIN u.articles a WHERE u.username = ?1 GROUP BY u.id'); $query->setParameter(1, 'jwage'); Celá řada frameworků využívá různé nadstavby SQL. Nadstavbou SQL zde myslíme jazyk, který se přeloží na SQL dotazy, které vykoná relační databáze, jedná se tedy o jazyk jiný, ale na první pohled podobný. Obvykle se v takových jazycích používají stejná klíčová slova jako v SQL i se stejným významem a znalost SQL je tedy výhodou. Cílem těchto jazyků je zjednodušení práce s databází v místech kde to lze. Jedná se obvykle o aplikace se dobře definovaným objektovým modelem, které znají vazby mezi objekty. Příklad na slajdu pochází z Doctrine a vypadá stejně jako SQL, pouze v něm chybí spojovací podmínka. Tu doplní systém automaticky, protože zná vazbu mezi uživateli a články. Přestože se na první pohled zdá, že se do dotazu jen doplní část řetězce, není to tak. Dotaz se totiž nejprve musí vyhodnotit, aby systém vůbec zjistil, na které tabulky se programátor ptá. Až po tom co zjistí, že dotaz pracuje s tabulkami CmsUser a CmsArticles (která je odkazovaná jako CmsUser.articles, což by v SQL nefungovalo), může teprve doplnit podmínku, že CmsUser.id_user = CmsArtiles.id_user (kterou nelze z příkladu vidět, ale je definovaná strukturou databáze).

23 Query builder $qb->select('u') ->from('User u')
->where('u.id = ?1') ->orderBy('u.name', 'ASC') ->setParameter(1, 100); Ve velmi výjimečných případech nutné Někdy přehlednější, často nepřehlednější Dotaz nelze snadno testovat a přenášet do jiné aplikace. Vymyslet se to musí úplně stejně. Současně celá řada (nejen PHP) frameworků nabízí možnost psát dotazy pomocí tzv. fluent interface (plynulého rozhraní). Zapisovat se takto mohou dotazy jak v SQL, tak v jiných podobných jazycích (DQL). Tento zápis je velmi užitečný v případech extrémně dynamických dotazů, ve kterých se například používají různé tabulky na základě zadání uživatele. V takových případech umožňuje čitelnější sestavení SQL dotazu, pro jednodušší dotazy je tento způsob spíš nepřehlednější, ale je to otázka osobních preferencí. $qb je proměnná, která obsahuje Query Builder, což je běžný název třídy, která implementuje fluent interface. Fluent interface samo o sobě spočívá v tom, že se za volání jedné funkce může ihned zařadit volání jiné funkce. Implementuje se to tak, že každá z metod objektu vrací referenci na objekt samotný. Tedy zápis: $obj->metoda1(); $obj->metoda2(); se dá přepsat jako $obj->metoda1()->metoda2(); Objektivní nevýhodou tohoto zápisu je nemožnost spouštět SQL dotaz mimo aplikaci, testovat ho a přenést ho do jiné aplikace (např. do administračního rozhraní DB).

24 Volně dostupné relační DBS
Firebird: MySQL Microsoft SQL Server (Express edice) Oracle (Express edice) PostgreSQL SQLite DB2 (Express edice)

25

26 Otázky? Je lepší nastavit u cizího klíče ON DELETE CASCADE nebo ON DELETE SET NULL? Je lepší použít MySQL nebo PostgreSQL DB server? Proč nelze použít funkci MAX() pro zjištění ID posledního vloženého záznamu? Proč není dobré ukládat datum v DB jako integer? Má jedna hodina 3600 sekund? Má každá tabulka index? Jaký rozsah čísel lze uložit do 32 bajtového integeru? Proč se nedá datový typ text použít všude?


Stáhnout ppt "Aplikační a programové vybavení"

Podobné prezentace


Reklamy Google