Az írások és olvasások egyensúlyozása egy adatbázisban

Az írások és olvasások egyensúlyozása egy adatbázisban
Az előzőben cikk A függvények, nem pedig táblák és mezők alapján épített adatbázis koncepcióját és megvalósítását írtam le, mint a relációs adatbázisokban. Számos példával mutatta be ennek a megközelítésnek az előnyeit a klasszikushoz képest. Sokan nem találták őket elég meggyőzőnek.

Ebben a cikkben bemutatom, hogy ez a koncepció hogyan teszi lehetővé az adatbázisba történő írások és olvasások gyors és kényelmes egyensúlyát a működési logika megváltoztatása nélkül. Hasonló funkcionalitást próbáltak megvalósítani a modern kereskedelmi DBMS-ekben (különösen az Oracle és a Microsoft SQL Server). A cikk végén megmutatom, hogy amit csináltak, finoman szólva sem sikerült túl jól.

Leírás

Mint korábban, a jobb megértés érdekében a leírást példákkal kezdem. Tegyük fel, hogy be kell vezetnünk egy olyan logikát, amely visszaadja az osztályok listáját a bennük lévő alkalmazottak számával és a teljes fizetésükkel.

Egy funkcionális adatbázisban ez így nézne ki:

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);

A lekérdezés végrehajtásának bonyolultsága bármely DBMS-ben megegyezik a O (alkalmazottak száma)mert ehhez a számításhoz az alkalmazottak teljes táblázatának átvizsgálása, majd részlegenkénti csoportosítása szükséges. A választott tervtől függően lesz némi (szerintünk sokkal több alkalmazott, mint részleg) kiegészítés is lesz O (napló alkalmazottak száma) vagy O (osztályok száma) csoportosításhoz és így tovább.

Nyilvánvaló, hogy a végrehajtási többlet eltérő lehet a különböző DBMS-ekben, de a bonyolultság semmilyen módon nem változik.

A javasolt megvalósításban a funkcionális DBMS egy részlekérdezést generál, amely kiszámítja a részleghez szükséges értékeket, majd JOIN-t készít a részlegtáblázattal a név megszerzéséhez. De minden függvényhez deklaráláskor lehetőség van egy speciális MATERIALIZED marker beállítására. A rendszer minden ilyen funkcióhoz automatikusan létrehoz egy megfelelő mezőt. Egy függvény értékének megváltoztatásakor a mező értéke is megváltozik ugyanabban a tranzakcióban. A funkció elérésekor az előre kiszámított mező lesz elérhető.

Különösen, ha a funkciókhoz a MATERIALIZED értéket állítja be számolja az alkalmazottakat и fizetésÖsszeg, akkor az osztályok listáját tartalmazó táblázathoz két mező kerül hozzáadásra, amely az alkalmazottak számát és teljes fizetését tárolja. Valahányszor változás történik az alkalmazottakban, fizetésükben vagy részlegek besorolásában, a rendszer automatikusan módosítja ezeknek a mezőknek az értékeit. A fenti lekérdezés közvetlenül eléri ezeket a mezőket, és végrehajtásra kerül O (osztályok száma).

Mik a korlátozások? Csak egy dolog: egy ilyen függvénynek véges számú bemeneti értékkel kell rendelkeznie, amelyekhez az értéke meg van határozva. Ellenkező esetben lehetetlen olyan táblát építeni, amely az összes értékét tárolja, mivel nem létezhet végtelen számú sorból álló tábla.

Példa:

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

Ez a függvény végtelen számú N értékhez van definiálva (például bármilyen negatív érték megfelelő). Ezért nem lehet rá tenni a MATERIALIZED-et. Ez tehát logikai korlát, nem technikai (vagyis nem azért, mert nem tudtuk megvalósítani). Ellenkező esetben nincs korlátozás. Használhat csoportosítást, rendezést, ÉS és VAGY, PARTÍCIÓT, rekurziót stb.

Például az előző cikk 2.2-es feladatában mindkét függvényre ráteheti a MATERIALIZED szót:

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;

A rendszer maga hoz létre egy táblázatot a típuskulcsokkal Vevő, Termékek и EGÉSZ SZÁM, két mezőt ad hozzá, és frissíti a mezők értékeit az esetleges változtatásokkal. A függvények további hívása során nem számítanak ki, hanem a megfelelő mezőkből olvassák ki az értékeket.

Ezzel a mechanizmussal például megszabadulhat a rekurzióktól (CTE) a lekérdezésekben. Fontolja meg különösen azokat a csoportokat, amelyek fát alkotnak a gyermek/szülő kapcsolat használatával (minden csoportnak van linkje a szülőjére):

parent = DATA Group (Group);

Egy funkcionális adatbázisban a rekurziós logika a következőképpen adható meg:

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;

Mivel a funkcióhoz isParent MATERIALIZED feliratú, akkor egy két kulcsos (csoportos) táblázat jön létre hozzá, amelyben a mező isParent csak akkor lesz igaz, ha az első kulcs a második gyermeke. A táblázatban szereplő bejegyzések száma megegyezik a csoportok számának és a fa átlagos mélységének szorzatával. Ha például meg kell számolnia egy bizonyos csoport leszármazottainak számát, akkor ezt a funkciót használhatja:

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

Az SQL lekérdezésben nem lesz CTE. Ehelyett egy egyszerű GROUP BY lesz.

Ezzel a mechanizmussal szükség esetén könnyedén denormalizálhatja az adatbázist:

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

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

Függvény meghívásakor adat a rendelési sorhoz az a mező lesz kiolvasva a rendelési sorokat tartalmazó táblázatból, amelyhez index tartozik. Amikor a rendelés dátuma megváltozik, a rendszer maga automatikusan újraszámolja a denormalizált dátumot a sorban.

Előnyei

Mire való ez az egész mechanizmus? A klasszikus DBMS-ekben a lekérdezések átírása nélkül a fejlesztő vagy a DBA csak az indexeket módosíthatja, statisztikákat határozhat meg, és megmondhatja a lekérdezéstervezőnek, hogyan hajtsa végre azokat (és a HINT-ek csak a kereskedelmi DBMS-ekben érhetők el). Bármennyire is igyekeznek, nem fogják tudni teljesíteni a cikkben szereplő első lekérdezést O (osztályok száma) a lekérdezések módosítása vagy triggerek hozzáadása nélkül. A javasolt sémában a fejlesztési szakaszban nem kell gondolkodnia az adattárolási struktúráról és arról, hogy milyen aggregációkat használjon. Mindez könnyen megváltoztatható menet közben, közvetlenül működés közben.

A gyakorlatban ez így néz ki. Vannak, akik logikát fejlesztenek közvetlenül az adott feladat alapján. Nem értik az algoritmusokat és azok összetettségét, sem a végrehajtási terveket, sem az összekapcsolások típusait, sem más műszaki összetevőket. Ezek az emberek inkább üzleti elemzők, mint fejlesztők. Ezután mindez a tesztelésbe vagy a működésbe kerül. Lehetővé teszi a régóta futó lekérdezések naplózását. Ha a rendszer egy hosszú lekérdezést észlel, akkor mások (technikaibbak - lényegében DBA) úgy döntenek, hogy engedélyezik a MATERIALIZED-et valamilyen köztes funkciónál. Ez kissé lelassítja a rögzítést (mivel a tranzakcióban egy további mező frissítését igényli). Azonban nem csak ez a lekérdezés gyorsult fel jelentősen, hanem az összes többi is, amely ezt a funkciót használja. Ugyanakkor viszonylag könnyű eldönteni, hogy melyik függvényt valósítsuk meg. Két fő paraméter: a lehetséges bemeneti értékek száma (ennyi rekord lesz a megfelelő táblázatban), és milyen gyakran használják más funkciókban.

analógok

A modern kereskedelmi DBMS-ek hasonló mechanizmusokkal rendelkeznek: MATERIALIZED VIEW FAST FRISSÍTÉSSEL (Oracle) és INDEXED VIEW (Microsoft SQL Server). A PostgreSQL-ben a MATERIALIZED VIEW nem frissíthető tranzakcióban, hanem csak kérésre (és még nagyon szigorú megkötésekkel is), ezért nem vesszük figyelembe. De számos problémájuk van, amelyek jelentősen korlátozzák a használatukat.

Először is, csak akkor engedélyezheti a materializálást, ha már létrehozott egy normál NÉZETet. Ellenkező esetben át kell írnia a fennmaradó kéréseket, hogy hozzáférjen az újonnan létrehozott nézethez, hogy ezt a materializációt használja. Vagy hagyjon mindent úgy, ahogy van, de az legalább hatástalan lesz, ha vannak bizonyos már előre kiszámított adatok, de sok lekérdezés nem mindig használja, hanem újraszámolja.

Másodszor, rengeteg korlátozással rendelkeznek:

Jóslat

5.3.8.4 A gyorsfrissítés általános korlátozásai

A megvalósult nézet meghatározó lekérdezése a következőkre korlátozódik:

  • A materializált nézet nem tartalmazhat hivatkozásokat nem ismétlődő kifejezésekre, mint pl SYSDATE és a ROWNUM.
  • A megvalósult nézet nem tartalmazhat hivatkozásokat RAW or LONG RAW adattípusok.
  • Nem tartalmazhat a SELECT lista allekérdezés.
  • Nem tartalmazhat elemző függvényeket (pl. RANK) ban,-ben SELECT kikötés.
  • Nem hivatkozhat olyan táblázatra, amelyen an XMLIndex index van meghatározva.
  • Nem tartalmazhat a MODEL kikötés.
  • Nem tartalmazhat a HAVING részlekérdezéssel.
  • Nem tartalmazhat olyan beágyazott lekérdezéseket, amelyek rendelkeznek ANY, ALLvagy NOT EXISTS.
  • Nem tartalmazhat a [START WITH …] CONNECT BY kikötés.
  • Nem tartalmazhat több részlettáblázatot különböző helyeken.
  • ON COMMIT A megvalósult nézetek nem tartalmazhatnak távoli részlettáblázatokat.
  • A beágyazott materializált nézeteknek csatlakozással vagy összesítéssel kell rendelkezniük.
  • Materializált összekapcsolási nézetek és materializált összesített nézetek a GROUP BY záradék nem választhat index szerint szervezett táblából.

5.3.8.5 A gyors frissítés korlátozásai a materializált nézetek csak csatlakozással

A megvalósult nézetekhez való lekérdezések definiálása csak csatlakozással és összesítés nélkül a következő korlátozásokkal rendelkezik a gyors frissítésre vonatkozóan:

  • Minden korlátozás a «A gyors frissítés általános korlátozásai”.
  • Nem lehet nekik GROUP BY záradékok vagy aggregátumok.
  • Az összes tábla sorai a FROM listának meg kell jelennie a SELECT a lekérdezés listája.
  • A materializált nézetnaplóknak létezniük kell sorazonosítókkal az összes alaptáblázathoz a FROM a lekérdezés listája.
  • Nem hozhat létre gyorsan frissíthető materializált nézetet több táblából olyan egyszerű illesztésekkel, amelyek egy objektumtípus oszlopot tartalmaznak a SELECT nyilatkozat.

Ezenkívül a választott frissítési módszer nem lesz optimálisan hatékony, ha:

  • A definiáló lekérdezés külső illesztést használ, amely belső illesztésként viselkedik. Ha a definiáló lekérdezés tartalmaz ilyen összekapcsolást, fontolja meg a definiáló lekérdezés átírását úgy, hogy tartalmazzon egy belső összekapcsolást.
  • A SELECT a materializált nézet listája több tábla oszlopaiban tartalmaz kifejezéseket.

5.3.8.6 Az aggregátumokat tartalmazó materializált nézetek gyors frissítésére vonatkozó korlátozások

Az aggregátumokkal vagy összekapcsolásokkal rendelkező materializált nézetek lekérdezései a következő korlátozásokkal rendelkeznek a gyors frissítésre vonatkozóan:

A gyors frissítés mindkettőnél támogatott ON COMMIT és a ON DEMAND megvalósult nézetek, azonban a következő korlátozások érvényesek:

  • A materializált nézetben lévő összes táblázatnak rendelkeznie kell megvalósult nézetnaplókkal, és a materializált nézetnaplóknak:
    • Tartalmazza a materializált nézetben hivatkozott táblázat összes oszlopát.
    • Adja meg a ROWID és a INCLUDING NEW VALUES.
    • Határozza meg a SEQUENCE záradék, ha a táblázat várhatóan vegyesen tartalmaz beszúrásokat/közvetlen betöltéseket, törléseket és frissítéseket.

  • Csak SUM, COUNT, AVG, STDDEV, VARIANCE, MIN és a MAX támogatja a gyors frissítést.
  • COUNT(*) meg kell adni.
  • Az összesített függvények csak a kifejezés legkülső részeként fordulhatnak elő. Vagyis olyan aggregátumok, mint pl AVG(AVG(x)) or AVG(x)+ AVG(x) nem megengedett.
  • Minden egyes aggregátumhoz, mint pl AVG(expr), a megfelelő COUNT(expr) jelen kell lennie. Az Oracle ezt javasolja SUM(expr) meg kell határozni.
  • If VARIANCE(expr) or STDDEV(expr) van megadva, COUNT(expr) és a SUM(expr) meg kell adni. Az Oracle ezt javasolja SUM(expr *expr) meg kell határozni.
  • A SELECT A definiáló lekérdezés oszlopa nem lehet összetett kifejezés több alaptáblázatból származó oszlopokkal. Ennek lehetséges megoldása egy beágyazott materializált nézet használata.
  • A SELECT listának tartalmaznia kell az összeset GROUP BY oszlopok.
  • A megvalósult nézet nem egy vagy több távoli táblán alapul.
  • Ha a CHAR A materializált nézetnapló szűrőoszlopaiban szereplő adattípusnak meg kell egyeznie a főhely és a materializált nézet karakterkészletének.
  • Ha a materializált nézet rendelkezik az alábbiak egyikével, akkor a gyors frissítés csak a hagyományos DML-beszúrások és közvetlen betöltések esetén támogatott.
    • Materializált nézetek -val MIN or MAX aggregátumok
    • Megvalósult nézetek, amelyek rendelkeznek SUM(expr) de nem COUNT(expr)
    • Materializált nézetek nélkül COUNT(*)

    Az ilyen materializált nézetet csak beillesztett materializált nézetnek nevezzük.

  • Egy megvalósult nézet MAX or MIN gyorsan frissíthető törlés vagy kevert DML utasítások után, ha nem rendelkezik a WHERE kikötés.
    A törlés vagy vegyes DML utáni max/perc gyorsfrissítés viselkedése nem ugyanaz, mint a csak beszúrásos eset. Törli és újraszámítja az érintett csoportok max/min értékeit. Tisztában kell lennie a teljesítményre gyakorolt ​​hatásával.
  • Materializált nézetek elnevezett nézetekkel vagy allekérdezésekkel a FROM záradék gyorsan frissíthető, feltéve, hogy a nézetek teljesen összevonhatók. Az egyesülő nézetek összevonásával kapcsolatos információkért lásd: Oracle Database SQL nyelvi referencia.
  • Ha nincsenek külső csatlakozások, akkor tetszőleges kijelölések és csatlakozások lehetnek a WHERE kikötés.
  • A külső illesztésekkel rendelkező materializált összesített nézetek gyorsan frissíthetők a hagyományos DML és közvetlen betöltések után, feltéve, hogy csak a külső táblázatot módosították. Ezenkívül egyedi megszorításoknak kell létezniük a belső összekapcsolási tábla összekapcsolási oszlopaiban. Ha vannak külső csatlakozások, akkor az összes csatlakozást a következővel kell összekötni ANDs és az egyenlőséget (=) operátor.
  • A megvalósult nézetekhez CUBE, ROLLUP, csoportosítási halmazok vagy azok összefűzése, a következő korlátozások érvényesek:
    • A SELECT listának tartalmaznia kell a csoportosító megkülönböztetőt, amely lehet a GROUPING_ID funkció mindegyiken GROUP BY kifejezések ill GROUPING mindegyikhez egy-egy funkció tartozik GROUP BY kifejezés. Például, ha a GROUP BY a megvalósult nézet záradéka: "GROUP BY CUBE(a, b)", aztán a SELECT a listának tartalmaznia kell a "GROUPING_ID(a, b)» vagy «GROUPING(a) AND GROUPING(b)» hogy a materializált nézet gyorsan frissíthető legyen.
    • GROUP BY nem eredményezhet ismétlődő csoportosítást. Például, "GROUP BY a, ROLLUP(a, b)"nem frissíthető gyorsan, mert ismétlődő csoportosítást eredményez"(a), (a, b), AND (a)”.

5.3.8.7 A gyors frissítés korlátozásai a materializált nézeteknél az UNION ALL szolgáltatással

Materializált nézetek a UNION ALL kezelői támogatás beállítása a REFRESH FAST opció, ha az alábbi feltételek teljesülnek:

  • A meghatározó lekérdezésnek rendelkeznie kell a UNION ALL operátor a legfelsőbb szinten.

    A UNION ALL operátor nem ágyazható be egy segédlekérdezésbe, egy kivétellel: The UNION ALL lehet egy segédlekérdezésben a FROM záradék, feltéve, hogy a meghatározó lekérdezés formájú SELECT * FROM (megtekintés vagy allekérdezés a UNION ALL), mint az alábbi példában:

    CREATE VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM ügyfelektől c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM ügyfelektől c WHERE c.cust_last „Jones”); LÉTREHOZOTT NÉZET LÉTREHOZÁSA unionall_inside_view_mv GYORS FRISSÍTÉS IGÉNYRE AS SELECT * FROM view_with_unionall;
    

    Vegye figyelembe, hogy a nézet view_with_unionall kielégíti a gyors frissítés követelményeit.

  • Minden lekérdezési blokk a UNION ALL a lekérdezésnek meg kell felelnie egy aggregátumokkal rendelkező, gyorsan frissíthető materializált nézet vagy az összekapcsolásokkal rendelkező, gyorsan frissíthető materializált nézet követelményeinek.

    A táblákon létre kell hozni a megfelelő materializált nézetnaplókat a megfelelő típusú, gyorsan frissíthető materializált nézethez megfelelően.
    Vegye figyelembe, hogy az Oracle Database lehetővé teszi az egyetlen tábla materializált nézet speciális esetét is, csak akkor, ha a ROWID oszlopba került be SELECT listában és a materializált nézetnaplóban. Ez megjelenik a nézet meghatározó lekérdezésében view_with_unionall.

  • A SELECT az egyes lekérdezések listájának tartalmaznia kell a UNION ALL marker, és a UNION ALL oszlopban különálló állandó numerikus vagy karakterlánc-értékkel kell rendelkeznie UNION ALL ág. Továbbá a jelölőoszlopnak ugyanabban a sorrendben kell megjelennie a SELECT az egyes lekérdezési blokkok listája. Lát "UNION ALL Marker and Query Rewrite» további információkért UNION ALL markerek.
  • Egyes funkciók, például a külső illesztések, a csak beszúrható összesített materializált nézetlekérdezések és a távoli táblák nem támogatottak a materializált nézetek esetén UNION ALL. Ne feledje azonban, hogy a replikáció során használt materializált nézetek, amelyek nem tartalmaznak csatlakozásokat vagy aggregátumokat, gyorsan frissíthetők, ha UNION ALL vagy távoli táblázatokat használnak.
  • A kompatibilitás inicializálási paraméterét 9.2.0 vagy magasabb értékre kell állítani, hogy gyorsan frissíthető materializált nézetet hozzon létre UNION ALL.

Nem akarom megbántani az Oracle rajongókat, de a korlátozások listájából ítélve úgy tűnik, hogy ezt a mechanizmust nem általános esetben, valamiféle modell segítségével írták, hanem több ezer indiai, ahol mindenkinek megadták a lehetőséget írják a saját águkat, és mindegyik megtette, amit tudott. Ezt a mechanizmust valódi logikára használni olyan, mint egy aknamezőn keresztül menni. Bármikor szerezhet aknát, ha eléri valamelyik nem nyilvánvaló korlátozást. Az, hogy ez hogyan működik, szintén egy külön kérdés, de ez túlmutat e cikk keretein.

Microsoft SQL Server

További követelmények

A SET opciókon és a determinisztikus függvénykövetelményeken kívül a következő követelményeknek kell teljesülniük:

  • A végrehajtó felhasználó CREATE INDEX a nézet tulajdonosának kell lennie.
  • Az index létrehozásakor a IGNORE_DUP_KEY opciót OFF állásba kell állítani (az alapértelmezett beállítás).
  • A táblázatokra kétrészes nevekkel kell hivatkozni, séma.táblanév a nézetdefinícióban.
  • A nézetben hivatkozott, felhasználó által definiált függvényeket a segítségével kell létrehozni WITH SCHEMABINDING opciót.
  • A nézetben hivatkozott bármely felhasználó által megadott függvényre kétrészes névvel kell hivatkozni, ..
  • A felhasználó által definiált függvény adathozzáférési tulajdonságának a következőnek kell lennie NO SQL, és a külső hozzáférés tulajdonságnak kell lennie NO.
  • A Common Language Runtime (CLR) függvények megjelenhetnek a nézet kijelölési listájában, de nem részei a fürtözött indexkulcs meghatározásának. A CLR függvények nem jelenhetnek meg a nézet WHERE záradékában vagy a nézet JOIN műveletének ON záradékában.
  • A nézetdefinícióban használt CLR-függvényeknek és -módszereknek a CLR felhasználó által definiált típusaihoz a következő táblázatban látható tulajdonságokkal kell rendelkezniük.

    ingatlan
    Megjegyzések

    DETERMINISTA = IGAZ
    A Microsoft .NET-keretrendszer metódusának attribútumaként kifejezetten deklarálni kell.

    PONTOS = IGAZ
    A .NET-keretrendszer metódusának attribútumaként kifejezetten deklarálni kell.

    ADATHOZZÁS = NINCS SQL
    A DataAccess attribútum DataAccessKind.None és SystemDataAccess attribútum SystemDataAccessKind.None értékre állításával határozható meg.

    KÜLSŐ HOZZÁFÉRÉS = NEM
    Ez a tulajdonság alapértelmezés szerint NEM a CLR-rutinoknál.

  • A nézetet a WITH SCHEMABINDING opciót.
  • A nézet csak azokra az alaptáblákra hivatkozhat, amelyek ugyanabban az adatbázisban vannak, mint a nézet. A nézet nem hivatkozhat más nézetekre.
  • A nézetdefinícióban szereplő SELECT utasítás nem tartalmazhatja a következő Transact-SQL elemeket:

    COUNT
    ROWSET függvények (OPENDATASOURCE, OPENQUERY, OPENROWSET, ÉS OPENXML)
    OUTER csatlakozik (LEFT, RIGHTvagy FULL)

    Származtatott táblázat (amelyet az a. megadásával határozunk meg SELECT nyilatkozat a FROM kikötés)
    Öncsatlakozások
    Oszlopok megadása a használatával SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPvagy AVG
    Közös táblázatos kifejezés (CTE)

    úszik1, szöveg, ntext, kép, XMLvagy fájlfolyam oszlopok
    segédlekérdezés
    OVER záradék, amely rangsorolási vagy összesítő ablakfüggvényeket tartalmaz

    Teljes szövegű predikátumok (CONTAINS, FREETEXT)
    SUM függvény, amely nullálható kifejezésre hivatkozik
    ORDER BY

    CLR felhasználó által definiált összesítő függvény
    TOP
    CUBE, ROLLUPvagy GROUPING SETS üzemeltetők

    MIN, MAX
    UNION, EXCEPTvagy INTERSECT üzemeltetők
    TABLESAMPLE

    Táblázat változói
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Ritka oszlopkészletek
    Soron belüli (TVF) vagy többutasításos táblázatértékű függvények (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Az indexelt nézet tartalmazhat úszik oszlopok; az ilyen oszlopok azonban nem szerepelhetnek a fürtözött indexkulcsban.

  • If GROUP BY jelen van, a VIEW definíciónak tartalmaznia kell COUNT_BIG(*) és nem tartalmazhat HAVING. Ezek GROUP BY A korlátozások csak az indexelt nézet meghatározására vonatkoznak. Egy lekérdezés akkor is használhat indexelt nézetet a végrehajtási tervében, ha ezeknek nem felel meg GROUP BY korlátozásokat.
  • Ha a nézetdefiníció tartalmazza a GROUP BY záradékkal, az egyedi fürtözött index kulcsa csak a -ban megadott oszlopokra hivatkozhat GROUP BY kikötés.

Itt egyértelmű, hogy az indiánok nem vettek részt, mivel úgy döntöttek, hogy a „keveset teszünk, de jól” séma szerint csinálják. Vagyis több aknájuk van a pályán, de a helyük átláthatóbb. A legkiábrándítóbb dolog ez a korlátozás:

A nézet csak azokra az alaptáblákra hivatkozhat, amelyek ugyanabban az adatbázisban vannak, mint a nézet. A nézet nem hivatkozhat más nézetekre.

A mi terminológiánk szerint ez azt jelenti, hogy egy függvény nem férhet hozzá egy másik materializált függvényhez. Ez minden ideológiát lerombol.
Ezenkívül ez a korlátozás (és még a szövegben) nagymértékben csökkenti a használati eseteket:

A nézetdefinícióban szereplő SELECT utasítás nem tartalmazhatja a következő Transact-SQL elemeket:

COUNT
ROWSET függvények (OPENDATASOURCE, OPENQUERY, OPENROWSET, ÉS OPENXML)
OUTER csatlakozik (LEFT, RIGHTvagy FULL)

Származtatott táblázat (amelyet az a. megadásával határozunk meg SELECT nyilatkozat a FROM kikötés)
Öncsatlakozások
Oszlopok megadása a használatával SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPvagy AVG
Közös táblázatos kifejezés (CTE)

úszik1, szöveg, ntext, kép, XMLvagy fájlfolyam oszlopok
segédlekérdezés
OVER záradék, amely rangsorolási vagy összesítő ablakfüggvényeket tartalmaz

Teljes szövegű predikátumok (CONTAINS, FREETEXT)
SUM függvény, amely nullálható kifejezésre hivatkozik
ORDER BY

CLR felhasználó által definiált összesítő függvény
TOP
CUBE, ROLLUPvagy GROUPING SETS üzemeltetők

MIN, MAX
UNION, EXCEPTvagy INTERSECT üzemeltetők
TABLESAMPLE

Táblázat változói
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Ritka oszlopkészletek
Soron belüli (TVF) vagy többutasításos táblázatértékű függvények (MSTVF)
OFFSET

CHECKSUM_AGG

A KÜLSŐ CSATLAKOZÁSOK, AZ ÖSSZEGZÉS, az ORDER BY és mások tilosak. Talán könnyebb lett volna meghatározni, hogy mit lehet használni, mint azt, hogy mit nem. A lista valószínűleg sokkal rövidebb lenne.

Összefoglalva: hatalmas korlátozások halmaza minden (jegyezzük meg a kereskedelmi) DBMS-ben, szemben az egyik sem (egy logikai, nem technikai kivételével) az LGPL technológiában. Meg kell azonban jegyezni, hogy ennek a mechanizmusnak a megvalósítása a relációs logikában valamivel nehezebb, mint a leírt funkcionális logikában.

Реализация

Hogyan működik? A PostgreSQL-t „virtuális gépként” használják. Benne van egy összetett algoritmus, amely lekérdezéseket készít. Itt forrás. És nem csak egy nagy számú heurisztika létezik egy csomó if-val. Tehát, ha van pár hónapod a tanulásra, megpróbálhatod megérteni az építészetet.

Hatékonyan működik? Elég hatásos. Sajnos ezt nehéz bizonyítani. Csak azt tudom mondani, hogy ha figyelembe vesszük a nagy alkalmazásokban létező több ezer lekérdezést, akkor átlagosan hatékonyabbak, mint egy jó fejlesztőé. Egy kiváló SQL-programozó bármilyen lekérdezést hatékonyabban meg tud írni, de ezer lekérdezéssel egyszerűen nem lesz motivációja és ideje sem. Az egyetlen dolog, amit most a hatékonyság bizonyítékaként említhetek, az az, hogy több projekt is dolgozik ezen a DBMS-re épített platformon. ERP rendszerek, amelyek több ezer különböző MATERIALIZÁLT funkcióval rendelkeznek, több ezer felhasználóval és több százmillió rekordot tartalmazó terabájtos adatbázissal egy normál kétprocesszoros szerveren. A hatékonyságot azonban letöltve bárki ellenőrizheti/cáfolhatja felület és PostgreSQL, bekapcsolva SQL lekérdezéseket naplóz, és megpróbálja megváltoztatni az ottani logikát és adatokat.

A következő cikkekben arról is beszélek, hogyan állíthat be korlátozásokat a funkciókra, hogyan dolgozhat a változási munkamenetekkel és még sok mással.

Forrás: will.com

Hozzászólás