
A korábbi Leírtam egy adatbázis koncepcióját és megvalósítását, amely funkciók, nem pedig táblák és mezők alapján épül fel, ahogyan azt a relációs adatbázisokban megszokhattuk. Számos példát mutattam be, amelyek azt illusztrálják, hogy ez a megközelítés miben előnyösebb a klasszikus módszernél. Sokan nem találták őket eléggé meggyőzőnek.
Ebben a cikkben bemutatom, hogyan teszi lehetővé ez a koncepció, hogy gyorsan és kényelmesen egyensúlyozzunk az adatok írása és olvasása között, anélkül, hogy bármilyen logikát megváltoztatnánk. 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 esetében). A cikk végén bemutatom, milyen eredmények születtek, hogy finoman fogalmazzak, nem éppen kielégítően.
Leírás
Ahogy korábban, a jobb érthetőség érdekében példákkal kezdem a leírást. Tegyük fel, hogy egy olyan logikát kell megvalósítanunk, amely visszaadja az osztályok listáját a bennük lévő alkalmazottak számával és azok összesített bérével.
A funkcionális adatbázisban ez a következőképpen nézne ki:
CLASS Department ‘Osztály’;
name ‘Megnevezés’ = DATA STRING[100] (Osztály);
CLASS Employee ‘Alkalmazott’;
department ‘Osztály’ = DATA Department (Employee);
salary ‘Bér’ = DATA NUMERIC[10,2] (Employee);
countEmployees ‘Alkalmazottak száma’ (Department d) =
GROUP SUM 1 IF department(Employee e) = d;
salarySum ‘Összes bér’ (Department d) =
Csoport ÖSSZEG fizetés(Munkavállaló e) HA osztály(e) = d;
SELECT name(Department d), countEmployees(d), salarySum(d);
Ennek a lekérdezésnek a végrehajtásának összetettsége bármely DBMS-ben O(alkalmazottak száma), mivel ennek a számításhoz végig kell nézni az összes alkalmazott tábláját, majd csoportosítani őket osztály szerint. Emellett lesz egy kis (tartsuk feltételezve, hogy az alkalmazottak száma sokkal nagyobb, mint az osztályoké) kiegészítés a választott tervtől függően. O(log alkalmazottak száma) vagy O(osztályok száma) a csoportosításhoz és egyebekhez.
Nyilvánvaló, hogy a végrehajtás költségei eltérőek lehetnek különböző DBMS-ekben, de az összetettség nem fog változni.
A javasolt megvalósítás egy funkcionális DBMS-ben egy al-lekérdezést fog létrehozni, amely kiszámítja a szükséges értékeket az osztályra vonatkozóan, majd összekapcsolja az osztálytáblával a név megkapásához. Ugyanakkor minden funkció kijelölésénél lehetőség van egy különleges MARKER MATERIALIZED definiálására. A rendszer automatikusan létrehozza a megfelelő mezőt minden ilyen funkcióhoz. Ha a funkció értéke megváltozik, akkor ugyanabban a tranzakcióban a mező értéke is megváltozik. A funkcióra való hivatkozáskor már a már kiszámított mezőhöz fogunk hivatkozni.
Különösen, ha a funkciókhoz MATERIALIZED-et állítunk be countEmployees és salarySum, a táblázatban a részlegek listájával két mező fog megjelenni, amelyek az alkalmazottak számát és összesített bérüket tárolják. Bármilyen alkalmazottal, bérrel vagy részleghez való tartozással kapcsolatos változás esetén a rendszer automatikusan módosítja ezeknek a mezőknek az értékeit. A fenti lekérdezés közvetlenül ezekhez a mezőkhöz fog fordulni, és végrehajtásra kerül O(osztályok száma).
Mik a korlátozások? Csak egy: ennek a funkciónak véges számú bemeneti értéke kell, hogy legyen, amelyeknél az értéke meghatározott. Különben lehetetlen lesz olyan táblázatot létrehozni, amely az összes értéket tárolja, hiszen lehetetlenség végtelen számú sorral teli táblázatot készíteni.
Példa:
alkalmazottakSzama 'A munkavállalók száma, akiknek a fizetése > N' (Osztály d, NUMERIC[10,2] N) =
CSOPORT ÖSSZEG bér(Employee e) HA department(e) = d ÉS salary(e) > N;
Ez a funkció végtelen számú N számértékre van definiálva (például bármilyen negatív értékre alkalmas). Ezért nem lehet MATERIALIZED-ra állítani. Így ez logikai, nem pedig technikai korlátozás (tehát nem azért, mert ezt nem tudtuk megvalósítani). Egyébként — nincsenek korlátozások. Használhatók csoportosítások, rendezések, AND és OR, PARTITION, rekurzió stb.
Például a korábbi cikk 2.2 feladatában MATERIALIZED-ot állíthatunk be mindkét funkcióra:
vásárolt 'Vásárolt' (Vevő c, Termék p, EGYES y) =
CSOPORT ÖSSZEG összeg(Részlet d) HA
vevő(rendelés(d)) = c ÉS
termék(d) = p ÉS
kivonatÉv(dátum(rendelés(d))) = y ANYAGOS;
értékelés 'Értékelés' (Vevő c, Termék p, EGYES y) =
PARTÍCIÓ ÖSSZEG 1 RENDEZÉS CSÖKKENŐ vásárolt(c, p, y), p CSATORNÁZVA c, y ANYAGOS;
VÁLASZTOZZ contactNév(Vevő c), név(Termék p) HA értékelés(c, p, 1997) < 3;
A rendszer automatikusan létrehoz egy táblázatot a típusok kulcsaival Ügyfél, Termék és INTEGER, hozzáadja ezt a két mezőt, és frissíti azok értékeit bármilyen változáskor. A továbbiakban, amikor ezekhez a funkciókhoz fordulunk, nem történik számítás, hanem az értékek olvasása a megfelelő mezőkből.
Ezzel a mechanizmussal például megszabadulhatunk a rekurzióktól (CTE) a lekérdezésekben. Különösen nézzük meg a csoportokat, amelyek fa struktúrát alkotnak a child/parent kapcsolattal (minden csoportnak van egy hivatkozása a szülőjére):
szülő = DATA Csoport (Csoport);
A funkcionális adatbázisban a rekurziók logikáját a következőképpen definiálhatjuk:
szint (Csoport gyermek, Csoport szülő) = REKURZIÓ 1l HA a gyermek Csoport ÉS a szülő == gyermek
LÉPÉS 2l HA a szülő == szülő($parent);
isParent (Csoport gyermek, Csoport szülő) = IGAZ HA a szint(gyermek, szülő) ANYAGI;
Mivel a funkciónak isParent MATERIALIZED-ra van állítva, egy táblázat fog létrejönni két kulccsal (csoportokkal), amelyben a mező isParent csak akkor lesz igaz, ha az első kulcs a második leszármazottja. A táblázatban lévő bejegyzések száma megegyezik a csoportok számával, megszorozva a fa átlagos mélységével. Ha például meg kell számolni egy adott csoport leszármazottainak számát, akkor ehhez a funkcióhoz fordulhatunk:
childrenCount (Csoport g) = Csoport ÖSSZEG 1 HA isParent(Csoport child, g);
A SQL lekérdezésben nem lesz CTE. Ehelyett egyszerű GROUP BY lesz.
Ezzel a mechanizmussal könnyedén végrehajtható az adatbázis denormalizálása, ha szükséges:
CLASS Order 'Rendelés';
dátum 'Dátum' = DATA DATE (Rendelés);
CLASS OrderDetail 'Rendelés sor';
order 'Rendelés' = DATA Order (OrderDetail);
date 'Dátum' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED;
A függvényhez való hozzáféréskor date a rendelés sor esetén a rendelési sorok táblájából olvasás történik azon mezőről, amelyhez index kapcsolódik. A rendelési dátum megváltoztatásakor a rendszer automatikusan újraszámítja a denormalizált dátumot a sorban.
Előnyök
Miért van szükség erre a mechanizmusra? A klasszikus DBMS-ek esetében, anélkül, hogy a lekérdezéseket át kellene írni, a fejlesztő vagy DBA csak módosíthatja az indexeket, meghatározhatja a statisztikát, és útmutatást adhat a lekérdezés tervezőnek, hogy hogyan hajtsa végre őket (ráadásul a HINT-ek csak kereskedelmi DBMS-ekben elérhetők). Bármit is tesznek, nem tudják az első lekérdezést a cikkben végrehajtani O (osztályok száma) lekérdezések módosítása és trigger-ek hozzáadása nélkül. Az itt javasolt rendszerben a fejlesztés során nem kell aggódni az adatok tárolási struktúrája és az agglegóriák használata miatt. Mindez zökkenőmentesen változtatható közvetlenül a használat során.
A gyakorlatban ez így néz ki. Néhány ember a felmerült feladat alapján fejleszti a logikát. Ők nem értenek sem az algoritmusokhoz és azok bonyolultságához, sem a végrehajtási tervekhez, sem a különböző join típusokhoz, sem pedig más technikai összetevőkhöz. Ezek az emberek inkább üzleti elemzők, mint fejlesztők. Ezután mindez tesztelésre vagy üzemeltetésre kerül. Bekapcsolják a hosszú lekérdezések naplózását. Amikor egy hosszú lekérdezést észlelnek, akkor már más emberek (technikaiabbak, lényegében DBA-k) döntenek arról, hogy egy köztes függvényen MATERIALIZED-t aktiválnak. Ezzel kissé lelassul a bejegyzés (mivel egy további mező frissítése szükséges a tranzakcióban). Azonban jelentősen felgyorsul nemcsak ez a lekérdezés, hanem minden más, amely ezt a funkciót használja. Ebben az esetben a döntés, hogy pontosan melyik függvényt materializálják, viszonylag egyszerűen megoldható. Két fő paraméter: a lehetséges bemeneti értékek száma (éppen annyi bejegyzés fog szerepelni a megfelelő táblában), és hogy milyen gyakran használják más funkciókban.
Analógia
A modern kereskedelmi DBMS-ek hasonló mechanizmusokkal rendelkeznek: AZ ANYAGIASÍTVA KÉPEZÉS FÁZISÚ FRISSÍTÉSSEL (Oracle) és AZ INDEXELT KÉPEZÉS (Microsoft SQL Server). A PostgreSQL-ben az ANYAGIASÍTOTT KÉPEZÉS nem frissíthető tranzakcióban, csak kérésre (ráadásul elég szigorú korlátozásokkal), így ezt nem vizsgáljuk. De van néhány problémájuk, amelyek jelentősen korlátozzák a használatukat.
Először is, a materializálás csak akkor aktíválható, ha korábban létrehoztak egy szokásos KÉPEZÉST. Ellenkező esetben át kell írni a többi kérdést az újonnan létrehozott nézetre történő hivatkozás érdekében, hogy ezt a materializálást használhassák. Vagy mindent hagyhat úgy, ahogy van, de ez legalábbis hatástalan lesz, ha vannak már előre számított adatok, amelyeket sok kérdés nem mindig használ, hanem újra kiszámít.
Másodszor, sok korlátozással rendelkeznek:
Oracle
5.3.8.4 Általános Korlátozások a Gyors Frissítéseknél
A materializált nézet meghatározó lekérdezése a következő korlátozásokkal rendelkezik:
- A materializált nézet nem tartalmazhat hivatkozásokat nem ismétlődő kifejezésekre, mint például
SYSDATEésROWNUM.- A materializált nézet nem tartalmazhat hivatkozásokat
RAWvagyHOSSZÚRAWadat típusokra.- Nem tartalmazhat
SELECTlistás a lekérdezés.- Nem tartalmazhat analitikai függvényeket (például,
RANG) aSELECTzáradékban.- Nem hivatkozhat egy olyan táblára, amelyen egy
XMLIndexindex van definiálva.- Nem tartalmazhat
MODELzáradékban.- Nem tartalmazhat
HAVINGzáradékot egy al-lekérdezéssel.- Nem tartalmazhatne fészkelt lekérdezéseket, amelyek vannak
Ez kissé furcsán hangzik, de a sémán — minden egyszerű.,ALL, vagyNEMVÉGE;.- Nem tartalmazhat
[KIVÉTELLEL …] KAPCSOLAT ÁLTALzáradékban.- Nem tartalmazhat több részletes táblát különböző helyeken.
ONCOMMITA materializált nézetek nem tartalmazhatnak távoli részletes táblákat.- A fészkelt materializált nézeteknek kontár vagy összesítő kell legyen.
- A materializált kontár nézeteknek és materializált összesítő nézeteknek
CSOPORTAZzáradék nem választhat az indexszervezett táblából.5.3.8.5 Korlátozások a Gyors Frissítésekre Csak Közös Materializált Nézetek esetén
A kötelező lekérdezések, amelyek csak közös materializált nézetek és nem aggregátumok, a következő korlátozásokkal rendelkeznek a gyors frissítések során:
- Minden korlátozás a „«.
- Nem tartalmazhatnak
CSOPORTAZzáradékokat vagy aggregátumokat.- A táblák ROWID-jának mind a
FROMlistájában fel kell bukkanniuk a lekérdezésSELECTlistájában.- A materializált nézet naplóknak létezniük kell a ROWID-kkal az összes alap táblához.
FROMlistájában.- Nem hozhatsz létre gyorsan frissíthető materializált nézetet több táblából egyszerű csatlakozásokkal, amelyek tartalmaznak egy objektum típusú oszlopot a
SELECTnyilatkozatban.A frissítési módszer, amelyet választasz, nem lesz optimálisan hatékony, ha:
- A meghatározó lekérdezés olyan külső csatlakozást használ, amely úgy viselkedik, mint egy belső csatlakozás. Ha a meghatározó lekérdezés tartalmaz egy ilyen csatlakozást, fontold meg a lekérdezés átírását, hogy tartalmazzon egy belső csatlakozást.
- A
SELECTA materializált nézet listája kifejezéseket tartalmaz több tábla oszlopain.5.3.8.6 Korlátozások a Gyors Frissítésekre Anyagiasított Nézeteknél Aggregátumokkal
A meghatározó lekérdezések, amelyek aggregátumokkal vagy közös lekérdezésekkel rendelkeznek, a következő korlátozásokkal rendelkeznek a gyors frissítések során:
- Minden korlátozás a „«.
A gyors frissítést támogatják mindkettő
ONCOMMITésONKERESLETmaterializált nézetek, azonban a következő korlátozások érvényesek:
- A materializált nézetben lévő összes táblának rendelkeznie kell materializált nézet naplókkal, és a materializált nézet naplóinak:
- Tartalmaznia kell az összes oszlopot a táblából, amelyre a materializált nézet hivatkozik.
- A ROWID-t meg kell határozni
TARTALMAZVAésÚJMeg kell határozni aVALUES.- záradékot, ha a táblának elegye van beszúrások/direkt betöltések, törlések és frissítések között.
SEQUENCECsak- ÖSSZEG
STDDEV,COUNT,AVG,VARIÁCIÓN,MAX,a kettő közül a legkisebbet választja.éstámogatott a gyors frissítéshez.COUNT(*)meg kell határozni.meg kell adni.- Az aggregáló függvényeknek a kifejezés legkülső részén kell előfordulniuk. Azaz, olyan aggregálók, mint például
AVG(AVG(x))vagyAVG(x)+AVG(x)nem engedélyezettek.- Minden aggregáló, mint például
AVG(expr), a megfelelőCOUNT(expr)jelen kell legyen. Az Oracle azt javasolja, hogySUM(expr)határozva legyen.- Ha
VARIANCE(expr)vagySTDDEV(expr) van meghatározva,COUNT(expr)ésSUM(expr)meg kell határozni. Az Oracle azt javasolja, hogySUM(expr *expr)határozva legyen.- A
SELECToszlop a definiáló lekérdezésben nem lehet komplex kifejezés, amely oszlopokat tartalmaz több alap táblából. Ezt megkerülheti egy beágyazott materializált nézettel.- A
SELECTA lista mindenCSOPORTAZoszlopot tartalmaznia kell.- A materializált nézet nem alapul egy vagy több távoli táblán.
- Ha egy
CHARadat típust használ a materializált nézet napló szűrő oszlopaiban, akkor a mesterhely és a materializált nézet karakterkészleteinek azonosaknak kell lenniük.- Ha a materializált nézet tartalmaz az alábbiak közül valamelyiket, akkor a gyors frissítés csak a hagyományos DML beszúrásokra és közvetlen betöltésre támogatott.
- Materializált nézetek aggregálókkal
a kettő közül a legkisebbet választja.vagytámogatott a gyors frissítéshez.Materializált nézetek, amelyek rendelkeznek- de nincs
SUM(expr)Materializált nézetek anélkül, hogyCOUNT(expr)- Egy ilyen materializált nézetet beszúrásra alkalmas materializált nézetnek neveznek.
meg kell határozni.Egy materializált nézet, amely
- gyorsan frissíthető törlés vagy vegyes DML utasítások után, ha nincs
támogatott a gyors frissítéshez.vagya kettő közül a legkisebbet választja.A max/min gyors frissítés törlés vagy vegyes DML után nem ugyanúgy működik, mint a beszúrásra alkalmas eset. Törli és újraszámolja a max/min értékeket az érintett csoportok számára. Tudnia kell a teljesítményhatását.AHOLzáradékban.
Materializált nézetek nézettel vagy részlekérdezésekkel a- záradékban gyorsan frissíthetők, amennyiben a nézeteket teljesen össze lehet vonni. Az összevonásra vonatkozó információkért lásd
FROMOracle Database SQL Language Reference .- A materializált aggregáló nézetek külső összekapcsolásokkal gyorsan frissíthetők hagyományos DML és közvetlen betöltések után, amennyiben csak a külső táblát módosították. Az is egyedi kényszereknek kell lenniük a belső összekapcsolás táblájának összekapcsolási oszlopaiban. Ha külső összekapcsolások vannak, az összes összekapcsolásnak kapcsolódnia kell
AHOLzáradékban.- és használniuk kell az egyenlőséget (
ÉS) operátort.=A materializált nézetekkel, amelyek rendelkeznek- CUBE
ROLLUP,, csoportosító halmazokkal, vagy azok összefűzésével, a következő korlátozások vonatkoznak:a lista csoportosító megkülönböztetőt kell tartalmazzon, amely lehet vagy egy
- A
SELECTGROUPING_IDfüggvény mindenkifejezésre, vagyCSOPORTAZGROUPINGfüggvények, egy mindenkifejezéshez. Például, ha a materializált nézet záradéka «CSOPORTAZCUBE(a, b)CSOPORTAZ«, akkor a lista tartalmaznia kell vagy «CSOPORTAZGROUPING_ID(a, b)» vagy «SELECTGROUPING(a)GROUPING(b)» a materializált nézet gyors frissítéséhez.nem szabad semmilyen duplikált csoportosítást eredményeznie. Például, «ÉSGROUP BY a, ROLLUP(a, b)» nem gyorsan frissíthető, mert duplikált csoportosítást eredményez «CSOPORTAZ(a), (a, b), ÉS (a)5.3.8.7 Korlátozások a gyors frissítésre az UNION ALL-lel rendelkező materializált nézeteknélAz UNION ALL-t tartalmazó materializált nézetek aset operátor támogatják«.REFRESH
FAST
UNIONALLopciót, ha a következő feltételek teljesülnek:A definiáló lekérdezésnek aoperátornak a legfelső szinten kell lennie.Az operátor nem ágyazható be egy részlekérdezésbe, egy kivétel van: A
- egy részlekérdezésben lehet a
UNIONALLzáradékban, amennyiben a definiáló lekérdezés a következő formában van:A
UNIONALLSELECT * FROMUNIONALL(nézet vagy részlekérdezés, amely tartalmazzaFROM) mint a következő példában:CREATE VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM customers c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM customers c WHERE c.cust_last_name = 'Jones');CREATE MATERIALIZED VIEW unionall_inside_view_mv REFRESH FAST ON DEMAND AS SELECT * FROM view_with_unionall;Vegye figyelembe, hogy a nézetUNIONALLview_with_unionallteljesíti a gyors frissítés követelményeit.Minden lekérdezési blokk a
lekérdezésnek meg kell felelnie a gyorsan frissíthető materializált nézet aggregátorokkal vagy gyorsan frissíthető materializált nézetekkel kapcsolatos követelményeknek.A megfelelő materializált nézet naplókat a táblákon kell létrehozni a megfelelő gyorsan frissíthető materializált nézet típusához szükségesek.- Minden lekérdezési blokk a
UNIONALLlekérdezésnek meg kell felelnie a gyorsan frissíthető anyagolt nézet aggregátumokkal vagy a gyorsan frissíthető anyagolt nézet összekapcsolásokkal szemben támasztott követelményeknek.A megfelelő anyagolt nézet naplók létrehozása szükséges a táblákon, ahogy azt a megfelelő típusú gyorsan frissíthető anyagolt nézet megköveteli.
Vegye figyelembe, hogy az Oracle Database különleges esetként lehetővé teszi egyetlen táblás materializált nézet létrehozását, amely csak lekérdezéseket tartalmaz, ha aTARTALMAZVAoszlop szerepel aSELECTlistában és a materializált nézet naplóban. Ezt a nézet definíciós lekérdezésében mutatják be.lekérdezésnek meg kell felelnie a gyorsan frissíthető materializált nézet aggregátorokkal vagy gyorsan frissíthető materializált nézetekkel kapcsolatos követelményeknek..- A
SELECTMinden lekérdezés listájának tartalmaznia kell egyUNIONALLjelölőt, és aUNIONALLoszlopnak egyedi állandó numerikus vagy karakterértékkel kell rendelkeznie mindenUNIONALLágban. Ezen túlmenően a jelölő oszlopnak ugyanabban a sorszámban kell szerepelnie aSELECTlekérdezési blokk listájában. További információk találhatók a «» című részben.UNIONALLjelölőkről.- Egyes funkciók, mint például a külső csatlakozások, csak beszúró halmozott materializált nézet lekérdezések és távoli táblák nem támogatottak a materializált nézetekhez.
UNIONALL. Vegye figyelembe, hogy a replikációval használt materializált nézetek, amelyek nem tartalmaznak csatlakozásokat vagy halmozásokat, gyorsan újra frissíthetők, haUNIONALLvagy távoli táblák használatosak.- A kompatibilitási inicializáló paraméternek 9.2.0 vagy magasabb értékre kell lennie beállítva, hogy gyors frissíthető materializált nézetet hozhassunk létre.
UNIONALL.
Nem szeretném megbántani az Oracle rajongóit, de az ő korlátozási listájuk alapján az a benyomásom támadt, hogy ezt a mechanizmust nem általános esetben írták, hanem valamilyen modell felhasználásával, hanem több ezer indiai fejlesztő, akik mindegyike a saját ágát írta, és mindegyikük azt csinált, amire képes volt. Ennek a mechanizmusnak a használata a valódi logikában olyan, mint egy aknamezőn járni. Bármikor felrobbanhat egy akna, ha rátalálunk egy nem nyilvánvaló korlátozásra. A működése is egy külön kérdés, de ez a cikk keretein kívül esik.
Microsoft SQL Server
További követelmények
A SET opciók és a determinisztikus függvény követelmények mellett a következő követelményeknek is meg kell felelni:
- A felhasználónak, aki végrehajtja
CREATE INDEXa nézet tulajdonosának kell lennie.- Amikor létrehozza az indexet, a
IGNORE_DUP_KEYopciónak OFF-ra (az alapértelmezett beállítás) kell lennie állítva.- A táblákat két részes névvel kell hivatkozni, schema.tablename a nézet definíciójában.
- A nézetben hivatkozott felhasználó által létrehozott függvényeknek a
WITH SCHEMABINDINGopcióval kell létrehozva lenniük.- A nézetben hivatkozott minden felhasználó által létrehozott függvénynek két részes néven kell szerepelnie, <schema>.<function>.
- A felhasználó által meghatározott függvény adat-hozzáférési tulajdonságának
NO SQL, és a külső hozzáférési tulajdonságánakNO.- A közös nyelv futtatási (CLR) függvények megjelenhetnek a nézet választási listájában, de nem lehetnek a klaszterezett index kulcs definíciójának részét képezniük. A CLR függvények nem jelenhetnek meg a nézet WHERE záradékában vagy a JOIN művelet ON záradékában a nézetben.
- A nézet definíciójában használt CLR függvénynek és CLR felhasználó által meghatározott típusának a következő táblázatban bemutatott tulajdonságokkal kell rendelkeznie.
Tulajdonság
MegjegyzésDETERMINISTIC = TRUE
Kifejezetten a Microsoft .NET Framework metódus attribútumaként kell deklarálni.PRECISE = TRUE
Kifejezetten a .NET Framework metódus attribútumaként kell deklarálni.ADATA HOZZÁFÉRÉS = NO SQL
Ez a DataAccess attribútum DataAccessKind.None-ra és a SystemDataAccess attribútum SystemDataAccessKind.None-ra állításával van meghatározva.KÜLSŐ HOZZÁFÉRÉS = NO
Ez a tulajdonság alapértelmezés szerint NO a CLR rutinok esetében.- A nézetet a következő módon kell létrehozni:
WITH SCHEMABINDINGopcióval kell létrehozva lenniük.- A nézetnek csak az ugyanabban az adatbázisban lévő alap táblákra kell hivatkoznia. A nézet nem hivatkozhat más nézetekre.
- A nézet definíciós SELECT nyilatkozatának nem szabad tartalmaznia a következő Transact-SQL elemeket:
COUNT
ROWSET függvények (OPENDATASOURCE,OPENQUERY,OPENROWSET, ÉSOPENXML)
KÜLSŐcsatlakozások (BAL,JOBB, vagyTELJES)Származtatott tábla (amelyet úgy definiálunk, hogy megadunk egy
SELECTállítást aFROMzáradékban)
Öncsatlakozások
Oszlopok megadásaSELECT *vagySELECT.*
DISTINCT
STDEV,STDEVP,VAR,VARP, vagyAVG
Közös táblázati kifejezés (CTE)lebegőpontos1, szöveg, ntext, kép, XML, vagy fájlstream oszlopok
Alkérdés
OVERzáradék, amely rangsorolási vagy aggregáló ablakfüggvényeket tartalmazTeljes szöveges predikátumok (
TARTALMAZ,SZABAD SZÖVEG)
STDDEVfüggvény, amely hivatkozik egy nullable kifejezésre
Rendezés után,CLR felhasználó által definiált aggregáló függvény
FELSŐ
ROLLUP,, csoportosító halmazokkal, vagy azok összefűzésével, a következő korlátozások vonatkoznak:, vagyCsoportosító készletekoperátorok
a kettő közül a legkisebbet választja.,támogatott a gyors frissítéshez.
UNION,KIVÉVE, vagyINTERSECToperátorok
TÁBLAMINTATábla változók
KÜLSŐ ALKALMAZÁSvagyCROSS APPLY
FORGATÁS,FORGATÁS VISSZARitka oszlopkészletek
Inline (TVF) vagy többs statements táblázatos értékű függvények (MSTVF)
OFFSET
CHECKSUM_AGG1 Az indexelt nézet tartalmazhat lebegőpontos oszlopokat; azonban az ilyen oszlopok nem szerepelhetnek a klaszterezett index kulcsában.
- Ha
A rekurzív „táblázás” nem található egy beágyazott lekérdezésben.ha jelen van, a NÉZET definíciójának tartalmaznia kellCOUNT_BIG(*)és nem tartalmazhatHAVING. EzekA rekurzív „táblázás” nem található egy beágyazott lekérdezésben.korlátozások csak az indexelt nézet definíciójára vonatkoznak. Egy lekérdezés használhat egy indexelt nézetet a végrehajtási tervében, még akkor is, ha nem teljesíti ezeket aA rekurzív „táblázás” nem található egy beágyazott lekérdezésben.korlátozásokat.- Ha a nézet definíció tartalmaz egy
A rekurzív „táblázás” nem található egy beágyazott lekérdezésben.záradékot, akkor az egyedi klaszterezett index kulcsa csak azokat az oszlopokat hivatkozhatja, amelyeket aA rekurzív „táblázás” nem található egy beágyazott lekérdezésben.záradékban.Itt látható, hogy az indiaiakat nem vonzották, mivel úgy döntöttek, hogy "keveset, de jót" készítenek. Vagyis nekik több aknájuk van a mezőn, de elhelyezésük átláthatóbb. Legjobban ez a korlátozás bántja:
A nézetnek csak az ugyanabban az adatbázisban lévő alap táblákra kell hivatkoznia. A nézet nem hivatkozhat más nézetekre.
A mi terminológiánkban ez azt jelenti, hogy a függvény nem hivatkozhat egy másik materializált függvényre. Ez aláássa az egész ideológiát.
Ezen korlátozás (és a továbbiakban) nagyon erősen csökkenti a használati lehetőségeket:A nézet definíciós SELECT nyilatkozatának nem szabad tartalmaznia a következő Transact-SQL elemeket:
COUNT
ROWSET függvények (OPENDATASOURCE,OPENQUERY,OPENROWSET, ÉSOPENXML)
KÜLSŐcsatlakozások (BAL,JOBB, vagyTELJES)Származtatott tábla (amelyet úgy definiálunk, hogy megadunk egy
SELECTállítást aFROMzáradékban)
Öncsatlakozások
Oszlopok megadásaSELECT *vagySELECT.*
DISTINCT
STDEV,STDEVP,VAR,VARP, vagyAVG
Közös táblázati kifejezés (CTE)lebegőpontos1, szöveg, ntext, kép, XML, vagy fájlstream oszlopok
Alkérdés
OVERzáradék, amely rangsorolási vagy aggregáló ablakfüggvényeket tartalmazTeljes szöveges predikátumok (
TARTALMAZ,SZABAD SZÖVEG)
STDDEVfüggvény, amely hivatkozik egy nullable kifejezésre
Rendezés után,CLR felhasználó által definiált aggregáló függvény
FELSŐ
ROLLUP,, csoportosító halmazokkal, vagy azok összefűzésével, a következő korlátozások vonatkoznak:, vagyCsoportosító készletekoperátorok
a kettő közül a legkisebbet választja.,támogatott a gyors frissítéshez.
UNION,KIVÉVE, vagyINTERSECToperátorok
TÁBLAMINTATábla változók
KÜLSŐ ALKALMAZÁSvagyCROSS APPLY
FORGATÁS,FORGATÁS VISSZARitka oszlopkészletek
Inline (TVF) vagy többs statements táblázatos értékű függvények (MSTVF)
OFFSET
CHECKSUM_AGGKülső JOINS, UNION, REND SZERINT és hasonlók tilosak. Lehet, hogy egyszerűbb lett volna megjelölni, hogy mit lehet használni, mint amit nem. A lista valószínűleg sokkal rövidebb lett volna.
Összefoglalva: hatalmas mennyiségű korlátozás minden (megjegyzem kereskedelmi) DBMS esetében, szemben az LGPL technológia által nem jelentett semmivel (kivéve egy logikai, nem technikai) esetet. Meg kell azonban jegyezni, hogy ezt a mechanizmust relációs logikában néhány dologban nehezebb megvalósítani, mint a leírt funkcionális.
Megvalósítás
Hogyan működik? A "virtuális gépként" a PostgreSQL-t használják. Belül egy bonyolult algoritmus van, amely a lekérdezések felépítésével foglalkozik. Itt . És nem csak egy nagy halom heurisztika sok if-vel. Tehát, ha van pár hónapod a tanulmányozásra, akkor megpróbálhatsz belemerülni az architektúrába.
Mennyire működik ez hatékonyan? Meglehetősen hatékonyan. Sajnos nehéz ezt bizonyítani. Csak annyit mondhatok, hogy ha megnézzük a nagy alkalmazásokban található ezer lekérdezést, akkor átlagosan hatékonyabbak, mint egy jó fejlesztőé. Egy kiváló SQL-programozó bármely lekérdezést hatékonyabban tudna írni, de ezer lekérdezés esetén egyszerűen nem lenne sem motivációja, sem ideje erre. Az egyetlen dolog, amit most bizonyítékként felhozhatok a hatékonyságról, az az, hogy az ezen az adatbázison alapuló platformon néhány projekt működik , amelyekben ezer különböző MATERIALIZED funkció található, ezer felhasználóval és terabájt méretű adatbázisokkal, amelyek több száz millió rekordot kezelnek egy átlagos, kétprocesszoros szerveren. Mindazonáltal bárki ellenőrizheti vagy megcáfolhatja a hatékonyságot azzal, hogy letölti és a PostgreSQL-t, beállítja az SQL-lekérdezések naplózását, és megpróbálja módosítani a logikát és az adatokat.
A következő cikkekben arról is beszélni fogok, hogyan lehet korlátozásokat beállítani a funkciókra, a változáskezelési munkamenetekre és sok egyébre.
Forrás: habr.comMegbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster
