Kirjoitusten ja lukujen tasapainottaminen tietokannassa

Kirjoitusten ja lukujen tasapainottaminen tietokannassa
Edellisessä статье Kuvasin tietokannan käsitettä ja toteutusta, joka on rakennettu funktioiden perusteella, eikä taulukkojen ja kenttien perusteella, kuten relaatiotietokannassa. Se tarjosi monia esimerkkejä, jotka osoittavat tämän lähestymistavan edut klassiseen lähestymistapaan verrattuna. Monien mielestä ne eivät olleet tarpeeksi vakuuttavia.

Tässä artikkelissa näytän, kuinka tämän konseptin avulla voit nopeasti ja kätevästi tasapainottaa kirjoitus- ja lukutiedot tietokantaan ilman muutoksia toimintalogiikassa. Vastaavia toimintoja on yritetty toteuttaa nykyaikaisissa kaupallisissa DBMS-järjestelmissä (erityisesti Oracle ja Microsoft SQL Server). Artikkelin lopussa näytän, että se, mitä he tekivät, ei lievästi sanottuna toiminut kovin hyvin.

Kuvaus

Kuten ennenkin, aloitan kuvauksen esimerkeillä ymmärtääkseni paremmin. Oletetaan, että meidän on otettava käyttöön logiikka, joka palauttaa luettelon osastoista, joissa on työntekijöiden lukumäärä ja heidän kokonaispalkkansa.

Toiminnallisessa tietokannassa se näyttäisi tältä:

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

Tämän kyselyn suorittamisen monimutkaisuus missä tahansa DBMS:ssä vastaa O (työntekijöiden määrä)koska tämä laskelma vaatii koko työntekijätaulukon skannaamisen ja ryhmittelyn osastoittain. Tulee myös pieni (uskomme, että työntekijöitä on paljon enemmän kuin osastoja) täydennys valitusta suunnitelmasta riippuen O (loki työntekijöiden lukumäärä) tai O (osastojen lukumäärä) ryhmittelyyn ja niin edelleen.

On selvää, että suorituksen lisäkustannukset voivat olla erilaisia ​​eri DBMS-järjestelmissä, mutta monimutkaisuus ei muutu millään tavalla.

Ehdotetussa toteutuksessa toimiva DBMS luo yhden alikyselyn, joka laskee osastolle vaaditut arvot ja tekee sitten JOIN osastotaulukon kanssa saadakseen nimen. Jokaiselle funktiolle on kuitenkin mahdollista asettaa erityinen MATERIALIZED-merkki ilmoittamisen yhteydessä. Järjestelmä luo automaattisesti vastaavan kentän jokaiselle tällaiselle toiminnolle. Kun funktion arvoa muutetaan, myös kentän arvo muuttuu samassa tapahtumassa. Kun käytät tätä toimintoa, esilaskettu kenttä avataan.

Erityisesti, jos määrität toiminnoille MATERIALIZED laskea työntekijöitä и palkkasumma, sitten osastoluettelon sisältävään taulukkoon lisätään kaksi kenttää, joihin tallennetaan työntekijöiden lukumäärä ja heidän kokonaispalkkansa. Aina kun työntekijöissä, heidän palkoissaan tai osastojen sidoksissa tapahtuu muutoksia, järjestelmä muuttaa automaattisesti näiden kenttien arvoja. Yllä oleva kysely pääsee suoraan näihin kenttiin, ja se suoritetaan O (osastojen lukumäärä).

Mitkä ovat rajoitukset? Vain yksi asia: sellaisella funktiolla on oltava rajallinen määrä syöttöarvoja, joille sen arvo on määritelty. Muuten on mahdotonta rakentaa taulukkoa, joka tallentaa kaikki sen arvot, koska ei voi olla taulukkoa, jossa on ääretön määrä rivejä.

Esimerkiksi:

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

Tämä funktio on määritetty äärettömälle määrälle N:n arvoja (esimerkiksi mikä tahansa negatiivinen arvo on sopiva). Siksi siihen ei voi laittaa MATERIALIZEDIA. Tämä on siis looginen rajoitus, ei tekninen (eli ei siksi, että emme voisi toteuttaa sitä). Muuten ei ole rajoituksia. Voit käyttää ryhmittelyjä, lajittelua, AND ja OR, OSIOTA, rekursiota jne.

Esimerkiksi edellisen artikkelin tehtävässä 2.2 voit laittaa MATERIALIZED molempiin toimintoihin:

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;

Järjestelmä itse luo yhden taulukon tyyppiavaimilla Asiakas, Tuotteet и KOKONAISLUKU, lisää siihen kaksi kenttää ja päivittää niissä olevat kenttien arvot mahdollisilla muutoksilla. Kun näitä funktioita kutsutaan lisää, niitä ei lasketa, vaan arvot luetaan vastaavista kentistä.

Tämän mekanismin avulla voit esimerkiksi päästä eroon kyselyiden rekursioista (CTE). Harkitse erityisesti ryhmiä, jotka muodostavat puun käyttämällä lapsi/vanhempi-suhdetta (jokaisella ryhmällä on linkki vanhempaansa):

parent = DATA Group (Group);

Toiminnallisessa tietokannassa rekursiologiikka voidaan määrittää seuraavasti:

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;

Koska toiminto isParent on merkitty AINEISTETTU, niin sille luodaan taulukko kahdella avaimella (ryhmällä), jossa kenttä isParent on totta vain, jos ensimmäinen avain on toisen avain. Tämän taulukon merkintöjen määrä on yhtä suuri kuin ryhmien lukumäärä kerrottuna puun keskimääräisellä syvyydellä. Jos haluat esimerkiksi laskea tietyn ryhmän jälkeläisten lukumäärän, voit käyttää tätä toimintoa:

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

SQL-kyselyssä ei ole CTE:tä. Sen sijaan tulee yksinkertainen GROUP BY.

Tämän mekanismin avulla voit myös helposti denormalisoida tietokannan tarvittaessa:

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

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

Kun toimintoa kutsutaan data tilausriville kenttä, jolle on indeksi, luetaan tilausrivien taulukosta. Kun tilauspäivämäärä muuttuu, järjestelmä itse laskee automaattisesti uudelleen rivillä olevan denormaalin päivämäärän.

Edut

Mitä varten tämä koko mekanismi on? Klassisissa DBMS-järjestelmissä kehittäjä tai DBA voi ilman kyselyjen uudelleenkirjoittamista muuttaa vain indeksejä, määrittää tilastoja ja kertoa kyselysuunnittelijalle, kuinka ne suoritetaan (ja VIHJEET ovat saatavilla vain kaupallisissa DBMS-järjestelmissä). Vaikka he yrittäisivät kuinka kovasti, he eivät pysty täyttämään artikkelin ensimmäistä kyselyä O (osastojen lukumäärä) muuttamatta kyselyitä tai lisäämättä laukaisimia. Ehdotetussa mallissa sinun ei kehitysvaiheessa tarvitse miettiä tiedon tallennusrakennetta ja mitä aggregaatioita käyttää. Kaikki tämä voidaan helposti muuttaa lennossa, suoraan toiminnassa.

Käytännössä se näyttää tältä. Jotkut ihmiset kehittävät logiikkaa suoraan käsillä olevan tehtävän perusteella. He eivät ymmärrä algoritmeja ja niiden monimutkaisuutta, toteutussuunnitelmia, liitostyyppejä tai muita teknisiä komponentteja. Nämä ihmiset ovat enemmän yritysanalyytikoita kuin kehittäjiä. Sitten kaikki tämä menee testaukseen tai käyttöön. Mahdollistaa pitkäaikaisten kyselyiden kirjaamisen. Kun pitkä kysely havaitaan, muut ihmiset (teknisempiä - lähinnä DBA) päättävät ottaa MATERIALIZEDin käyttöön jossain välitoiminnossa. Tämä hidastaa tallennusta hieman (koska se vaatii lisäkentän päivittämistä tapahtumassa). Tämä kysely ei kuitenkaan ole merkittävästi nopeutunut, vaan myös kaikki muut, jotka käyttävät tätä toimintoa. Samalla on suhteellisen helppoa päättää, mikä funktio toteutetaan. Kaksi pääparametria: mahdollisten syöttöarvojen määrä (näin monta tietuetta on vastaavassa taulukossa) ja kuinka usein sitä käytetään muissa toiminnoissa.

analogit

Nykyaikaisissa kaupallisissa DBMS-järjestelmissä on samanlaiset mekanismit: MATERIALIZED VIEW ja FAST REFRESH (Oracle) ja INDEXED VIEW (Microsoft SQL Server). PostgreSQL:ssä MATERIALIZED VIEW -ohjelmaa ei voi päivittää tapahtumassa, vaan vain pyynnöstä (ja jopa erittäin tiukoin rajoituksin), joten emme ota sitä huomioon. Mutta niillä on useita ongelmia, jotka rajoittavat merkittävästi niiden käyttöä.

Ensinnäkin voit ottaa materialisoinnin käyttöön vain, jos olet jo luonut tavallisen NÄKYMÄN. Muussa tapauksessa sinun on kirjoitettava uudelleen loput pyynnöt päästäksesi äskettäin luotuun näkymään käyttääksesi tätä materialisaatiota. Tai jätä kaikki ennalleen, mutta se on ainakin tehotonta, jos on olemassa tiettyjä jo ennalta laskettuja tietoja, mutta monet kyselyt eivät aina käytä sitä, vaan laskevat sen uudelleen.

Toiseksi heillä on valtava määrä rajoituksia:

oraakkeli

5.3.8.4 Yleiset nopean päivityksen rajoitukset

Toteutuneen näkymän määrittelykyselyä rajoitetaan seuraavasti:

  • Toteutunut näkymä ei saa sisältää viittauksia ei-toistuviin ilmaisuihin, kuten SYSDATE ja ROWNUM.
  • Toteutunut näkymä ei saa sisältää viittauksia RAW or LONG RAW tietotyypit.
  • Se ei voi sisältää a SELECT luettelon alikysely.
  • Se ei voi sisältää analyyttisiä toimintoja (esim. RANK) On SELECT lauseke.
  • Se ei voi viitata taulukkoon, jossa an XMLIndex indeksi on määritelty.
  • Se ei voi sisältää a MODEL lauseke.
  • Se ei voi sisältää a HAVING lauseke alikyselyllä.
  • Se ei voi sisältää sisäkkäisiä kyselyitä, joilla on ANY, ALLtai NOT EXISTS.
  • Se ei voi sisältää a [START WITH …] CONNECT BY lauseke.
  • Se ei voi sisältää useita tietotaulukoita eri sivustoissa.
  • ON COMMIT toteutuneissa näkymissä ei voi olla etätietotaulukoita.
  • Sisäkkäisillä materialisoiduilla näkymillä on oltava liitos tai kooste.
  • Toteutuneet liitosnäkymät ja materialisoidut koostenäkymät a GROUP BY lauseketta ei voi valita indeksijärjestetystä taulukosta.

5.3.8.5 Nopean päivityksen rajoitukset materialisoiduissa näkymissä, joissa on vain liitoksia

Kyselyjen määrittämisessä materialisoituneille näkymille, joissa on vain liitoksia, mutta ei aggregaatteja, on seuraavat rajoitukset nopealle päivitykselle:

  • Kaikki rajoitukset alkaen «Yleiset rajoitukset nopealle päivitykselle".
  • Heillä ei voi olla GROUP BY lausekkeita tai aggregaatteja.
  • Kaikkien taulukoiden rivit FROM luettelon tulee näkyä SELECT kyselyn luettelo.
  • Toteutuneiden näkymälokien on oltava rivien kanssa kaikissa perustaulukoissa FROM kyselyn luettelo.
  • Et voi luoda nopeasti päivitettävää materialisoitua näkymää useista taulukoista yksinkertaisilla liitoksilla, jotka sisältävät objektityyppisarakkeen SELECT lausuma.

Valitsemasi päivitysmenetelmä ei myöskään ole optimaalisen tehokas, jos:

  • Määrittävä kysely käyttää ulkoliitosta, joka toimii kuin sisäliitos. Jos määrittävä kysely sisältää tällaisen liitoksen, harkitse määrittävän kyselyn uudelleenkirjoittamista sisältämään sisäinen liitos.
  • - SELECT materialisoidun näkymän luettelo sisältää lausekkeita useiden taulukoiden sarakkeissa.

5.3.8.6 Aggregaatteja sisältävien materialisoitujen näkymien nopean päivityksen rajoitukset

Aggregaatteja tai liitoksia sisältävien materialisoituneiden näkymien kyselyjen määrittämisessä on seuraavat rajoitukset nopealle päivitykselle:

Nopea päivitys on tuettu molemmille ON COMMIT ja ON DEMAND toteutuneet näkemykset, mutta seuraavat rajoitukset ovat voimassa:

  • Kaikissa materialisoidun näkymän taulukoissa on oltava materialisoituneet näkymälokit, ja materialisoituneiden näkymälokien on:
    • Sisällytä kaikki materialisoidussa näkymässä viitatun taulukon sarakkeet.
    • Määritä kanssa ROWID ja INCLUDING NEW VALUES.
    • Määritä SEQUENCE lauseke, jos taulukossa odotetaan olevan sekoitus lisäyksiä/suoralatauksia, poistoja ja päivityksiä.

  • Vain SUM, COUNT, AVG, STDDEV, VARIANCE, MIN ja MAX ovat tuettuja nopeaa päivitystä varten.
  • COUNT(*) on täsmennettävä.
  • Aggregaattifunktiot saavat esiintyä vain lausekkeen uloimpana osana. Eli aggregaatit, kuten AVG(AVG(x)) or AVG(x)+ AVG(x) eivät ole sallittuja.
  • Jokaiselle aggregaatille, kuten AVG(expr), vastaava COUNT(expr) täytyy olla läsnä. Oracle suosittelee sitä SUM(expr) täsmennettävä.
  • If VARIANCE(expr) or STDDEV(expr) on määritelty, COUNT(expr) ja SUM(expr) on täsmennettävä. Oracle suosittelee sitä SUM(expr *expr) täsmennettävä.
  • - SELECT sarake määrittelykyselyssä ei voi olla monimutkainen lauseke, jossa on sarakkeita useista perustaulukoista. Mahdollinen kiertotapa tähän on käyttää sisäkkäistä materialisoitua näkymää.
  • - SELECT luettelon tulee sisältää kaikki GROUP BY sarakkeita.
  • Toteutunut näkymä ei perustu yhteen tai useampaan etätaulukkoon.
  • Jos käytät a CHAR materialisoidun näkymälokin suodatinsarakkeiden tietotyyppi, pääsivuston ja materialisoidun näkymän merkistöjen on oltava samat.
  • Jos materialisoidussa näkymässä on jokin seuraavista, nopeaa päivitystä tuetaan vain tavanomaisissa DML-lisäyksissä ja suorissa latauksissa.
    • Toteutuneet näkymät MIN or MAX aggregaatit
    • Toteutuneet näkymät, joilla on SUM(expr) mutta ei COUNT(expr)
    • Toteutuneet näkymät ilman COUNT(*)

    Tällaista materialisoitua näkymää kutsutaan vain lisättäväksi materialisoiduksi näkymäksi.

  • Toteutunut näkymä MAX or MIN on nopeasti päivitettävissä poistamisen tai sekoitettujen DML-käskyjen jälkeen, jos siinä ei ole a WHERE lauseke.
    Maksimi/min-pikapäivitys poistamisen tai seka-DML:n jälkeen ei toimi samalla tavalla kuin vain lisäystapauksessa. Se poistaa ja laskee uudelleen maksimi-/minuuttiarvot kyseisille ryhmille. Sinun on oltava tietoinen sen tehokkuudesta.
  • Toteutetut näkymät, joissa on nimetyt näkymät tai alikyselyt FROM lauseke voidaan päivittää nopeasti, jos näkymät voidaan yhdistää kokonaan. Katso lisätietoja siitä, mitkä näkymät yhdistetään Oracle Database SQL Language Reference.
  • Jos ulkoisia liitoksia ei ole, sinulla voi olla mielivaltaisia ​​valintoja ja liitoksia WHERE lauseke.
  • Materialisoidut koontinäkymät, joissa on ulommat liitokset, ovat nopeasti päivitettävissä tavanomaisten DML- ja suorien latausten jälkeen, mikäli vain ulompaa taulukkoa on muokattu. Myös sisäisen liitostaulukon liitossarakkeissa on oltava yksilölliset rajoitukset. Jos ulompia liitoksia on, kaikki liitokset on yhdistettävä ANDs ja täytyy käyttää tasa-arvoa (=) -operaattori.
  • Toteutuneille näkymille CUBE, ROLLUP, ryhmittelyjoukot tai niiden ketjuttaminen, seuraavat rajoitukset ovat voimassa:
    • - SELECT luettelon tulee sisältää ryhmittelyerotin, joka voi olla joko a GROUPING_ID toimii kaikissa GROUP BY ilmaisuja tai GROUPING toimii yksi kullekin GROUP BY ilmaisu. Esimerkiksi jos GROUP BY toteutuneen näkemyksen lauseke on "GROUP BY CUBE(a, b)", sitten SELECT listan tulee sisältää joko "GROUPING_ID(a, b)» tai «GROUPING(a) AND GROUPING(b)» jotta toteutunut näkymä olisi nopeasti päivitettävissä.
    • GROUP BY ei saa johtaa päällekkäisiin ryhmittelyihin. Esimerkiksi, "GROUP BY a, ROLLUP(a, b)"ei päivitettävissä nopeasti, koska se johtaa päällekkäisiin ryhmittelyihin"(a), (a, b), AND (a)".

5.3.8.7 Toteutuneiden näkymien nopean päivityksen rajoitukset UNION ALL:lla

Toteutuneet näkymät UNION ALL aseta operaattorin tuki REFRESH FAST vaihtoehto, jos seuraavat ehdot täyttyvät:

  • Määrittävässä kyselyssä on oltava UNION ALL operaattori huipputasolla.

    - UNION ALL -operaattoria ei voida upottaa alikyselyyn, lukuun ottamatta yhtä poikkeusta: The UNION ALL voi olla alikyselyssä kohdassa FROM lauseke edellyttäen, että määrittävä kysely on muotoa SELECT * FROM (katso tai alikysely käyttämällä UNION ALL) kuten seuraavassa esimerkissä:

    CREATE VIEW view_with_unionall AS (VALITSE c.rowid crid, c.cust_id, 2 umarker FROM asiakkailta c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM asiakkailta c WHERE c.cust_last "Jones"); LUO AINEISTETTU NÄKYMÄ unionall_inside_view_mv PÄIVITYS NOPEASTI KYSYMYKSIÄ KUIN SELECT * FROM view_with_unionall;
    

    Huomaa, että näkymä view_with_unionall täyttää nopean päivityksen vaatimukset.

  • Jokainen kyselylohko UNION ALL kyselyn on täytettävä nopeasti päivitettävän materialisoidun näkymän vaatimukset aggregaattein tai nopeasti päivitettävän materialisoidun näkymän liitoksilla.

    Taulukoihin on luotava sopivat materialisoidut näkymälokit vastaavan tyyppisen nopeasti päivitettävän materialisoidun näkymän edellyttämällä tavalla.
    Huomaa, että Oracle Database sallii myös yksittäisen taulukon materialisoidun näkymän erikoistapauksen liitoksilla vain, jos ROWID sarake on sisällytetty SELECT luettelossa ja materialisoituneen näkymän lokissa. Tämä näkyy näkymän määrittelykyselyssä view_with_unionall.

  • - SELECT jokaisen kyselyn luettelossa on oltava a UNION ALL merkki, ja UNION ALL sarakkeessa on oltava erillinen vakio numeerinen tai merkkijonoarvo jokaisessa UNION ALL haara. Lisäksi merkkisarakkeen on oltava samassa järjestyskohdassa SELECT luettelo kustakin kyselylohkosta. Katso "UNIONIN KAIKKI Merkin ja kyselyn uudelleenkirjoitus» lisätietoja aiheesta UNION ALL markkereita.
  • Joitakin ominaisuuksia, kuten ulkoliitokset, vain lisättävät koostematerialisoidut näkymäkyselyt ja etätaulukot, ei tueta materialisoiduissa näkymissä UNION ALL. Huomaa kuitenkin, että replikaatiossa käytetyt materialisoidut näkymät, jotka eivät sisällä liitoksia tai aggregaatteja, voidaan päivittää nopeasti, kun UNION ALL tai etäpöytiä käytetään.
  • Yhteensopivuuden alustusparametrin arvoksi on asetettava 9.2.0 tai korkeampi, jotta voidaan luoda nopeasti päivitettävä materialisoitu näkymä UNION ALL.

En halua loukata Oracle-faneja, mutta heidän rajoitusluettelonsa perusteella näyttää siltä, ​​​​että tämä mekanismi ei ollut yleisessä tapauksessa jonkinlaista mallia käyttäen, vaan tuhansien intialaisten kirjoittama, jossa kaikille annettiin mahdollisuus kirjoittaa oman haaransa, ja jokainen heistä teki mitä pystyi ja teki. Tämän mekanismin käyttäminen todelliseen logiikkaan on kuin kävelemistä miinakentän läpi. Voit hankkia miinan milloin tahansa osumalla johonkin ei-ilmeisistä rajoituksista. Se, miten se toimii, on myös erillinen kysymys, mutta se ei kuulu tämän artikkelin soveltamisalaan.

Microsoft SQL Server

Lisävaatimukset

SET-vaihtoehtojen ja determinististen toimintovaatimusten lisäksi seuraavat vaatimukset on täytettävä:

  • Käyttäjä, joka suorittaa CREATE INDEX on oltava näkymän omistaja.
  • Kun luot hakemiston, IGNORE_DUP_KEY vaihtoehdon on oltava OFF (oletusasetus).
  • Taulukoihin on viitattava kaksiosaisilla nimillä, malli.taulukon nimi näkymän määritelmässä.
  • Näkymässä viitatut käyttäjän määrittämät funktiot on luotava käyttämällä WITH SCHEMABINDING vaihtoehto.
  • Kaikkiin näkymässä viitattuihin käyttäjän määrittämiin funktioihin on viitattava kaksiosaisilla nimillä, ..
  • Käyttäjän määrittämän funktion tiedonkäyttöominaisuuden on oltava NO SQL, ja ulkoisen pääsyn ominaisuuden on oltava NO.
  • Common Language Runtime (CLR) -funktiot voivat näkyä näkymän valintaluettelossa, mutta ne eivät voi olla osa klusteroidun indeksiavaimen määritelmää. CLR-funktiot eivät voi esiintyä näkymän WHERE-lauseessa tai näkymän JOIN-toiminnon ON-lauseessa.
  • Näkymän määrittelyssä käytetyillä CLR-funktioilla ja -menetelmillä on oltava seuraavan taulukon mukaiset ominaisuudet.

    Omaisuus
    Huomautuksia

    DETERMINISTINEN = TOSI
    On ilmoitettava erikseen Microsoft .NET Framework -menetelmän attribuuttina.

    TARKKA = TOSI
    On ilmoitettava eksplisiittisesti .NET Framework -menetelmän attribuuttina.

    TIETOJEN KÄYTTÖ = EI SQL:ää
    Määritetään asettamalla DataAccess-attribuutiksi DataAccessKind.None ja SystemDataAccess-attribuutiksi SystemDataAccessKind.None.

    ULKOINEN PÄÄSY = EI
    Tämä ominaisuus on oletuksena NO CLR-rutiineille.

  • Näkymä on luotava käyttämällä WITH SCHEMABINDING vaihtoehto.
  • Näkymän tulee viitata vain perustaulukoihin, jotka ovat samassa tietokannassa kuin näkymä. Näkymä ei voi viitata muihin näkymiin.
  • Näkymän määritelmän SELECT-käsky ei saa sisältää seuraavia Transact-SQL-elementtejä:

    COUNT
    ROWSET-toiminnot (OPENDATASOURCE, OPENQUERY, OPENROWSET, AND OPENXML)
    OUTER liittyy (LEFT, RIGHTtai FULL)

    Johdettu taulukko (määritetty määrittämällä a SELECT lausunto FROM lauseke)
    Itseliittyvät
    Sarakkeiden määrittäminen käyttämällä SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPtai AVG
    Yhteinen taulukkolauseke (CTE)

    kellua1, teksti, ntext, kuva, XMLtai tiedostovirta sarakkeet
    Alakysely
    OVER lauseke, joka sisältää ranking- tai aggregate window -funktiot

    Kokotekstipredikaatit (CONTAINS, FREETEXT)
    SUM funktio, joka viittaa nollattavaan lausekkeeseen
    ORDER BY

    CLR käyttäjän määrittämä aggregaattitoiminto
    TOP
    CUBE, ROLLUPtai GROUPING SETS operaattorit

    MIN, MAX
    UNION, EXCEPTtai INTERSECT operaattorit
    TABLESAMPLE

    Taulukon muuttujat
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Harva sarakesarja
    Sisäiset (TVF) tai monilauseiset taulukkoarvoiset funktiot (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Indeksoitu näkymä voi sisältää kellua sarakkeet; tällaisia ​​sarakkeita ei kuitenkaan voida sisällyttää klusteroituun indeksiavaimeen.

  • If GROUP BY on läsnä, VIEW-määritelmän tulee sisältää COUNT_BIG(*) eikä saa sisältää HAVING. Nämä GROUP BY rajoitukset koskevat vain indeksoidun näkymän määritelmää. Kysely voi käyttää indeksoitua näkymää suoritussuunnitelmassaan, vaikka se ei täyttäisikään niitä GROUP BY rajoituksia.
  • Jos näkymän määritelmä sisältää a GROUP BY lauseke, yksilöllisen klusteroidun indeksin avain voi viitata vain sarakkeissa määritettyihin sarakkeisiin GROUP BY lauseke.

Tässä on selvää, että intiaanit eivät olleet mukana, koska he päättivät tehdä sen suunnitelman mukaan "teemme vähän, mutta hyvin". Toisin sanoen heillä on enemmän miinoja kentällä, mutta niiden sijainti on läpinäkyvämpi. Suurin pettymys on tämä rajoitus:

Näkymän tulee viitata vain perustaulukoihin, jotka ovat samassa tietokannassa kuin näkymä. Näkymä ei voi viitata muihin näkymiin.

Terminologiamme mukaan tämä tarkoittaa, että funktio ei voi käyttää toista materialisoitunutta funktiota. Tämä katkaisee kaiken ideologian alkuunsa.
Myös tämä rajoitus (ja edelleen tekstissä) vähentää huomattavasti käyttötapauksia:

Näkymän määritelmän SELECT-käsky ei saa sisältää seuraavia Transact-SQL-elementtejä:

COUNT
ROWSET-toiminnot (OPENDATASOURCE, OPENQUERY, OPENROWSET, AND OPENXML)
OUTER liittyy (LEFT, RIGHTtai FULL)

Johdettu taulukko (määritetty määrittämällä a SELECT lausunto FROM lauseke)
Itseliittyvät
Sarakkeiden määrittäminen käyttämällä SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPtai AVG
Yhteinen taulukkolauseke (CTE)

kellua1, teksti, ntext, kuva, XMLtai tiedostovirta sarakkeet
Alakysely
OVER lauseke, joka sisältää ranking- tai aggregate window -funktiot

Kokotekstipredikaatit (CONTAINS, FREETEXT)
SUM funktio, joka viittaa nollattavaan lausekkeeseen
ORDER BY

CLR käyttäjän määrittämä aggregaattitoiminto
TOP
CUBE, ROLLUPtai GROUPING SETS operaattorit

MIN, MAX
UNION, EXCEPTtai INTERSECT operaattorit
TABLESAMPLE

Taulukon muuttujat
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Harva sarakesarja
Sisäiset (TVF) tai monilauseiset taulukkoarvoiset funktiot (MSTVF)
OFFSET

CHECKSUM_AGG

ULKOISET LIITTYMÄT, UNIONIT, ORDER BY ja muut ovat kiellettyjä. Olisi voinut olla helpompi määritellä, mitä voidaan käyttää, kuin mitä ei voida käyttää. Lista olisi todennäköisesti paljon pienempi.

Yhteenvetona: valtava joukko rajoituksia jokaisessa (huomaa vaikka kaupallinen) DBMS vs. ei mitään (lukuun ottamatta yhtä loogista, ei teknistä) LGPL-tekniikassa. On kuitenkin huomattava, että tämän mekanismin toteuttaminen relaatiologiikassa on jonkin verran vaikeampaa kuin kuvatussa toiminnallisessa logiikassa.

Реализация

Kuinka se toimii? PostgreSQL:ää käytetään "virtuaalikoneena". Sisällä on monimutkainen algoritmi, joka rakentaa kyselyitä. Tässä lähdekoodi. Eikä ole olemassa vain suurta joukkoa heuristiikkaa, jossa on joukko ifs. Joten jos sinulla on pari kuukautta aikaa opiskella, voit yrittää ymmärtää arkkitehtuuria.

Toimiiko se tehokkaasti? Melko tehokasta. Valitettavasti tätä on vaikea todistaa. Voin vain sanoa, että jos ottaa huomioon ne tuhannet kyselyt suurissa sovelluksissa, ne ovat keskimäärin tehokkaampia kuin hyvän kehittäjän kyselyt. Erinomainen SQL-ohjelmoija voi kirjoittaa minkä tahansa kyselyn tehokkaammin, mutta tuhannella kyselyllä hänellä ei yksinkertaisesti ole motivaatiota tai aikaa tehdä sitä. Ainoa asia, jonka voin nyt mainita todisteena tehokkuudesta, on se, että tälle DBMS:lle rakennetulla alustalla työskentelee useita projekteja. ERP-järjestelmät, joissa on tuhansia erilaisia ​​MATERIALIZOITUJA toimintoja, tuhansia käyttäjiä ja teratavuisia tietokantoja, joissa on satoja miljoonia tietueita, jotka toimivat tavallisella kahden prosessorin palvelimella. Kuka tahansa voi kuitenkin tarkistaa/kiistää tehokkuuden lataamalla alusta ja PostgreSQL, kytketty päälle kirjaamalla SQL-kyselyitä ja yrittämällä muuttaa logiikkaa ja tietoja siellä.

Seuraavissa artikkeleissa puhun myös siitä, kuinka voit asettaa rajoituksia toiminnoille, työskennellä muutosistuntojen kanssa ja paljon muuta.

Lähde: will.com

Lisää kommentti