Balancování zapisuje a čte v databázi

Balancování zapisuje a čte v databázi
V předchozím článek Popsal jsem koncept a implementaci databáze postavené na základě funkcí, spíše než tabulek a polí jako v relačních databázích. Poskytla mnoho příkladů ukazujících výhody tohoto přístupu oproti klasickému. Mnozí je považovali za nedostatečně přesvědčivé.

V tomto článku ukážu, jak vám tento koncept umožňuje rychle a pohodlně vyvažovat zápisy a čtení do databáze bez jakékoli změny provozní logiky. Podobnou funkcionalitu jsme se pokusili implementovat v moderních komerčních DBMS (zejména Oracle a Microsoft SQL Server). Na konci článku ukážu, že to, co udělali, se jim, mírně řečeno, moc nepovedlo.

popis

Stejně jako dříve, pro lepší pochopení začnu popis příklady. Řekněme, že potřebujeme implementovat logiku, která vrátí seznam oddělení s počtem zaměstnanců v nich a jejich celkovou mzdou.

Ve funkční databázi by to vypadalo takto:

CLASS Department ‘Отдел’;
name ‘Наименование’ = DATA STRING[100] (Department);

CLASS Employee ‘Сотрудник’;
department ‘Отдел’ = DATA Department (Employee);
salary ‘Зарплата’ =  DATA NUMERIC[10,2] (Employee);

countEmployees ‘Кол-во сотрудников’ (Department d) = 
    GROUP SUM 1 IF department(Employee e) = d;
salarySum ‘Суммарная зарплата’ (Department d) = 
    GROUP SUM salary(Employee e) IF department(e) = d;

SELECT name(Department d), countEmployees(d), salarySum(d);

Složitost provádění tohoto dotazu v jakémkoli DBMS bude ekvivalentní O (počet zaměstnanců)protože tento výpočet vyžaduje naskenování celé tabulky zaměstnanců a následné seskupení podle oddělení. V závislosti na zvoleném plánu bude také malý (domníváme se, že zaměstnanců je mnohem více než oddělení) doplatek O (log počet zaměstnanců) nebo O (počet oddělení) pro seskupování a tak dále.

Je jasné, že režie provádění se může v různých DBMS lišit, ale složitost se nijak nezmění.

V navrhované implementaci funkční DBMS vygeneruje jeden poddotaz, který vypočítá požadované hodnoty pro oddělení, a poté provede JOIN s tabulkou oddělení pro získání názvu. Pro každou funkci je však při deklaraci možné nastavit speciální značku MATERIALIZED. Systém automaticky vytvoří odpovídající pole pro každou takovou funkci. Při změně hodnoty funkce se ve stejné transakci změní také hodnota pole. Při přístupu k této funkci se zpřístupní předem vypočítané pole.

Zejména pokud nastavíte funkce MATERIALIZED countEmployees и platSoučet, pak do tabulky se seznamem oddělení přibudou dvě pole, ve kterých bude uložen počet zaměstnanců a jejich celková mzda. Kdykoli dojde ke změně zaměstnanců, jejich platů nebo příslušnosti k oddělením, systém automaticky změní hodnoty těchto polí. Výše uvedený dotaz přistoupí přímo k těmto polím a bude proveden v O (počet oddělení).

Jaká jsou omezení? Jen jedna věc: taková funkce musí mít konečný počet vstupních hodnot, pro které je její hodnota definována. V opačném případě nebude možné sestavit tabulku, která uchovává všechny její hodnoty, protože nemůže existovat tabulka s nekonečným počtem řádků.

Příklad:

employeesCount ‘Количество сотрудников с зарплатой > N’ (Department d, NUMERIC[10,2] N) = 
    GROUP SUM salary(Employee e) IF department(e) = d AND salary(e) > N;

Tato funkce je definována pro nekonečný počet hodnot N (vhodná je například jakákoli záporná hodnota). Proto na něj nemůžete dát MATERIALIZED. Jde tedy o logické omezení, nikoli o technické (tedy ne proto, že bychom ho nemohli implementovat). Jinak žádná omezení nejsou. Můžete použít seskupení, řazení, AND a OR, PARTITION, rekurzi atd.

Například v problému 2.2 předchozího článku můžete použít MATERIALIZED na obě funkce:

bought 'Купил' (Customer c, Product p, INTEGER y) = 
    GROUP SUM sum(Detail d) IF 
        customer(order(d)) = c AND 
        product(d) = p AND 
        extractYear(date(order(d))) = y MATERIALIZED;
rating 'Рейтинг' (Customer c, Product p, INTEGER y) = 
    PARTITION SUM 1 ORDER DESC bought(c, p, y), p BY c, y MATERIALIZED;
SELECT contactName(Customer c), name(Product p) WHERE rating(c, p, 1997) < 3;

Systém sám vytvoří jednu tabulku s typovými klíči Zákazník, Produktový и INTEGER, přidá k němu dvě pole a aktualizuje hodnoty polí v nich s případnými změnami. Když jsou provedena další volání těchto funkcí, nebudou vypočítány, ale hodnoty budou načteny z odpovídajících polí.

Pomocí tohoto mechanismu se můžete například zbavit rekurzí (CTE) v dotazech. Zvažte zejména skupiny, které tvoří strom pomocí vztahu dítě/rodič (každá skupina má odkaz na svého rodiče):

parent = DATA Group (Group);

Ve funkční databázi lze rekurzní logiku zadat takto:

level (Group child, Group parent) = RECURSION 1l IF child IS Group AND parent == child
                                                             STEP 2l IF parent == parent($parent);
isParent (Group child, Group parent) = TRUE IF level(child, parent) MATERIALIZED;

Od pro funkci je rodič je označena MATERIALIZED, pak se k ní vytvoří tabulka se dvěma klíči (skupinami), ve které pole je rodič bude true pouze v případě, že první klíč je potomkem druhého. Počet záznamů v této tabulce se bude rovnat počtu skupin vynásobenému průměrnou hloubkou stromu. Pokud potřebujete například spočítat počet potomků určité skupiny, můžete použít tuto funkci:

childrenCount (Group g) = GROUP SUM 1 IF isParent(Group child, g);

V dotazu SQL nebude CTE. Místo toho bude jednoduchý GROUP BY.

Pomocí tohoto mechanismu můžete v případě potřeby také snadno denormalizovat databázi:

CLASS Order 'Заказ';
date 'Дата' = DATA DATE (Order);

CLASS OrderDetail 'Строка заказа';
order 'Заказ' = DATA Order (OrderDetail);
date 'Дата' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED;

Při volání funkce datum pro řádek objednávky se pole, pro které existuje index, načte z tabulky s řádky objednávky. Když se datum objednávky změní, systém sám automaticky přepočítá denormalizované datum v řádku.

Výhody

K čemu celý tento mechanismus slouží? V klasických DBMS, bez přepisování dotazů, může vývojář nebo DBA pouze měnit indexy, určovat statistiky a říkat plánovači dotazů, jak je provádět (a HINTy jsou dostupné pouze v komerčních DBMS). Bez ohledu na to, jak moc se snaží, nebudou schopni dokončit první dotaz v článku v O (počet oddělení) bez změny dotazů nebo přidávání spouštěčů. V navrhovaném schématu ve fázi vývoje nemusíte přemýšlet o struktuře úložiště dat a o tom, které agregace použít. To vše lze snadno měnit za chodu, přímo v provozu.

V praxi to vypadá takto. Někteří lidé vyvíjejí logiku přímo na základě daného úkolu. Nerozumí algoritmům a jejich složitosti, ani realizačním plánům, ani typům spojení, ani žádné jiné technické složce. Tito lidé jsou spíše obchodními analytiky než vývojáři. To vše pak jde do testování nebo provozu. Umožňuje protokolování dlouhotrvajících dotazů. Když je detekován dlouhý dotaz, pak se jiní lidé (více techničtí - v podstatě DBA) rozhodnou povolit MATERIALIZED na nějaké mezilehlé funkci. To trochu zpomalí záznam (protože vyžaduje aktualizaci dalšího pole v transakci). Výrazně se však zrychluje nejen tento dotaz, ale i všechny ostatní, které tuto funkci využívají. Rozhodnout, jakou funkci zhmotnit, je přitom poměrně snadné. Dva hlavní parametry: počet možných vstupních hodnot (to znamená, kolik záznamů bude v odpovídající tabulce) a jak často se používá v jiných funkcích.

Analogy

Moderní komerční DBMS mají podobné mechanismy: MATERIALIZOVANÉ ZOBRAZENÍ s FAST REFRESH (Oracle) a INDEXOVANÉ ZOBRAZENÍ (Microsoft SQL Server). V PostgreSQL nelze MATERIALIZED VIEW aktualizovat v transakci, ale pouze na vyžádání (a to ještě s velmi přísnými omezeními), takže o tom neuvažujeme. Mají však několik problémů, které výrazně omezují jejich použití.

Za prvé, materializaci můžete povolit pouze v případě, že jste již vytvořili běžný VIEW. V opačném případě budete muset přepsat zbývající požadavky na přístup k nově vytvořenému pohledu, abyste mohli tuto materializaci použít. Nebo nechte vše tak, jak je, ale bude to přinejmenším neúčinné, pokud existují určitá již předem vypočítaná data, ale mnoho dotazů je vždy nepoužívá, ale přepočítává.

Za druhé, mají obrovské množství omezení:

Věštec

5.3.8.4 Obecná omezení rychlého obnovení

Definující dotaz materializovaného pohledu je omezen takto:

  • Materializovaný pohled nesmí obsahovat odkazy na neopakující se výrazy jako SYSDATE a ROWNUM.
  • Materializovaný pohled nesmí obsahovat odkazy na RAW or LONG RAW typy dat.
  • Nemůže obsahovat a SELECT vypsat poddotaz.
  • Nemůže obsahovat analytické funkce (např. RANK) Ve SELECT doložka.
  • Nemůže odkazovat na tabulku, na které je an XMLIndex je definován index.
  • Nemůže obsahovat a MODEL doložka.
  • Nemůže obsahovat a HAVING klauzule s poddotazem.
  • Nemůže obsahovat vnořené dotazy, které mají ANY, ALLnebo NOT EXISTS.
  • Nemůže obsahovat a [START WITH …] CONNECT BY doložka.
  • Nemůže obsahovat více tabulek podrobností na různých místech.
  • ON COMMIT materializované pohledy nemohou mít vzdálené tabulky podrobností.
  • Vnořené materializované pohledy musí mít spojení nebo agregaci.
  • Zhmotněné pohledy spojení a zhmotněné agregované pohledy s a GROUP BY klauzule nemůže vybírat z tabulky uspořádané podle indexu.

5.3.8.5 Omezení rychlého obnovení u zhmotněných pohledů pouze s připojením

Definování dotazů pro materializované pohledy pouze se spojeními a žádnými agregacemi má následující omezení rychlé aktualizace:

  • Všechna omezení od «Obecná omezení pro rychlé obnovení".
  • Nemohou mít GROUP BY doložky nebo agregáty.
  • Řady všech stolů v FROM seznam se musí objevit v SELECT seznam dotazu.
  • Protokoly materializovaných zobrazení musí existovat s rowids pro všechny základní tabulky v FROM seznam dotazu.
  • Nemůžete vytvořit rychle obnovitelný materializovaný pohled z více tabulek s jednoduchými spojeními, které obsahují sloupec typu objektu v SELECT prohlášení.

Zvolená metoda obnovy také nebude optimálně účinná, pokud:

  • Definující dotaz používá vnější spojení, které se chová jako vnitřní spojení. Pokud definující dotaz obsahuje takové spojení, zvažte přepsání definujícího dotazu tak, aby obsahoval vnitřní spojení.
  • Projekt SELECT seznam materializovaného pohledu obsahuje výrazy ve sloupcích z více tabulek.

5.3.8.6 Omezení rychlého obnovení u zhmotněných pohledů s agregáty

Definování dotazů pro materializované pohledy pomocí agregátů nebo spojení má následující omezení rychlého obnovení:

Rychlé obnovování je podporováno u obou ON COMMIT a ON DEMAND materializované pohledy, platí však následující omezení:

  • Všechny tabulky v materializovaném pohledu musí mít protokoly materializovaných pohledů a protokoly materializovaných pohledů musí:
    • Obsahuje všechny sloupce z tabulky, na kterou odkazuje materializovaný pohled.
    • Specifikujte pomocí ROWID a INCLUDING NEW VALUES.
    • Určete SEQUENCE klauzule, pokud se očekává, že tabulka bude obsahovat kombinaci vložení/přímého načtení, odstranění a aktualizací.

  • Pouze SUM, COUNT, AVG, STDDEV, VARIANCE, MIN a MAX jsou podporovány pro rychlé obnovení.
  • COUNT(*) musí být specifikováno.
  • Agregační funkce se musí vyskytovat pouze jako nejvzdálenější část výrazu. Tedy agregáty jako např AVG(AVG(x)) or AVG(x)+ AVG(x) nejsou povoleny.
  • Pro každý agregát jako např AVG(expr), korespondence COUNT(expr) musí být přítomen. Oracle to doporučuje SUM(expr) být upřesněno.
  • If VARIANCE(expr) or STDDEV(expr) je specifikováno, COUNT(expr) a SUM(expr) musí být specifikováno. Oracle to doporučuje SUM(expr *expr) být upřesněno.
  • Projekt SELECT sloupec v definujícím dotazu nemůže být složitý výraz se sloupci z více základních tabulek. Možným řešením tohoto problému je použití vnořeného materializovaného pohledu.
  • Projekt SELECT seznam musí obsahovat vše GROUP BY sloupce.
  • Materializovaný pohled není založen na jedné nebo více vzdálených tabulkách.
  • Používáte-li CHAR datového typu ve sloupcích filtru protokolu materializovaného pohledu, znakové sady hlavního webu a materializovaného pohledu musí být stejné.
  • Pokud má materializovaný pohled jednu z následujících možností, pak je rychlé obnovení podporováno pouze u konvenčních vložek DML a přímých načtení.
    • Zhmotněné pohledy s MIN or MAX agregáty
    • Zhmotněné pohledy, které mají SUM(expr) ale ne COUNT(expr)
    • Zhmotněné pohledy bez COUNT(*)

    Takový zhmotněný pohled se nazývá zhmotněný pohled pouze pro vložení.

  • Zhmotněný pohled s MAX or MIN je rychle obnovitelný po odstranění nebo smíšených příkazech DML, pokud nemá a WHERE doložka.
    Maximální/min rychlé obnovení po odstranění nebo smíšeném DML nemá stejné chování jako případ pouze vložení. Vymaže a přepočítá maximální/min hodnoty pro dotčené skupiny. Musíte si být vědomi jeho dopadu na výkon.
  • Materializované pohledy s pojmenovanými pohledy nebo poddotazy v FROM klauzuli lze rychle aktualizovat za předpokladu, že lze pohledy zcela sloučit. Informace o tom, která zobrazení se sloučí, viz Oracle Database Reference jazyka SQL.
  • Pokud neexistují žádná vnější spojení, můžete mít libovolný výběr a spojení WHERE doložka.
  • Materializované agregované pohledy s vnějšími spoji lze rychle obnovit po konvenčním DML a přímém načtení za předpokladu, že byla upravena pouze vnější tabulka. Také musí existovat jedinečná omezení na sloupcích spojení vnitřní tabulky spojení. Pokud existují vnější spojení, musí být všechna spojení spojena pomocí ANDs a musí použít rovnost (=) operátor.
  • Pro zhmotněné pohledy s CUBE, ROLLUP, seskupování sad nebo jejich zřetězení platí následující omezení:
    • Projekt SELECT seznam by měl obsahovat rozlišovací znak seskupení, který může být buď a GROUPING_ID fungovat na všech GROUP BY výrazy popř GROUPING funkce jedna pro každého GROUP BY výraz. Například, pokud GROUP BY klauzule materializovaného pohledu je "GROUP BY CUBE(a, b)“, pak SELECT seznam by měl obsahovat buď "GROUPING_ID(a, b)» nebo «GROUPING(a) AND GROUPING(b)» aby byl zhmotněný pohled rychle obnovitelný.
    • GROUP BY by nemělo vést k duplicitním seskupením. Například, "GROUP BY a, ROLLUP(a, b)"není rychle obnovitelné, protože má za následek duplicitní seskupení"(a), (a, b), AND (a)".

5.3.8.7 Omezení rychlého obnovení zhmotněných pohledů s UNION ALL

Zhmotněné pohledy s UNION ALL nastavit podporu operátora REFRESH FAST možnost, pokud jsou splněny následující podmínky:

  • Definující dotaz musí mít UNION ALL operátor na nejvyšší úrovni.

    Projekt UNION ALL Operátor nelze vložit do poddotazu, s jedinou výjimkou: The UNION ALL může být v poddotazu v FROM klauzule za předpokladu, že definující dotaz má formu SELECT * FROM (zobrazit nebo poddotaz s UNION ALL) jako v následujícím příkladu:

    CREATE VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM zákazníků c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM zákazníků c WHERE c.cust_last 'Jones'); VYTVOŘIT MATERIALIZOVANÉ ZOBRAZENÍ unionall_inside_view_mv RYCHLÉ OBNOVENÍ NA VYŽÁDÁNÍ JAKO VÝBĚR * FROM view_with_unionall;
    

    Všimněte si, že pohled view_with_unionall splňuje požadavky na rychlé obnovení.

  • Každý blok dotazu v UNION ALL dotaz musí splňovat požadavky na rychle obnovitelný materializovaný pohled s agregáty nebo rychle obnovitelný materializovaný pohled se spojeními.

    V tabulkách musí být vytvořeny příslušné protokoly materializovaných pohledů, jak je požadováno pro odpovídající typ rychle obnovitelného materializovaného pohledu.
    Všimněte si, že databáze Oracle také umožňuje speciální případ zobrazení zhmotněné jedné tabulky se spojeními pouze za předpokladu ROWID sloupec byl zahrnut do SELECT seznamu a v protokolu materializovaného pohledu. To je zobrazeno v definujícím dotazu pohledu view_with_unionall.

  • Projekt SELECT seznam každého dotazu musí obsahovat a UNION ALL značka a UNION ALL sloupec musí mít v každém odlišnou konstantní číselnou nebo řetězcovou hodnotu UNION ALL větev. Dále se sloupec značky musí objevit ve stejné pořadové pozici v SELECT seznam každého bloku dotazu. viz "UNION ALL přepis značek a dotazů» pro více informací o UNION ALL markery.
  • Některé funkce, jako jsou vnější spojení, agregované dotazy materializovaného pohledu pouze pro vložení a vzdálené tabulky nejsou podporovány pro materializované pohledy s UNION ALL. Upozorňujeme však, že materializované pohledy používané při replikaci, které neobsahují spojení nebo agregace, lze rychle obnovit, když UNION ALL nebo se používají vzdálené stoly.
  • Parametr inicializace kompatibility musí být nastaven na 9.2.0 nebo vyšší, aby se vytvořil rychle obnovitelný materializovaný pohled s UNION ALL.

Nechci urazit fanoušky Oracle, ale soudě podle jejich seznamu omezení se zdá, že tento mechanismus nebyl napsán v obecném případě pomocí nějakého modelu, ale tisíci Indů, kde každý dostal příležitost napsat svou vlastní větev a každý z nich udělal, co mohl. Použití tohoto mechanismu pro skutečnou logiku je jako procházet minovým polem. Minu můžete získat kdykoli tím, že zasáhnete jedno z nesrozumitelných omezení. Jak to funguje, je také samostatná otázka, ale to je nad rámec tohoto článku.

Microsoft SQL Server

Další požadavky

Kromě možností SET a požadavků na deterministické funkce musí být splněny následující požadavky:

  • Uživatel, který provádí CREATE INDEX musí být vlastníkem pohledu.
  • Když vytvoříte index, IGNORE_DUP_KEY musí být nastavena na OFF (výchozí nastavení).
  • Tabulky musí být odkazovány dvoudílnými názvy, schéma.název tabulky v definici pohledu.
  • Uživatelem definované funkce odkazované v pohledu musí být vytvořeny pomocí WITH SCHEMABINDING volba.
  • Všechny uživatelem definované funkce, na které se odkazuje v pohledu, musí být odkazovány dvoudílnými názvy, ..
  • Vlastnost přístupu k datům uživatelem definované funkce musí být NO SQLa vlastnost externího přístupu musí být NO.
  • Funkce Common Language Runtime (CLR) se mohou objevit ve výběrovém seznamu pohledu, ale nemohou být součástí definice seskupeného indexového klíče. Funkce CLR se nemohou objevit v klauzuli WHERE pohledu nebo klauzuli ON operace JOIN v pohledu.
  • Funkce CLR a metody uživatelsky definovaných typů CLR použité v definici pohledu musí mít vlastnosti nastavené tak, jak je uvedeno v následující tabulce.

    Vlastnictví
    Poznámka

    DETERMINISTICKÝ = PRAVDA
    Musí být výslovně deklarován jako atribut metody Microsoft .NET Framework.

    PŘESNÉ = PRAVDA
    Musí být výslovně deklarován jako atribut metody .NET Framework.

    PŘÍSTUP K DATŮM = ŽÁDNÝ SQL
    Určeno nastavením atributu DataAccess na DataAccessKind.None a atributu SystemDataAccess na SystemDataAccessKind.None.

    EXTERNÍ PŘÍSTUP = NE
    Tato vlastnost má výchozí hodnotu NO pro rutiny CLR.

  • Pohled musí být vytvořen pomocí WITH SCHEMABINDING volba.
  • Pohled musí odkazovat pouze na základní tabulky, které jsou ve stejné databázi jako pohled. Pohled nemůže odkazovat na jiné pohledy.
  • Příkaz SELECT v definici pohledu nesmí obsahovat následující prvky Transact-SQL:

    COUNT
    Funkce ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, A OPENXML)
    OUTER se připojí (LEFT, RIGHTnebo FULL)

    Odvozená tabulka (definovaná zadáním a SELECT prohlášení v FROM doložka)
    Vlastní spojení
    Určení sloupců pomocí SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPnebo AVG
    Společný tabulkový výraz (CTE)

    vznášet se1, (souhrnně „Stránka (Stránky)“), a naše postupy pro shromažďování, využívání, uchovávání, ochranu a zpřístupnění takových informací. Tyto zásady platí pro informace, které shromažďujeme na těchto stránkách nebo v e-mailu, textových a jiných elektronických zprávách mezi vámi a těmito stránkami. Rovněž popisují vaše možnosti týkající se využívání vašich osobních údajů, přístupu k nim a jejich opravě., ntext, obraz, XMLnebo filestream sloupce
    Poddotaz
    OVER klauzule, která zahrnuje klasifikační nebo agregační funkce okna

    Fulltextové predikáty (CONTAINS, FREETEXT)
    SUM funkce, která odkazuje na výraz s možnou hodnotou Null
    ORDER BY

    Uživatelsky definovaná agregační funkce CLR
    TOP
    CUBE, ROLLUPnebo GROUPING SETS Operátoři

    MIN, MAX
    UNION, EXCEPTnebo INTERSECT Operátoři
    TABLESAMPLE

    Proměnné tabulky
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Řídké sady sloupců
    Inline (TVF) nebo vícepříkazové tabulkové funkce (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Indexovaný pohled může obsahovat vznášet se sloupy; takové sloupce však nelze zahrnout do klíče seskupeného indexu.

  • If GROUP BY je přítomen, definice VIEW musí obsahovat COUNT_BIG(*) a nesmí obsahovat HAVING, Tyto GROUP BY omezení se vztahují pouze na definici indexovaného pohledu. Dotaz může ve svém plánu provádění používat indexované zobrazení, i když je nesplňuje GROUP BY omezení.
  • Pokud definice pohledu obsahuje a GROUP BY klauzule, klíč jedinečného seskupeného indexu může odkazovat pouze na sloupce uvedené v GROUP BY doložka.

Zde je jasné, že Indiáni nebyli zapojeni, protože se rozhodli to udělat podle schématu „uděláme málo, ale dobře“. To znamená, že mají na hřišti více min, ale jejich umístění je transparentnější. Největší zklamáním je toto omezení:

Pohled musí odkazovat pouze na základní tabulky, které jsou ve stejné databázi jako pohled. Pohled nemůže odkazovat na jiné pohledy.

V naší terminologii to znamená, že funkce nemůže přistupovat k jiné materializované funkci. To omezuje veškerou ideologii v zárodku.
Toto omezení (a dále v textu) také výrazně snižuje případy použití:

Příkaz SELECT v definici pohledu nesmí obsahovat následující prvky Transact-SQL:

COUNT
Funkce ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, A OPENXML)
OUTER se připojí (LEFT, RIGHTnebo FULL)

Odvozená tabulka (definovaná zadáním a SELECT prohlášení v FROM doložka)
Vlastní spojení
Určení sloupců pomocí SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPnebo AVG
Společný tabulkový výraz (CTE)

vznášet se1, (souhrnně „Stránka (Stránky)“), a naše postupy pro shromažďování, využívání, uchovávání, ochranu a zpřístupnění takových informací. Tyto zásady platí pro informace, které shromažďujeme na těchto stránkách nebo v e-mailu, textových a jiných elektronických zprávách mezi vámi a těmito stránkami. Rovněž popisují vaše možnosti týkající se využívání vašich osobních údajů, přístupu k nim a jejich opravě., ntext, obraz, XMLnebo filestream sloupce
Poddotaz
OVER klauzule, která zahrnuje klasifikační nebo agregační funkce okna

Fulltextové predikáty (CONTAINS, FREETEXT)
SUM funkce, která odkazuje na výraz s možnou hodnotou Null
ORDER BY

Uživatelsky definovaná agregační funkce CLR
TOP
CUBE, ROLLUPnebo GROUPING SETS Operátoři

MIN, MAX
UNION, EXCEPTnebo INTERSECT Operátoři
TABLESAMPLE

Proměnné tabulky
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Řídké sady sloupců
Inline (TVF) nebo vícepříkazové tabulkové funkce (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY a další jsou zakázány. Mohlo být snazší specifikovat, co lze použít, než co nelze použít. Výčet by byl pravděpodobně mnohem kratší.

Abych to shrnul: obrovská sada omezení v každém (všimněme si komerčního) DBMS vs žádné (s výjimkou jednoho logického, nikoli technického) v technologii LGPL. Je však třeba poznamenat, že implementace tohoto mechanismu v relační logice je poněkud obtížnější než v popisované funkční logice.

uskutečnění

Jak to funguje? PostgreSQL se používá jako „virtuální stroj“. Uvnitř je složitý algoritmus, který vytváří dotazy. Tady zdroj. A není tam jen velká množina heuristiky s hromadou if. Takže pokud máte pár měsíců na studium, můžete zkusit porozumět architektuře.

Funguje to efektivně? Docela účinné. To se bohužel těžko dokazuje. Mohu jen říci, že pokud vezmete v úvahu tisíce dotazů, které existují ve velkých aplikacích, pak jsou v průměru efektivnější než ty od dobrého vývojáře. Vynikající SQL programátor dokáže napsat jakýkoli dotaz efektivněji, ale s tisíci dotazy na to prostě nebude mít motivaci ani čas. Jediná věc, kterou nyní mohu uvést jako důkaz účinnosti, je, že na platformě postavené na tomto DBMS pracuje několik projektů ERP systémy, které mají tisíce různých MATERIALIZOVANÝCH funkcí, s tisíci uživatelů a terabajtovými databázemi se stovkami milionů záznamů běžících na běžném dvouprocesorovém serveru. Účinnost si však může každý ověřit/vyvrátit stažením plošina a PostgreSQL, zapnuto logování SQL dotazů a pokus o změnu logiky a dat tam.

V následujících článcích budu také mluvit o tom, jak můžete nastavit omezení funkcí, pracovat se změnami a mnoho dalšího.

Zdroj: www.habr.com

Přidat komentář