Ang pagbabalanse ay nagsusulat at nagbabasa sa isang database

Ang pagbabalanse ay nagsusulat at nagbabasa sa isang database
Sa nakaraan Artikulo Inilarawan ko ang konsepto at pagpapatupad ng isang database na binuo batay sa mga function, sa halip na mga talahanayan at mga patlang tulad ng sa relational database. Nagbigay ito ng maraming halimbawa na nagpapakita ng mga pakinabang ng diskarteng ito kaysa sa klasikal. Marami ang nakakita sa kanila na hindi sapat na nakakumbinsi.

Sa artikulong ito, ipapakita ko kung paano pinapayagan ka ng konseptong ito na mabilis at maginhawang balansehin ang pagsusulat at pagbabasa sa database nang walang anumang pagbabago sa operating logic. Ang katulad na pag-andar ay sinubukang ipatupad sa mga modernong komersyal na DBMS (sa partikular, Oracle at Microsoft SQL Server). Sa dulo ng artikulo ay ipapakita ko na kung ano ang kanilang ginawa, upang ilagay ito nang mahinahon, ay hindi gumana nang maayos.

ОписаниС

Tulad ng dati, para sa mas mahusay na pag-unawa sisimulan ko ang paglalarawan na may mga halimbawa. Sabihin nating kailangan nating ipatupad ang lohika na magbabalik ng isang listahan ng mga departamento na may bilang ng mga empleyado sa kanila at ang kanilang kabuuang suweldo.

Sa isang functional na database ito ay magiging ganito:

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

Ang pagiging kumplikado ng pagsasagawa ng query na ito sa anumang DBMS ay magiging katumbas ng O(bilang ng mga empleyado)dahil ang pagkalkula na ito ay nangangailangan ng pag-scan sa buong talahanayan ng mga empleyado at pagkatapos ay pagpangkatin sila ayon sa departamento. Magkakaroon din ng ilang maliit (naniniwala kami na mas maraming empleyado kaysa sa mga departamento) na suplemento depende sa napiling plano O(log number ng mga empleyado) o O(bilang ng mga departamento) para sa pagpapangkat at iba pa.

Malinaw na ang execution overhead ay maaaring iba sa iba't ibang DBMS, ngunit ang pagiging kumplikado ay hindi magbabago sa anumang paraan.

Sa iminungkahing pagpapatupad, ang functional DBMS ay bubuo ng isang subquery na kakalkulahin ang mga kinakailangang halaga para sa departamento, at pagkatapos ay gagawa ng JOIN sa talahanayan ng departamento upang makuha ang pangalan. Gayunpaman, para sa bawat function, kapag nagdedeklara, posibleng magtakda ng espesyal na MATERIALIZED na marker. Awtomatikong gagawa ang system ng kaukulang field para sa bawat ganoong function. Kapag binabago ang halaga ng isang function, magbabago din ang halaga ng field sa parehong transaksyon. Kapag ina-access ang function na ito, maa-access ang pre-calculated field.

Sa partikular, kung itinakda mo ang MATERIALIZED para sa mga function bilang ng mga Empleyado ΠΈ salarySum, pagkatapos ay dalawang patlang ang idaragdag sa talahanayan na may listahan ng mga departamento, na mag-iimbak ng bilang ng mga empleyado at ang kanilang kabuuang suweldo. Sa tuwing may pagbabago sa mga empleyado, ang kanilang mga suweldo o mga kaakibat ng departamento, awtomatikong babaguhin ng system ang mga halaga ng mga larangang ito. Direktang maa-access ng query sa itaas ang mga field na ito at isasagawa sa O(bilang ng mga departamento).

Ano ang mga paghihigpit? Isang bagay lamang: ang naturang function ay dapat magkaroon ng isang tiyak na bilang ng mga halaga ng input kung saan ang halaga nito ay tinukoy. Kung hindi, imposibleng bumuo ng isang talahanayan na nag-iimbak ng lahat ng mga halaga nito, dahil hindi maaaring magkaroon ng isang talahanayan na may walang katapusang bilang ng mga hilera.

Halimbawa:

employeesCount β€˜ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΡΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊΠΎΠ² Ρ Π·Π°Ρ€ΠΏΠ»Π°Ρ‚ΠΎΠΉ > N’ (Department d, NUMERIC[10,2] N) = 
    GROUP SUM salary(Employee e) IF department(e) = d AND salary(e) > N;

Ang function na ito ay tinukoy para sa isang walang katapusang bilang ng mga halaga ng N (halimbawa, anumang negatibong halaga ay angkop). Samakatuwid, hindi mo maaaring ilagay ang MATERIALIZED dito. Kaya ito ay isang lohikal na limitasyon, hindi isang teknikal (iyon ay, hindi dahil hindi namin ito maipatupad). Kung hindi, walang mga paghihigpit. Maaari kang gumamit ng mga pagpapangkat, pag-uuri, AT at O, PARTITION, recursion, atbp.

Halimbawa, sa problema 2.2 ng nakaraang artikulo, maaari mong ilagay ang MATERIALIZED sa parehong mga function:

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;

Ang system mismo ay gagawa ng isang table na may mga type key Parokyano, produkto ΠΈ Integer, ay magdaragdag ng dalawang patlang dito at ia-update ang mga halaga ng patlang sa mga ito sa anumang mga pagbabago. Kapag ang mga karagdagang tawag sa mga function na ito ay ginawa, hindi sila kakalkulahin, ngunit ang mga halaga ay babasahin mula sa kaukulang mga patlang.

Gamit ang mekanismong ito, maaari mong, halimbawa, alisin ang mga recursion (CTE) sa mga query. Sa partikular, isaalang-alang ang mga grupo na bumubuo ng isang puno gamit ang relasyon ng anak/magulang (bawat grupo ay may link sa magulang nito):

parent = DATA Group (Group);

Sa isang functional na database, ang recursion logic ay maaaring tukuyin tulad ng sumusunod:

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;

Dahil para sa function ayMagulang ay minarkahan na MATERIALIZED, pagkatapos ay isang talahanayan na may dalawang key (mga grupo) ay gagawin para dito, kung saan ang field ayMagulang ay magiging totoo lamang kung ang unang susi ay anak ng pangalawa. Ang bilang ng mga entry sa talahanayang ito ay magiging katumbas ng bilang ng mga pangkat na na-multiply sa average na lalim ng puno. Kung kailangan mo, halimbawa, upang mabilang ang bilang ng mga inapo ng isang partikular na grupo, maaari mong gamitin ang function na ito:

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

Walang CTE sa SQL query. Sa halip ay magkakaroon ng simpleng GROUP BY.

Gamit ang mekanismong ito, madali mo ring ma-denormalize ang database kung kinakailangan:

CLASS Order 'Π—Π°ΠΊΠ°Π·';
date 'Π”Π°Ρ‚Π°' = DATA DATE (Order);

CLASS OrderDetail 'Π‘Ρ‚Ρ€ΠΎΠΊΠ° Π·Π°ΠΊΠ°Π·Π°';
order 'Π—Π°ΠΊΠ°Π·' = DATA Order (OrderDetail);
date 'Π”Π°Ρ‚Π°' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED;

Kapag tumatawag sa isang function petsa para sa linya ng order, babasahin ang field kung saan mayroong index mula sa talahanayan na may mga linya ng order. Kapag nagbago ang petsa ng order, awtomatikong muling kakalkulahin ng system ang denormalized na petsa sa linya.

Kalamangan

Para saan ang buong mekanismong ito? Sa mga classic na DBMS, nang walang muling pagsusulat ng mga query, ang isang developer o DBA ay maaari lamang magpalit ng mga index, matukoy ang mga istatistika at sabihin sa query planner kung paano isasagawa ang mga ito (at ang mga HINT ay magagamit lamang sa mga komersyal na DBMS). Gaano man nila subukan, hindi nila makukumpleto ang unang query sa artikulo sa O (bilang ng mga departamento) nang hindi binabago ang mga query o pagdaragdag ng mga trigger. Sa iminungkahing pamamaraan, sa yugto ng pagbuo, hindi mo kailangang isipin ang istraktura ng pag-iimbak ng data at kung aling mga pagsasama-sama ang gagamitin. Ang lahat ng ito ay madaling mabago sa mabilisang, nang direkta sa operasyon.

Sa pagsasagawa, ganito ang hitsura. Ang ilang mga tao ay direktang bumuo ng lohika batay sa gawain sa kamay. Hindi nila naiintindihan ang mga algorithm at ang kanilang pagiging kumplikado, o mga plano sa pagpapatupad, o mga uri ng mga pagsali, o anumang iba pang teknikal na bahagi. Ang mga taong ito ay mas maraming analyst ng negosyo kaysa sa mga developer. Pagkatapos, ang lahat ng ito ay napupunta sa pagsubok o operasyon. Pinapagana ang pag-log ng matagal nang mga query. Kapag may nakitang mahabang query, ang ibang tao (mas teknikal - mahalagang DBA) ay magpapasya na paganahin ang MATERIALIZED sa ilang intermediate na function. Ito ay bahagyang nagpapabagal sa pag-record (dahil nangangailangan ito ng pag-update ng karagdagang field sa transaksyon). Gayunpaman, hindi lamang ang query na ito ay makabuluhang pinabilis, kundi pati na rin ang lahat ng iba pa na gumagamit ng function na ito. Kasabay nito, ang pagpapasya kung aling function ang matutupad ay medyo madali. Dalawang pangunahing parameter: ang bilang ng mga posibleng halaga ng pag-input (ito ay kung gaano karaming mga tala ang nasa kaukulang talahanayan), at kung gaano kadalas ito ginagamit sa iba pang mga function.

Mga Analogue

Ang mga modernong komersyal na DBMS ay may mga katulad na mekanismo: MATERIALIZED VIEW na may FAST REFRESH (Oracle) at INDEXED VIEW (Microsoft SQL Server). Sa PostgreSQL, hindi maa-update ang MATERIALIZED VIEW sa isang transaksyon, ngunit kapag hiniling lamang (at kahit na may napakahigpit na mga paghihigpit), kaya hindi namin ito isinasaalang-alang. Ngunit mayroon silang ilang mga problema na makabuluhang nililimitahan ang kanilang paggamit.

Una, mapapagana mo lang ang materialization kung nakagawa ka na ng regular na VIEW. Kung hindi, kakailanganin mong muling isulat ang natitirang mga kahilingan upang ma-access ang bagong likhang view upang magamit ang materyalisasyong ito. O iwanan ang lahat ng ito, ngunit ito ay hindi bababa sa hindi epektibo kung mayroong tiyak na paunang nakalkula na data, ngunit maraming mga query ang hindi palaging gumagamit nito, ngunit muling kalkulahin ito.

Pangalawa, mayroon silang malaking bilang ng mga paghihigpit:

Orakulo

5.3.8.4 Pangkalahatang Paghihigpit sa Mabilis na Pag-refresh

Ang pagtukoy sa query ng materialized na view ay pinaghihigpitan gaya ng sumusunod:

  • Ang materyalized na view ay hindi dapat maglaman ng mga sanggunian sa hindi umuulit na mga expression tulad ng SYSDATE at ROWNUM.
  • Ang materyalized na view ay hindi dapat maglaman ng mga sanggunian sa RAW or LONG RAW uri ng data.
  • Hindi ito maaaring maglaman ng a SELECT listahan ng subquery.
  • Hindi ito maaaring maglaman ng mga analytical function (halimbawa, RANK) nasa SELECT sugnay.
  • Hindi ito maaaring sumangguni sa isang talahanayan kung saan ang isang XMLIndex tinukoy ang index.
  • Hindi ito maaaring maglaman ng a MODEL sugnay.
  • Hindi ito maaaring maglaman ng a HAVING sugnay na may subquery.
  • Hindi ito maaaring maglaman ng mga nested query na mayroon ANY, ALL, O NOT EXISTS.
  • Hindi ito maaaring maglaman ng a [START WITH …] CONNECT BY sugnay.
  • Hindi ito maaaring maglaman ng maramihang mga talahanayan ng detalye sa iba't ibang mga site.
  • ON COMMIT hindi maaaring magkaroon ng mga malayuang talahanayan ng detalye ang mga na-materialize na view.
  • Ang mga nested materialized na view ay dapat na may pagsasama o pinagsama-sama.
  • Materialized join view at materialized aggregate view na may a GROUP BY hindi makakapili ang sugnay mula sa isang index-organized na talahanayan.

5.3.8.5 Mga Paghihigpit sa Mabilis na Pag-refresh sa Mga Materyal na Pananaw na may Mga Pagsali Lamang

Ang pagtukoy sa mga query para sa mga materialized na view na may mga pagsali lamang at walang mga pinagsama-sama ay may mga sumusunod na paghihigpit sa mabilis na pag-refresh:

  • Lahat ng mga paghihigpit mula sa Β«Pangkalahatang Paghihigpit sa Mabilis na Pag-refresh".
  • Hindi sila maaaring magkaroon GROUP BY mga sugnay o pinagsama-samang.
  • Rowids ng lahat ng mga talahanayan sa FROM dapat lumabas ang listahan sa SELECT listahan ng query.
  • Ang mga materialized na view log ay dapat na may mga rowids para sa lahat ng mga base table sa FROM listahan ng query.
  • Hindi ka makakagawa ng mabilis na nare-refresh na materialized na view mula sa maraming table na may mga simpleng pagsasama na may kasamang column ng object type sa SELECT pahayag.

Gayundin, ang paraan ng pag-refresh na iyong pipiliin ay hindi magiging mahusay kung:

  • Ang pagtukoy sa query ay gumagamit ng panlabas na pagsali na kumikilos tulad ng isang panloob na pagsasama. Kung ang pagtukoy ng query ay naglalaman ng ganoong pagsali, isaalang-alang ang muling pagsulat ng pagtukoy ng query upang maglaman ng isang panloob na pagsasama.
  • Ang SELECT listahan ng materyalized na view ay naglalaman ng mga expression sa mga hanay mula sa maramihang mga talahanayan.

5.3.8.6 Mga Paghihigpit sa Mabilis na Pag-refresh sa Materialized Views na may Mga Pinagsama-sama

Ang pagtukoy ng mga query para sa mga materialized na view na may mga pinagsama-sama o pagsali ay may mga sumusunod na paghihigpit sa mabilis na pag-refresh:

Sinusuportahan ang mabilis na pag-refresh para sa pareho ON COMMIT at ON DEMAND naganap na mga pananaw, gayunpaman ang mga sumusunod na paghihigpit ay nalalapat:

  • Ang lahat ng mga talahanayan sa materialized view ay dapat na may materialized view logs, at ang materialized view logs ay dapat na:
    • Maglaman ng lahat ng mga column mula sa talahanayang isinangguni sa materialized na view.
    • Tukuyin gamit ang ROWID at INCLUDING NEW VALUES.
    • tukuyin ang SEQUENCE sugnay kung ang talahanayan ay inaasahang magkaroon ng halo ng mga pagsingit/direktang pagkarga, pagtanggal, at pag-update.

  • Lamang SUM, COUNT, AVG, STDDEV, VARIANCE, MIN at MAX ay suportado para sa mabilis na pag-refresh.
  • COUNT(*) dapat tukuyin.
  • Ang mga pinagsama-samang function ay dapat mangyari lamang bilang ang pinakalabas na bahagi ng expression. Ibig sabihin, mga pinagsama-samang tulad ng AVG(AVG(x)) or AVG(x)+ AVG(x) bawal.
  • Para sa bawat pinagsama-samang tulad ng AVG(expr), ang kaukulang COUNT(expr) dapat naroroon. Inirerekomenda iyon ng Oracle SUM(expr) matukoy.
  • If VARIANCE(expr) or STDDEV(expr) ay tinukoy, COUNT(expr) at SUM(expr) dapat tukuyin. Inirerekomenda iyon ng Oracle SUM(expr *expr) matukoy.
  • Ang SELECT column sa pagtukoy ng query ay hindi maaaring isang kumplikadong expression na may mga column mula sa maraming base table. Ang isang posibleng solusyon dito ay ang paggamit ng nested materialized view.
  • Ang SELECT ang listahan ay dapat maglaman ng lahat GROUP BY mga haligi.
  • Ang materyalized na view ay hindi batay sa isa o higit pang mga malayuang talahanayan.
  • Kung gumagamit ka ng a CHAR uri ng data sa mga column ng filter ng isang materialized view log, ang mga character set ng master site at ang materialized na view ay dapat na pareho.
  • Kung ang materyalized na view ay may isa sa mga sumusunod, ang mabilis na pag-refresh ay sinusuportahan lamang sa mga nakasanayang pagsingit ng DML at direktang pag-load.
    • Materialized view na may MIN or MAX pinagsama-sama
    • Materialized view na mayroon SUM(expr) pero hindi COUNT(expr)
    • Materialized view nang wala COUNT(*)

    Ang ganitong materialized view ay tinatawag na insert-only materialized view.

  • Isang materialized view na may MAX or MIN ay mabilis na nare-refresh pagkatapos tanggalin o pinaghalo ang mga pahayag ng DML kung wala itong a WHERE sugnay.
    Ang max/min na mabilis na pag-refresh pagkatapos tanggalin o pinaghalong DML ay walang katulad na gawi sa insert-only na case. Tinatanggal at muling kinukuwenta nito ang mga halaga ng max/min para sa mga apektadong grupo. Kailangan mong magkaroon ng kamalayan sa epekto nito sa pagganap.
  • Materialized view na may pinangalanang view o subquery sa FROM Maaaring mabilis na mai-refresh ang sugnay kung ang mga view ay maaaring ganap na pagsamahin. Para sa impormasyon kung aling mga view ang magsasama, tingnan Oracle Database SQL Language Reference.
  • Kung walang mga panlabas na pagsasama, maaari kang magkaroon ng mga arbitraryong pagpili at pagsali sa WHERE sugnay.
  • Ang mga materialized na pinagsama-samang view na may mga panlabas na pagsasama ay mabilis na nare-refresh pagkatapos ng maginoo na DML at mga direktang pag-load, sa kondisyon na ang panlabas na talahanayan lamang ang nabago. Gayundin, ang mga natatanging hadlang ay dapat na umiiral sa mga column ng pagsali sa inner join table. Kung may mga panlabas na pagsasama, ang lahat ng mga pagsali ay dapat na konektado sa pamamagitan ng ANDs at dapat gamitin ang pagkakapantay-pantay (=) operator.
  • Para sa materialized view na may CUBE, ROLLUP, mga pangkat na hanay, o pagsasama-sama ng mga ito, nalalapat ang mga sumusunod na paghihigpit:
    • Ang SELECT Ang listahan ay dapat maglaman ng pagpapangkat ng distinguisher na maaaring maging a GROUPING_ID function sa lahat GROUP BY mga ekspresyon o GROUPING gumagana ang isa para sa bawat isa GROUP BY pagpapahayag. Halimbawa, kung ang GROUP BY sugnay ng materialized view ay "GROUP BY CUBE(a, b)", pagkatapos ay ang SELECT ang listahan ay dapat maglaman ng alinman sa "GROUPING_ID(a, b)Β»o Β«GROUPING(a) AND GROUPING(b)Β» para mabilis na mai-refresh ang materialized view.
    • GROUP BY hindi dapat magresulta sa anumang mga duplicate na pagpapangkat. Halimbawa, "GROUP BY a, ROLLUP(a, b)" ay hindi mabilis na nare-refresh dahil nagreresulta ito sa mga duplicate na pagpapangkat "(a), (a, b), AND (a)".

5.3.8.7 Mga Paghihigpit sa Mabilis na Pag-refresh sa Materialized Views kasama ang UNION ALL

Materialized view sa UNION ALL itakda ang suporta ng operator sa REFRESH FAST opsyon kung ang mga sumusunod na kondisyon ay natutugunan:

  • Ang pagtukoy sa query ay dapat na mayroong UNION ALL operator sa pinakamataas na antas.

    Ang UNION ALL hindi maaaring i-embed ang operator sa loob ng isang subquery, na may isang pagbubukod: Ang UNION ALL ay maaaring nasa isang subquery sa FROM sugnay kung ang pagtukoy ng query ay nasa anyo SELECT * FROM (tingnan o i-subquery gamit ang UNION ALL) tulad ng sa sumusunod na halimbawa:

    GUMAWA NG VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker MULA sa mga customer c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM customer c WHERE c.cust_last_name 'Jones'); GUMAWA NG MATERIALIZED VIEW unionall_inside_view_mv REFRESH FAST ON DEMAND BILANG PUMILI * MULA sa view_with_unionall;
    

    Tandaan na ang view view_with_unionall natutugunan ang mga kinakailangan para sa mabilis na pag-refresh.

  • Ang bawat bloke ng query sa UNION ALL dapat matugunan ng query ang mga kinakailangan ng isang mabilis na refreshable materialized view na may mga pinagsama-sama o isang mabilis na refreshable materialized view na may mga pagsasama.

    Ang naaangkop na materialized view logs ay dapat gawin sa mga talahanayan ayon sa kinakailangan para sa kaukulang uri ng mabilis na refreshable materialized view.
    Tandaan na ang Oracle Database ay nagpapahintulot din sa espesyal na kaso ng isang solong table na materialized na view na may mga pagsasama lamang na ibinigay ang ROWID kolum ay kasama sa SELECT listahan at sa materialized view log. Ito ay ipinapakita sa pagtukoy ng query ng view view_with_unionall.

  • Ang SELECT listahan ng bawat query ay dapat may kasamang a UNION ALL marker, at ang UNION ALL Ang column ay dapat na may natatanging pare-parehong numeric o string value sa bawat isa UNION ALL sangay. Dagdag pa, ang haligi ng marker ay dapat lumitaw sa parehong ordinal na posisyon sa SELECT listahan ng bawat bloke ng query. Tingnan mo"UNION ALL Marker at Query RewriteΒ» para sa karagdagang impormasyon tungkol sa UNION ALL mga marker
  • Ang ilang mga tampok tulad ng mga panlabas na pagsasama, insert-only na pinagsama-samang materyalized na mga query sa view at mga malayuang talahanayan ay hindi suportado para sa mga materyal na view na may UNION ALL. Tandaan, gayunpaman, na ang mga materyal na view na ginamit sa pagtitiklop, na hindi naglalaman ng mga pagsasama o pinagsama-sama, ay maaaring mabilis na mai-refresh kapag UNION ALL o mga remote table ang ginagamit.
  • Dapat itakda sa 9.2.0 o mas mataas ang compatibility initialization parameter para makagawa ng mabilis na refreshable materialized view na may UNION ALL.

Ayokong masaktan ang mga tagahanga ng Oracle, ngunit sa paghusga sa kanilang listahan ng mga paghihigpit, tila ang mekanismong ito ay isinulat hindi sa pangkalahatang kaso, gamit ang ilang uri ng modelo, ngunit ng libu-libong Indian, kung saan ang lahat ay nabigyan ng pagkakataon na sumulat ng kanilang sariling sangay, at ginawa ng bawat isa sa kanila ang kanyang makakaya. Ang paggamit ng mekanismong ito para sa tunay na lohika ay parang paglalakad sa isang minahan. Maaari kang makakuha ng minahan anumang oras sa pamamagitan ng pagpindot sa isa sa mga hindi halatang paghihigpit. Paano ito gumagana ay isa ring hiwalay na tanong, ngunit ito ay lampas sa saklaw ng artikulong ito.

Microsoft SQL Server

Karagdagang Mga Kinakailangan

Bilang karagdagan sa mga opsyon sa SET at mga kinakailangan sa pagpapaandar ng tiyak, ang mga sumusunod na kinakailangan ay dapat matugunan:

  • Ang gumagamit na nagpapatupad CREATE INDEX dapat ang may-ari ng view.
  • Kapag nilikha mo ang index, ang IGNORE_DUP_KEY dapat itakda ang opsyon sa OFF (ang default na setting).
  • Ang mga talahanayan ay dapat na sanggunian ng dalawang bahagi na mga pangalan, pamamaraan.tablename sa kahulugan ng view.
  • Ang mga function na tinukoy ng user na isinangguni sa view ay dapat gawin sa pamamagitan ng paggamit ng WITH SCHEMABINDING pagpipilian.
  • Ang anumang mga function na tinukoy ng gumagamit na isinangguni sa view ay dapat na i-reference ng dalawang bahagi na mga pangalan, ..
  • Ang data access property ng isang function na tinukoy ng user ay dapat NO SQL, at dapat na ang external na access property NO.
  • Maaaring lumabas ang mga karaniwang function ng runtime ng wika (CLR) sa piling listahan ng view, ngunit hindi maaaring maging bahagi ng kahulugan ng clustered index key. Ang mga function ng CLR ay hindi maaaring lumabas sa sugnay na WHERE ng view o sa sugnay na ON ng isang JOIN na operasyon sa view.
  • Ang mga function at pamamaraan ng CLR ng mga uri na tinukoy ng gumagamit ng CLR na ginamit sa kahulugan ng view ay dapat may mga katangian na nakatakda tulad ng ipinapakita sa sumusunod na talahanayan.

    Ari-arian
    nota

    DETERMINISTIC = TOTOO
    Dapat na tahasang ideklara bilang isang katangian ng paraan ng Microsoft .NET Framework.

    TOTOO = TOTOO
    Dapat na tahasang ideklara bilang katangian ng .NET Framework na paraan.

    DATA ACCESS = WALANG SQL
    Tinutukoy sa pamamagitan ng pagtatakda ng DataAccess attribute sa DataAccessKind.None at SystemDataAccess attribute sa SystemDataAccessKind.None.

    EXTERNAL ACCESS = HINDI
    Nagde-default ang property na ito sa NO para sa mga CLR routine.

  • Ang view ay dapat malikha sa pamamagitan ng paggamit ng WITH SCHEMABINDING pagpipilian.
  • Ang view ay dapat na sumangguni lamang sa mga base table na nasa parehong database ng view. Ang view ay hindi maaaring sumangguni sa iba pang mga view.
  • Ang SELECT statement sa kahulugan ng view ay hindi dapat maglaman ng mga sumusunod na elemento ng Transact-SQL:

    COUNT
    Mga function ng ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, AT OPENXML)
    OUTER sumali(LEFT, RIGHT, O FULL)

    Hinango na talahanayan (tinukoy sa pamamagitan ng pagtukoy ng a SELECT pahayag sa FROM sugnay)
    Sumasali sa sarili
    Pagtukoy sa mga column sa pamamagitan ng paggamit SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARP, O AVG
    Common table expression (CTE)

    lumutang1, teksto, ntext, larawan, XML, O filestream haligi
    Subquery
    OVER sugnay, na kinabibilangan ng pagraranggo o pinagsama-samang mga function ng window

    Mga predicate ng buong teksto (CONTAINS, FREETEXT)
    SUM function na tumutukoy sa isang nullable na expression
    ORDER BY

    CLR user-defined aggregate function
    TOP
    CUBE, ROLLUP, O GROUPING SETS operator

    MIN, MAX
    UNION, EXCEPT, O INTERSECT operator
    TABLESAMPLE

    Mga variable ng talahanayan
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Kalat-kalat na hanay ng hanay
    Inline (TVF) o multi-statement table-valued function (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Maaaring maglaman ang naka-index na view lumutang mga hanay; gayunpaman, ang mga naturang column ay hindi maaaring isama sa clustered index key.

  • If GROUP BY ay naroroon, ang kahulugan ng VIEW ay dapat na naglalaman COUNT_BIG(*) at hindi dapat maglaman HAVING. Mga ito GROUP BY ang mga paghihigpit ay nalalapat lamang sa naka-index na kahulugan ng view. Maaaring gumamit ang isang query ng naka-index na view sa plano ng pagpapatupad nito kahit na hindi nito natutugunan ang mga ito GROUP BY mga paghihigpit.
  • Kung ang kahulugan ng view ay naglalaman ng a GROUP BY clause, ang susi ng natatanging clustered index ay maaari lamang sumangguni sa mga column na tinukoy sa GROUP BY sugnay.

Maliwanag dito na hindi kasali ang mga Indian, dahil nagpasya silang gawin ito ayon sa iskema na "kaunti lang ang gagawin natin, ngunit mabuti." Ibig sabihin, mas marami silang minahan sa field, pero mas transparent ang kanilang lokasyon. Ang pinaka nakakadismaya ay ang limitasyong ito:

Ang view ay dapat na sumangguni lamang sa mga base table na nasa parehong database ng view. Ang view ay hindi maaaring sumangguni sa iba pang mga view.

Sa aming terminolohiya, nangangahulugan ito na hindi ma-access ng isang function ang isa pang materialized na function. Pinutol nito ang lahat ng ideolohiya sa simula.
Gayundin, ang limitasyong ito (at higit pa sa teksto) ay lubos na binabawasan ang mga kaso ng paggamit:

Ang SELECT statement sa kahulugan ng view ay hindi dapat maglaman ng mga sumusunod na elemento ng Transact-SQL:

COUNT
Mga function ng ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, AT OPENXML)
OUTER sumali(LEFT, RIGHT, O FULL)

Hinango na talahanayan (tinukoy sa pamamagitan ng pagtukoy ng a SELECT pahayag sa FROM sugnay)
Sumasali sa sarili
Pagtukoy sa mga column sa pamamagitan ng paggamit SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARP, O AVG
Common table expression (CTE)

lumutang1, teksto, ntext, larawan, XML, O filestream haligi
Subquery
OVER sugnay, na kinabibilangan ng pagraranggo o pinagsama-samang mga function ng window

Mga predicate ng buong teksto (CONTAINS, FREETEXT)
SUM function na tumutukoy sa isang nullable na expression
ORDER BY

CLR user-defined aggregate function
TOP
CUBE, ROLLUP, O GROUPING SETS operator

MIN, MAX
UNION, EXCEPT, O INTERSECT operator
TABLESAMPLE

Mga variable ng talahanayan
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Kalat-kalat na hanay ng hanay
Inline (TVF) o multi-statement table-valued function (MSTVF)
OFFSET

CHECKSUM_AGG

Ang OUTER JOINS, UNION, ORDER BY at iba pa ay ipinagbabawal. Maaaring mas madaling tukuyin kung ano ang maaaring gamitin kaysa kung ano ang hindi magagamit. Ang listahan ay malamang na mas maliit.

Upang ibuod: isang malaking hanay ng mga paghihigpit sa bawat (tandaan natin ang komersyal) DBMS kumpara sa wala (maliban sa isang lohikal, hindi teknikal) sa teknolohiya ng LGPL. Gayunpaman, dapat tandaan na ang pagpapatupad ng mekanismong ito sa relational logic ay medyo mas mahirap kaysa sa inilarawan na functional logic.

Pagpapatupad

Paano ito gumagana? Ang PostgreSQL ay ginagamit bilang isang "virtual machine". Mayroong isang kumplikadong algorithm sa loob na bumubuo ng mga query. Dito pinagmulan. At hindi lamang isang malaking hanay ng heuristics na may isang grupo ng mga ifs. Kaya, kung mayroon kang ilang buwan upang mag-aral, maaari mong subukang maunawaan ang arkitektura.

Mabisa ba ito? Medyo epektibo. Sa kasamaang palad, ito ay mahirap patunayan. Masasabi ko lang na kung isasaalang-alang mo ang libu-libong query na umiiral sa malalaking application, sa karaniwan ay mas mahusay ang mga ito kaysa sa isang mahusay na developer. Ang isang mahusay na programmer ng SQL ay maaaring magsulat ng anumang query nang mas mahusay, ngunit sa isang libong mga query ay hindi siya magkakaroon ng pagganyak o oras upang gawin ito. Ang tanging bagay na maaari kong banggitin ngayon bilang patunay ng pagiging epektibo ay ang ilang mga proyekto ay gumagana sa platform na binuo sa DBMS na ito Mga sistema ng ERP, na mayroong libu-libong iba't ibang MATERIALIZED function, na may libu-libong user at terabyte database na may daan-daang milyong record na tumatakbo sa isang regular na two-processor server. Gayunpaman, kahit sino ay maaaring suriin / pabulaanan ang pagiging epektibo sa pamamagitan ng pag-download platform at PostgreSQL, binuksan pag-log ng mga query sa SQL at sinusubukang baguhin ang logic at data doon.

Sa mga sumusunod na artikulo, pag-uusapan ko rin kung paano ka makakapagtakda ng mga paghihigpit sa mga pag-andar, magtrabaho kasama ang mga sesyon ng pagbabago, at marami pa.

Pinagmulan: www.habr.com

Magdagdag ng komento