Дерекқордағы жазу мен оқуды теңестіру

Дерекқордағы жазу мен оқуды теңестіру
Алдыңғысында мақала Мен реляциялық дерекқорлардағыдай кестелер мен өрістерден гөрі функциялар негізінде құрылған деректер қорының тұжырымдамасы мен жүзеге асырылуын сипаттадым. Онда бұл тәсілдің классикалық әдіске қарағанда артықшылығын көрсететін көптеген мысалдар келтірілген. Көпшілігі оларды жеткілікті сенімді емес деп тапты.

Бұл мақалада мен бұл тұжырымдаманың жұмыс логикасын өзгертпестен дерекқорға жазу мен оқуды тез және ыңғайлы теңестіруге қалай мүмкіндік беретінін көрсетемін. Осыған ұқсас функционалдық қазіргі коммерциялық ДҚБЖ (атап айтқанда, Oracle және Microsoft SQL Server) енгізуге әрекеттенді. Мақаланың соңында мен олардың істегендері, жұмсартып айтқанда, жақсы нәтиже бермегенін көрсетемін.

сипаттамасы

Бұрынғыдай, жақсы түсіну үшін сипаттаманы мысалдармен бастаймын. Бөлімшелердің тізімін олардағы қызметкерлер саны мен олардың жалпы жалақысын қайтаратын логиканы енгізу керек делік.

Функционалды дерекқорда ол келесідей болады:

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

Кез келген ДҚБЖ-да осы сұрауды орындаудың күрделілігі оған тең болады O(қызметкерлер саны)өйткені бұл есептеу қызметкерлердің бүкіл кестесін сканерлеуді, содан кейін оларды бөлім бойынша топтастыруды талап етеді. Сондай-ақ таңдалған жоспарға байланысты кейбір шағын (бөлімшелерге қарағанда қызметкерлер көп деп есептейміз) қосымша болады. O (қызметкерлердің журналы) немесе O(бөлімшелер саны) топтастыру үшін және т.б.

Әртүрлі ДҚБЖ-да орындаудың үстеме шығындары әртүрлі болуы мүмкін екені анық, бірақ күрделілік ешбір жолмен өзгермейді.

Ұсынылған іске асыруда функционалды МҚБЖ бөлім үшін қажетті мәндерді есептейтін бір ішкі сұрауды жасайды, содан кейін атауды алу үшін бөлім кестесімен JOIN жасайды. Дегенмен, әрбір функция үшін декларациялау кезінде арнайы МАТЕРИАЛДАНДЫРЫЛҒАН маркерді орнатуға болады. Жүйе әрбір осындай функция үшін автоматты түрде сәйкес өрісті жасайды. Функцияның мәнін өзгерткен кезде өрістің мәні де сол транзакцияда өзгереді. Бұл функцияға қол жеткізген кезде алдын ала есептелген өріске қол жеткізіледі.

Атап айтқанда, егер сіз функциялар үшін MATERİALIZED орнатсаңыз қызметкерлер саны и жалақы сомасы, содан кейін қызметкерлердің санын және олардың жалпы жалақысын сақтайтын бөлімдер тізімі бар кестеге екі өріс қосылады. Қызметкерлерде, олардың жалақыларында немесе бөлімшелерге қатысты өзгерістер болған кезде, жүйе осы өрістердің мәндерін автоматты түрде өзгертеді. Жоғарыдағы сұрау осы өрістерге тікелей қатынасады және орындалады O(бөлімшелер саны).

Қандай шектеулер бар? Бір ғана нәрсе: мұндай функцияда оның мәні анықталған кіріс мәндерінің шектеулі саны болуы керек. Әйтпесе, оның барлық мәндерін сақтайтын кестені құру мүмкін емес, өйткені шексіз жолдар саны бар кесте болуы мүмкін емес.

Мысал:

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

Бұл функция N мәндерінің шексіз саны үшін анықталған (мысалы, кез келген теріс мән қолайлы). Сондықтан оған МАТЕРИАЛДАЙДЫ қоюға болмайды. Демек, бұл техникалық емес, логикалық шектеу (яғни біз оны жүзеге асыра алмағандықтан емес). Әйтпесе, ешқандай шектеулер жоқ. Топтау, сұрыптау, ЖӘНЕ және НЕМЕСЕ, PARTITION, рекурсия және т.б.

Мысалы, алдыңғы мақаланың 2.2-есепте екі функцияға да MATERIALIZED қоюға болады:

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;

Жүйе өзі типтік пернелері бар бір кестені жасайды сатып алушы, өнім и БҮТІН, оған екі өріс қосады және олардағы өріс мәндерін кез келген өзгерістермен жаңартады. Бұл функцияларға қосымша қоңыраулар жасалғанда, олар есептелмейді, керісінше мәндер сәйкес өрістерден оқылады.

Бұл механизмді пайдалана отырып, мысалы, сұраулардағы рекурсиялардан (CTE) құтылуға болады. Атап айтқанда, бала/ата-ана қатынасын пайдаланып ағаш құрайтын топтарды қарастырыңыз (әр топтың ата-анасына сілтемесі бар):

parent = DATA Group (Group);

Функционалды дерекқорда рекурсия логикасын келесідей көрсетуге болады:

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;

Өйткені функция үшін Ата-ана МАТЕРИАЛДАНДЫРЫЛДЫ деп белгіленеді, содан кейін оған екі кілті (топтары) бар кесте жасалады, онда өріс Ата-ана егер бірінші кілт екіншісінің еншісінде болса ғана ақиқат болады. Бұл кестедегі жазбалар саны ағаштың орташа тереңдігіне көбейтілген топтар санына тең болады. Егер сізге, мысалы, белгілі бір топтың ұрпақтарының санын санау қажет болса, мына функцияны пайдалануға болады:

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

SQL сұрауында CTE болмайды. Оның орнына қарапайым GROUP BY болады.

Бұл механизмді пайдалана отырып, қажет болған жағдайда дерекқорды оңай қалыпсыздандыруға болады:

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

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

Функцияны шақыру кезінде дата тапсырыс жолы үшін индексі бар өріс тапсырыс жолдары бар кестеден оқылады. Тапсырыс күні өзгерген кезде жүйенің өзі жолдағы нормадан шығарылған күнді автоматты түрде қайта есептейді.

артықшылықтары

Бұл механизм не үшін қажет? Классикалық ДҚБЖ-да сұрауларды қайта жазусыз әзірлеуші ​​​​немесе DBA тек индекстерді өзгерте алады, статистиканы анықтай алады және сұрауды жоспарлаушыға оларды орындау жолын айта алады (және КЕҢЕС тек коммерциялық ДҚБЖ-да қол жетімді). Олар қанша тырысса да, мақаладағы бірінші сұрауды орындай алмайды O (бөлімшелер саны) сұрауларды өзгертпей немесе триггерлерді қоспай. Ұсынылған схемада әзірлеу кезеңінде деректерді сақтау құрылымы және қандай агрегаттарды пайдалану керектігі туралы ойланудың қажеті жоқ. Мұның барлығын тікелей жұмыс кезінде оңай өзгертуге болады.

Іс жүзінде бұл былай көрінеді. Кейбір адамдар логиканы тікелей тапсырма негізінде дамытады. Олар алгоритмдерді және олардың күрделілігін, орындау жоспарларын, біріктіру түрлерін, басқа да техникалық құрамдастарды түсінбейді. Бұл адамдар әзірлеушілерге қарағанда бизнес-аналитиктер. Содан кейін мұның бәрі тестілеуге немесе операцияға өтеді. Ұзақ орындалатын сұрауларды тіркеуді қосады. Ұзақ сұрау анықталған кезде, басқа адамдар (көбірек техникалық - негізінен DBA) кейбір аралық функцияда MATERIALIZED қосуды шешеді. Бұл жазуды сәл баяулатады (өйткені ол транзакциядағы қосымша өрісті жаңартуды қажет етеді). Дегенмен, бұл сұрауды ғана емес, сонымен қатар осы функцияны пайдаланатын барлық басқаларды да айтарлықтай жылдамдатады. Сонымен қатар, қандай функцияны жүзеге асыруды шешу салыстырмалы түрде оңай. Екі негізгі параметр: ықтимал кіріс мәндерінің саны (бұл сәйкес кестеде қанша жазба болады) және оның басқа функцияларда қаншалықты жиі қолданылатыны.

Аналог

Заманауи коммерциялық ДҚБЖ ұқсас механизмдерге ие: ЖЫЛДАМ ЖАҢАРТУ (Oracle) бар МАТЕРИАЛДАНҒАН КӨРІНІС және ИНДЕКСтелген КӨРІНІС (Microsoft SQL Server). PostgreSQL-де МАТЕРИАЛДАНҒАН КӨРІНІС транзакцияда жаңартылмайды, тек сұраныс бойынша (тіпті өте қатаң шектеулермен), сондықтан біз оны қарастырмаймыз. Бірақ олардың қолданылуын айтарлықтай шектейтін бірнеше проблемалар бар.

Біріншіден, егер сіз кәдімгі VIEW жасаған болсаңыз ғана материалдандыруды қоса аласыз. Әйтпесе, осы материалдандыруды пайдалану үшін жаңадан жасалған көрініске қол жеткізу үшін қалған сұрауларды қайта жазуға тура келеді. Немесе бәрін сол күйінде қалдырыңыз, бірақ алдын ала есептелген белгілі бір деректер болса, ол кем дегенде тиімсіз болады, бірақ көптеген сұраулар оны әрдайым пайдаланбайды, бірақ оны қайта есептейді.

Екіншіден, оларда көптеген шектеулер бар:

Oracle

5.3.8.4 Жылдам жаңартуға жалпы шектеулер

Материалдандырылған көріністің анықтаушы сұрауы келесідей шектелген:

  • Материалдандырылған көріністе қайталанбайтын өрнектерге сілтемелер болмауы керек SYSDATE және ROWNUM.
  • Материалдандырылған көріністе сілтемелер болмауы керек RAW or LONG RAW деректер түрлері.
  • Оның құрамында а болуы мүмкін емес SELECT тізім ішкі сұрауы.
  • Ол аналитикалық функцияларды қамти алмайды (мысалы, RANK) ішінде SELECT тармақ.
  • Ол кестеге сілтеме жасай алмайды XMLIndex индексі анықталады.
  • Оның құрамында а болуы мүмкін емес MODEL тармақ.
  • Оның құрамында а болуы мүмкін емес HAVING бағыныңқы сұрауы бар сөйлем.
  • Ол кірістірілген сұрауларды қамтуы мүмкін емес ANY, ALLнемесе NOT EXISTS.
  • Оның құрамында а болуы мүмкін емес [START WITH …] CONNECT BY тармақ.
  • Ол әртүрлі тораптардағы бірнеше егжей-тегжейлі кестелерді қамтуы мүмкін емес.
  • ON COMMIT материалдандырылған көріністерде қашықтағы мәліметтер кестелері болуы мүмкін емес.
  • Кірістірілген материалдандырылған көріністерде біріктіру немесе біріктіру болуы керек.
  • Материалдандырылған біріктірілген көріністер және а көмегімен материалдандырылған жиынтық көріністер GROUP BY тармақ индекспен ұйымдастырылған кестеден таңдай алмайды.

5.3.8.5 Тек біріктірілген материалдандырылған көріністердегі жылдам жаңартуға шектеулер

Материалдандырылған көріністерге арналған сұрауларды тек біріктірулермен анықтау және ешқандай жиынтықта жылдам жаңартуға келесі шектеулер жоқ:

  • Барлық шектеулер «Жылдам жаңартуға жалпы шектеулер«.
  • Оларда болуы мүмкін емес GROUP BY сөйлемдер немесе жиынтықтар.
  • ішіндегі барлық кестелердің қатарлары FROM тізімде пайда болуы керек SELECT сұрау тізімі.
  • Материалдандырылған көрініс журналдары барлық негізгі кестелер үшін жолдармен болуы керек FROM сұрау тізімі.
  • Нысан түрінің бағанын қамтитын қарапайым біріктірулері бар бірнеше кестелерден жылдам жаңартылатын материалдандырылған көріністі жасай алмайсыз. SELECT өтініш.

Сондай-ақ, сіз таңдаған жаңарту әдісі оңтайлы тиімді болмайды, егер:

  • Анықтаушы сұрау ішкі біріктіру сияқты әрекет ететін сыртқы біріктіруді пайдаланады. Егер анықтаушы сұрауда осындай біріктіру болса, ішкі біріктіруді қамту үшін анықтаушы сұрауды қайта жазуды қарастырыңыз.
  • The SELECT материалдандырылған көрініс тізімі бірнеше кестелердің бағандарындағы өрнектерді қамтиды.

5.3.8.6 Жиынтықтары бар материалдандырылған көріністердегі жылдам жаңартуға шектеулер

Жиынтықтары немесе біріктірулері бар материалдандырылған көріністерге арналған сұрауларды анықтау жылдам жаңартуда келесі шектеулерге ие:

Жылдам жаңартуға екеуіне де қолдау көрсетіледі ON COMMIT және ON DEMAND материалданған көзқарастар, дегенмен келесі шектеулер қолданылады:

  • Материалдандырылған көріністегі барлық кестелерде материалдандырылған қарау журналдары болуы керек, ал материалдандырылған көрініс журналдарында:
    • Материалдандырылған көріністе сілтеме жасалған кестедегі барлық бағандарды қамтиды.
    • арқылы көрсетіңіз ROWID және INCLUDING NEW VALUES.
    • Белгілеңіз SEQUENCE егер кестеде кірістірулер/тікелей жүктеулер, жоюлар және жаңартулар қоспасы болуы күтілсе.

  • тек SUM, COUNT, AVG, STDDEV, VARIANCE, MIN және MAX жылдам жаңартуға қолдау көрсетіледі.
  • COUNT(*) көрсетілуі керек.
  • Жиынтық функциялар өрнектің ең сыртқы бөлігі ретінде ғана орын алуы керек. сияқты агрегаттар, яғни AVG(AVG(x)) or AVG(x)+ AVG(x) рұқсат етілмейді.
  • сияқты әрбір агрегат үшін AVG(expr), сәйкес COUNT(expr) қатысуы керек. Oracle мұны ұсынады SUM(expr) белгіленеді.
  • If VARIANCE(expr) or STDDEV(expr) көрсетілген, COUNT(expr) және SUM(expr) көрсетілуі керек. Oracle мұны ұсынады SUM(expr *expr) белгіленеді.
  • The SELECT анықтаушы сұраудағы баған бірнеше негізгі кестелердің бағандары бар күрделі өрнек бола алмайды. Бұған мүмкін болатын уақытша шешім кірістірілген материалдандырылған көріністі пайдалану болып табылады.
  • The SELECT тізім барлығын қамтуы керек GROUP BY бағандар.
  • Материалдандырылған көрініс бір немесе бірнеше қашықтағы кестелерге негізделмеген.
  • Егер сіз a қолдансаңыз CHAR материалдандырылған көрініс журналының сүзгі бағандарындағы деректер түрі, негізгі тораптың таңбалар жиыны және материалдандырылған көрініс бірдей болуы керек.
  • Егер материалдандырылған көріністе төмендегілердің біреуі болса, жылдам жаңартуға тек әдеттегі DML кірістірулерінде және тікелей жүктемелерде қолдау көрсетіледі.
    • көмегімен материалдандырылған көріністер MIN or MAX агрегаттар
    • Материалданған көзқарастар бар SUM(expr) бірақ жоқ COUNT(expr)
    • Онсыз материалдандырылған көріністер COUNT(*)

    Мұндай материалдандырылған көрініс тек кірістірілген материалдандырылған көрініс деп аталады.

  • көмегімен материалдандырылған көрініс MAX or MIN жою немесе аралас DML мәлімдемелерінен кейін жылдам жаңартылады, егер ол болмаса WHERE тармақ.
    Жою немесе аралас DML кейінгі максимум/мин жылдам жаңарту тек кірістіруге арналған жағдай сияқты әрекетке ие емес. Ол зардап шеккен топтар үшін максимум/мин мәндерді жояды және қайта есептейді. Сіз оның өнімділігіне әсерін білуіңіз керек.
  • Атаулы көріністері немесе ішкі сұраулары бар материалдандырылған көріністер FROM көріністер толығымен біріктірілуі мүмкін болса, сөйлемді тез жаңартуға болады. Қай көріністер біріктірілетіні туралы ақпаратты қараңыз Oracle Database SQL тіл анықтамасы.
  • Егер сыртқы біріктірулер болмаса, сізде ерікті таңдаулар мен қосылыстар болуы мүмкін WHERE тармақ.
  • Сыртқы біріктірулері бар материалдандырылған жиынтық көріністер тек сыртқы кесте өзгертілген жағдайда, әдеттегі DML және тікелей жүктемелерден кейін жылдам жаңартылады. Сондай-ақ, ішкі біріктіру кестесінің біріктіру бағандарында бірегей шектеулер болуы керек. Егер сыртқы қосылыстар болса, барлық қосылыстар арқылы қосылу керек ANDs және теңдігін пайдалану керек (=) оператор.
  • Материалдандырылған көріністер үшін CUBE, ROLLUP, топтау жиындары немесе оларды біріктіру үшін келесі шектеулер қолданылады:
    • The SELECT тізімде а болуы мүмкін топтауды ажыратушы болуы керек GROUPING_ID барлығында функция GROUP BY өрнектер немесе GROUPING әрқайсысы үшін бір функцияны орындайды GROUP BY өрнек. Мысалы, егер GROUP BY материалданған көзқарастың тармағы «GROUP BY CUBE(a, b)", содан кейін SELECT тізімде біреуі болуы керекGROUPING_ID(a, b)» немесе «GROUPING(a) AND GROUPING(b)» материалдандырылған көрініс жылдам жаңартылатын болуы үшін.
    • GROUP BY қайталанатын топтарға әкелмеуі керек. Мысалы, »GROUP BY a, ROLLUP(a, b)"тез жаңартылмайды, себебі ол қайталанатын топтарға әкеледі"(a), (a, b), AND (a)«.

5.3.8.7 UNION ALL көмегімен материалдандырылған көріністердегі жылдам жаңартуға шектеулер

көмегімен материалдандырылған көріністер UNION ALL операторды орнату REFRESH FAST опция, егер келесі шарттар орындалса:

  • Анықтаушы сұрауда болуы керек UNION ALL жоғарғы деңгейдегі оператор.

    The UNION ALL операторды ішкі сұрау ішіне енгізу мүмкін емес, бір ерекшелік: The UNION ALL ішіндегі ішкі сұрауда болуы мүмкін FROM анықтаушы сұрау пішінде болған жағдайда сөйлем SELECT * FROM (көру немесе қосымша сұрау UNION ALL) келесі мысалдағыдай:

    КӨРІНІС ЖАСАУ view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM тұтынушылар c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM тұтынушылар c WHERE c.cust = «Джонс»); МАТЕРИАЛДАНҒАН КӨРІНІС ЖАСАУ unionall_inside_view_mv СҰРАНЫС БОЙЫНША ТЕЗ ЖАҢАРТУ * FROM view_with_unionall;
    

    Көрініс екенін ескеріңіз view_with_unionall жылдам жаңарту талаптарын қанағаттандырады.

  • Әрбір сұрау блогындағы UNION ALL сұрау агрегаттары бар жылдам жаңартылатын материалдандырылған көріністің немесе біріктірулері бар жылдам жаңартылатын материалдандырылған көріністің талаптарын қанағаттандыруы керек.

    Сәйкес материалдандырылған көрініс журналдары жылдам жаңартылатын материалдандырылған көріністің сәйкес түрі үшін талап етілетін кестелерде жасалуы керек.
    Oracle дерекқоры сонымен қатар тек берілген біріктірулермен материалдандырылған бір кесте көрінісінің ерекше жағдайына мүмкіндік беретінін ескеріңіз ROWID бағанына қосылды SELECT тізімде және материалдандырылған көрініс журналында. Бұл көріністің анықтаушы сұрауында көрсетілген view_with_unionall.

  • The SELECT әрбір сұраудың тізімі а қамтуы керек UNION ALL маркер және UNION ALL бағанның әрқайсысында нақты тұрақты сан немесе жол мәні болуы керек UNION ALL филиалы. Әрі қарай, маркер бағанында бірдей реттік позицияда пайда болуы керек SELECT әрбір сұрау блогының тізімі. Қараңыз»UNION ALL маркер және сұрауды қайта жазу» туралы қосымша ақпарат алу үшін UNION ALL маркерлер.
  • Сыртқы біріктірулер, тек кірістіруге арналған жиынтық материалдандырылған көрініс сұраулары және қашықтағы кестелер сияқты кейбір мүмкіндіктерге материалдандырылған көріністер үшін қолдау көрсетілмейді. UNION ALL. Дегенмен, репликацияда пайдаланылған, біріктірулер немесе жиынтықтарды қамтымайтын материалдандырылған көріністерді келесі жағдайларда жылдам жаңартуға болатынын ескеріңіз. UNION ALL немесе қашықтағы кестелер пайдаланылады.
  • Жылдам жаңартылатын материалдандырылған көріністі жасау үшін үйлесімділікті инициализациялау параметрі 9.2.0 немесе одан жоғары мәнге орнатылуы керек. UNION ALL.

Мен Oracle жанкүйерлерін ренжіткім келмейді, бірақ олардың шектеулер тізіміне қарағанда, бұл механизм жалпы жағдайда емес, қандай да бір үлгіні пайдалана отырып, мыңдаған үндістер жазған сияқты, мұнда барлығына мүмкіндік берілген. өз саласын жазып, әрқайсысы қолынан келгенін істеді. Бұл механизмді нақты логика үшін пайдалану мина алаңында жүрумен бірдей. Сіз кез келген уақытта анық емес шектеулердің біреуін басу арқылы минаны ала аласыз. Оның қалай жұмыс істейтіні де бөлек мәселе, бірақ бұл мақаланың аясынан тыс.

Microsoft SQL Server

Қосымша талаптар

SET опциялары мен детерминирленген функция талаптарына қосымша келесі талаптар орындалуы керек:

  • Орындайтын пайдаланушы CREATE INDEX көріністің иесі болуы керек.
  • Индексті жасаған кезде, IGNORE_DUP_KEY опциясын ӨШІРУ (әдепкі параметр) күйіне орнату керек.
  • Кестелерге сілтеме екі бөліктен тұратын атаулармен көрсетілуі керек, схемасы.кесте атауы көрініс анықтамасында.
  • Көріністе сілтеме жасалған пайдаланушы анықтайтын функцияларды пайдалану арқылы жасау керек WITH SCHEMABINDING опция.
  • Көріністе сілтеме жасалған кез келген пайдаланушы анықтайтын функцияларға екі бөлік атаулары арқылы сілтеме жасалуы керек, ..
  • Пайдаланушы анықтайтын функцияның деректерге қол жеткізу сипаты болуы керек NO SQL, және сыртқы қатынас сипаты болуы керек NO.
  • Жалпы тілдің орындалу уақыты (CLR) функциялары көріністің таңдау тізімінде пайда болуы мүмкін, бірақ кластерленген индекс кілтінің анықтамасының бөлігі бола алмайды. CLR функциялары көріністің WHERE сөйлемінде немесе көріністегі JOIN әрекетінің ON сөйлемінде пайда болмайды.
  • Көрініс анықтамасында пайдаланылатын CLR пайдаланушы анықтайтын түрлердің CLR функциялары мен әдістері келесі кестеде көрсетілгендей орнатылған сипаттарға ие болуы керек.

    меншік
    Ескерту

    ДЕТЕРМИНИСТІК = ШЫН
    Microsoft .NET Framework әдісінің төлсипаты ретінде анық жариялануы керек.

    НАҚТЫ = ШЫН
    .NET Framework әдісінің төлсипаты ретінде анық жариялануы керек.

    ДЕРЕКТЕРГЕ ҚОЛДАНУ = SQL ЖОҚ
    DataAccess төлсипатын DataAccessKind.None және SystemDataAccess төлсипатын SystemDataAccessKind.None параметріне орнату арқылы анықталады.

    СЫРТҚЫ ҚОСУ = ЖОҚ
    Бұл сипат әдепкі бойынша CLR процедуралары үшін ЖОҚ болып табылады.

  • Көрініс арқылы жасалуы керек WITH SCHEMABINDING опция.
  • Көрініс тек көрініспен бірдей дерекқордағы негізгі кестелерге сілтеме жасауы керек. Көрініс басқа көріністерге сілтеме жасай алмайды.
  • Көрініс анықтамасындағы SELECT операторында келесі Transact-SQL элементтері болмауы керек:

    COUNT
    ROWSET функциялары (OPENDATASOURCE, OPENQUERY, OPENROWSET, ЖӘНЕ OPENXML)
    OUTER қосылады(LEFT, RIGHTнемесе FULL)

    Туынды кесте (a. көрсету арқылы анықталады SELECT ішіндегі мәлімдеме FROM тармақ)
    Өздігінен қосылу
    Қолдану арқылы бағандарды анықтау SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPнемесе AVG
    Жалпы кесте өрнегі (CTE)

    жүзу1, мәтін, ntext, бейне, XMLнемесе файлдар ағыны бағандар
    Ішкі сұрау
    OVER тармақ, ол рейтингті немесе жиынтық терезе функцияларын қамтиды

    Толық мәтінді предикаттар (CONTAINS, FREETEXT)
    SUM нөлдік өрнекке сілтеме жасайтын функция
    ORDER BY

    CLR пайдаланушы анықтайтын жиынтық функциясы
    TOP
    CUBE, ROLLUPнемесе GROUPING SETS операторлар

    MIN, MAX
    UNION, EXCEPTнемесе INTERSECT операторлар
    TABLESAMPLE

    Кесте айнымалылары
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Сирек баған жиындары
    Кірістірілген (TVF) немесе көп мәлімдемелік кестелік функциялар (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Индекстелген көріністе болуы мүмкін жүзу бағандар; дегенмен, мұндай бағандарды кластерленген индекс кілтіне қосу мүмкін емес.

  • If GROUP BY бар болса, VIEW анықтамасында болуы керек COUNT_BIG(*) және болмауы керек HAVING. Олар GROUP BY шектеулер индекстелген көрініс анықтамасына ғана қолданылады. Сұрау оларды қанағаттандырмаса да, оның орындалу жоспарында индекстелген көріністі пайдалана алады GROUP BY шектеулер.
  • Көрініс анықтамасында а болса GROUP BY тармағында, бірегей кластерленген индекстің кілті бөлімде көрсетілген бағандарға ғана сілтеме жасай алады GROUP BY тармақ.

Мұнда үндістердің қатысы жоқ екені анық, өйткені олар мұны «біз аз жасаймыз, бірақ жақсы» схемасы бойынша жасауға шешім қабылдады. Яғни, олардың кен орнында көп кеніштері бар, бірақ олардың орналасқан жері ашық. Ең өкініштісі - бұл шектеу:

Көрініс тек көрініспен бірдей дерекқордағы негізгі кестелерге сілтеме жасауы керек. Көрініс басқа көріністерге сілтеме жасай алмайды.

Біздің терминологиямызда бұл функция басқа материалданған функцияға қол жеткізе алмайтынын білдіреді. Бұл бүршіктегі барлық идеологияны жояды.
Сондай-ақ, бұл шектеу (және одан әрі мәтінде) пайдалану жағдайларын айтарлықтай азайтады:

Көрініс анықтамасындағы SELECT операторында келесі Transact-SQL элементтері болмауы керек:

COUNT
ROWSET функциялары (OPENDATASOURCE, OPENQUERY, OPENROWSET, ЖӘНЕ OPENXML)
OUTER қосылады(LEFT, RIGHTнемесе FULL)

Туынды кесте (a. көрсету арқылы анықталады SELECT ішіндегі мәлімдеме FROM тармақ)
Өздігінен қосылу
Қолдану арқылы бағандарды анықтау SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPнемесе AVG
Жалпы кесте өрнегі (CTE)

жүзу1, мәтін, ntext, бейне, XMLнемесе файлдар ағыны бағандар
Ішкі сұрау
OVER тармақ, ол рейтингті немесе жиынтық терезе функцияларын қамтиды

Толық мәтінді предикаттар (CONTAINS, FREETEXT)
SUM нөлдік өрнекке сілтеме жасайтын функция
ORDER BY

CLR пайдаланушы анықтайтын жиынтық функциясы
TOP
CUBE, ROLLUPнемесе GROUPING SETS операторлар

MIN, MAX
UNION, EXCEPTнемесе INTERSECT операторлар
TABLESAMPLE

Кесте айнымалылары
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Сирек баған жиындары
Кірістірілген (TVF) немесе көп мәлімдемелік кестелік функциялар (MSTVF)
OFFSET

CHECKSUM_AGG

СЫРТҚЫ ҚОСЫЛУЛАР, СОЮЗ, ORDER BY және т.б. тыйым салынады. Нені қолдануға болмайтынын емес, нені қолдануға болатынын анықтау оңайырақ болуы мүмкін. Тізім әлдеқайда қысқа болар еді.

Қорытындылай келе: LGPL технологиясындағы әрбір (коммерциялық) ДҚБЖ мен ешқайсысына (бір логикалық емес, техникалық емес) шектеулердің үлкен жиынтығы. Дегенмен, бұл механизмді реляциялық логикада жүзеге асыру сипатталған функционалдық логикаға қарағанда біршама қиынырақ екенін атап өткен жөн.

Реализация

Бұл қалай жұмыс істейді? PostgreSQL «виртуалды машина» ретінде пайдаланылады. Ішінде сұрауларды құрайтын күрделі алгоритм бар. Мұнда қайнар көзі. Сондай-ақ, егер саны бар эвристиканың үлкен жиынтығы ғана емес. Сонымен, егер сізде оқуға бірнеше ай болса, архитектураны түсінуге тырысуға болады.

Ол тиімді жұмыс істей ме? Өте тиімді. Өкінішке орай, мұны дәлелдеу қиын. Мен тек үлкен қосымшаларда бар мыңдаған сұрауларды қарастыратын болсаңыз, орташа алғанда олар жақсы әзірлеушіге қарағанда тиімдірек деп айта аламын. Тамаша SQL бағдарламашысы кез келген сұрауды тиімдірек жаза алады, бірақ мыңдаған сұраулармен оны орындауға мотивациясы да, уақыты да болмайды. Тиімділіктің дәлелі ретінде мен келтіре алатын жалғыз нәрсе - бірнеше жоба осы ДҚБЖ негізінде жасалған платформада жұмыс істейді. ERP жүйелері, мыңдаған әртүрлі МАТЕРИАЛДАНҒАН функциялары бар, мыңдаған пайдаланушылар және кәдімгі екі процессорлы серверде жұмыс істейтін жүздеген миллион жазбалары бар терабайт дерекқорлары бар. Дегенмен, кез келген адам жүктеп алу арқылы тиімділікті тексере алады/жоқтай алады платформа және PostgreSQL, қосылды SQL сұрауларын тіркеу және ондағы логика мен деректерді өзгертуге әрекет жасау.

Келесі мақалаларда мен функцияларға шектеулерді қалай орнатуға, өзгерту сеанстарымен жұмыс істеуге және т.б. туралы айтатын боламын.

Ақпарат көзі: www.habr.com

пікір қалдыру