Ma'lumotlar bazasida yozish va o'qishni muvozanatlash

Ma'lumotlar bazasida yozish va o'qishni muvozanatlash
Avvalgisida maqola Men relyatsion ma'lumotlar bazalarida bo'lgani kabi jadvallar va maydonlar emas, balki funktsiyalar asosida qurilgan ma'lumotlar bazasi tushunchasi va amalga oshirilishini tasvirlab berdim. U ushbu yondashuvning klassikaga nisbatan afzalliklarini ko'rsatadigan ko'plab misollar keltirdi. Ko'pchilik ularni etarlicha ishonarli emas deb topdi.

Ushbu maqolada men ushbu kontseptsiya sizga operatsion mantiqda hech qanday o'zgarishsiz ma'lumotlar bazasiga yozish va o'qishni tez va qulay tarzda muvozanatlash imkonini qanday ko'rsataman. Shunga o'xshash funktsiyani zamonaviy tijorat ma'lumotlar bazasi tizimlarida (xususan, Oracle va Microsoft SQL Server) amalga oshirishga harakat qilingan. Maqolaning oxirida men ularning qilgan ishlari, yumshoq qilib aytganda, unchalik yaxshi natija bermaganini ko'rsataman.

tavsifi

Avvalgidek, yaxshiroq tushunish uchun tavsifni misollar bilan boshlayman. Aytaylik, biz mantiqni amalga oshirishimiz kerak, bu bo'limlar ro'yxatini ulardagi xodimlar soni va ularning umumiy maoshi bilan qaytaradi.

Funktsional ma'lumotlar bazasida u quyidagicha ko'rinadi:

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

Har qanday ma'lumotlar bazasida ushbu so'rovni bajarishning murakkabligi unga teng bo'ladi O (xodimlar soni)chunki bu hisob-kitob xodimlarning butun jadvalini skanerlashni va keyin ularni bo'lim bo'yicha guruhlashni talab qiladi. Tanlangan rejaga qarab, kichik (biz bo'limlarga qaraganda ko'proq xodimlar borligiga ishonamiz) qo'shimchalar ham bo'ladi. O (xodimlar soni jurnali) yoki O (bo'limlar soni) guruhlash uchun va boshqalar.

Ma'lumki, har xil ma'lumotlar bazasida bajariladigan qo'shimcha xarajatlar har xil bo'lishi mumkin, ammo murakkablik hech qanday tarzda o'zgarmaydi.

Tavsiya etilgan amalga oshirishda funktsional ma'lumotlar bazasi bo'limi bo'lim uchun zarur bo'lgan qiymatlarni hisoblaydigan bitta quyi so'rovni yaratadi va keyin nomni olish uchun bo'lim jadvaliga QO'SHILADI. Biroq, har bir funktsiya uchun e'lon qilishda maxsus MATERIALIZE markerni o'rnatish mumkin. Tizim avtomatik ravishda har bir bunday funktsiya uchun tegishli maydonni yaratadi. Funktsiya qiymatini o'zgartirganda, maydonning qiymati ham xuddi shu tranzaksiyada o'zgaradi. Ushbu funktsiyaga kirishda oldindan hisoblangan maydonga kirish mumkin bo'ladi.

Xususan, agar siz funksiyalar uchun MATERIALIZED o'rnatsangiz Xodimlar soni и ish haqi summasi, keyin bo'limlar ro'yxati bilan jadvalga ikkita maydon qo'shiladi, unda xodimlar soni va ularning umumiy ish haqi saqlanadi. Xodimlar, ularning maoshlari yoki bo'limga mansubligi o'zgarganda, tizim avtomatik ravishda ushbu maydonlarning qiymatlarini o'zgartiradi. Yuqoridagi so'rov to'g'ridan-to'g'ri ushbu maydonlarga kiradi va bajariladi O (bo'limlar soni).

Qanday cheklovlar bor? Faqat bitta narsa: bunday funktsiyada uning qiymati aniqlangan cheklangan miqdordagi kirish qiymatlari bo'lishi kerak. Aks holda, uning barcha qiymatlarini saqlaydigan jadvalni qurish mumkin bo'lmaydi, chunki cheksiz sonli qatorli jadval bo'lishi mumkin emas.

Misol:

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

Ushbu funktsiya cheksiz miqdordagi N qiymatlari uchun aniqlanadi (masalan, har qanday salbiy qiymat mos keladi). Shuning uchun siz unga MATERIALIZED qo'yolmaysiz. Demak, bu mantiqiy cheklov, texnik emas (ya'ni, biz uni amalga oshira olmaganimiz uchun emas). Aks holda, hech qanday cheklovlar yo'q. Guruhlash, saralash, AND va OR, PARTITION, rekursiya va boshqalardan foydalanishingiz mumkin.

Masalan, oldingi maqolaning 2.2-muammosida ikkala funktsiyaga MATERIALIZED ni qo'yishingiz mumkin:

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;

Tizimning o'zi turi kalitlari bilan bitta jadval yaratadi Mijozlar, mahsulot и TAM, unga ikkita maydon qo'shadi va ulardagi maydon qiymatlarini har qanday o'zgarishlar bilan yangilaydi. Ushbu funktsiyalarga qo'shimcha qo'ng'iroqlar amalga oshirilganda, ular hisoblanmaydi, aksincha qiymatlar tegishli maydonlardan o'qiladi.

Ushbu mexanizmdan foydalanib, siz, masalan, so'rovlardagi rekursiyalardan (CTE) xalos bo'lishingiz mumkin. Xususan, bola/ota-ona munosabatlaridan foydalangan holda daraxt hosil qiluvchi guruhlarni ko'rib chiqing (har bir guruh o'z ota-onasi bilan bog'langan):

parent = DATA Group (Group);

Funktsional ma'lumotlar bazasida rekursiya mantig'ini quyidagicha ko'rsatish mumkin:

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;

Chunki funktsiya uchun Ota-ona MATERIALIZE qilingan deb belgilangan bo'lsa, u uchun ikkita kalitli (guruh) jadval tuziladi, unda maydon Ota-ona birinchi kalit ikkinchisining bolasi bo'lsagina to'g'ri bo'ladi. Ushbu jadvaldagi yozuvlar soni daraxtning o'rtacha chuqurligiga ko'paytirilgan guruhlar soniga teng bo'ladi. Agar sizga, masalan, ma'lum bir guruhning avlodlari sonini hisoblash kerak bo'lsa, siz ushbu funktsiyadan foydalanishingiz mumkin:

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

SQL so'rovida CTE bo'lmaydi. Buning o'rniga oddiy GROUP BY bo'ladi.

Ushbu mexanizmdan foydalanib, agar kerak bo'lsa, ma'lumotlar bazasini osongina normalizatsiya qilishingiz mumkin:

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

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

Funktsiyani chaqirganda sana buyurtma qatori uchun indeks mavjud bo'lgan maydon buyurtma satrlari bilan jadvaldan o'qiladi. Buyurtma sanasi o'zgarganda, tizimning o'zi avtomatik ravishda chiziqdagi normalizatsiya qilingan sanani qayta hisoblab chiqadi.

Kanada PR

Bu butun mexanizm nima uchun? Klassik DBMSlarda, so'rovlarni qayta yozmasdan, ishlab chiquvchi yoki DBA faqat indekslarni o'zgartirishi, statistik ma'lumotlarni aniqlashi va so'rovlarni rejalashtiruvchiga ularni qanday bajarish kerakligini aytishi mumkin (va MA'LUMOTlar faqat tijorat DBMSlarida mavjud). Qanchalik urinmasinlar, maqoladagi birinchi so'rovni bajara olmaydilar O (bo'limlar soni) so'rovlarni o'zgartirmasdan yoki triggerlarni qo'shmasdan. Taklif etilgan sxemada, ishlab chiqish bosqichida siz ma'lumotlarni saqlash tuzilishi va qaysi agregatlardan foydalanish haqida o'ylashingiz shart emas. Bularning barchasini tezda, to'g'ridan-to'g'ri ishlashda osongina o'zgartirish mumkin.

Amalda bu shunday ko'rinadi. Ba'zi odamlar mantiqni bevosita topshiriq asosida rivojlantiradilar. Ular algoritmlarni va ularning murakkabligini, bajarish rejalarini, birlashma turlarini yoki boshqa texnik komponentlarni tushunmaydilar. Bu odamlar ishlab chiquvchilardan ko'ra ko'proq biznes tahlilchilaridir. Keyin, bularning barchasi sinovga yoki operatsiyaga o'tadi. Uzoq davom etayotgan so'rovlarni jurnalga kiritish imkonini beradi. Uzoq so'rov aniqlanganda, boshqa odamlar (ko'proq texnik - asosan DBA) ba'zi bir oraliq funktsiyada MATERIALIZED-ni yoqishga qaror qilishadi. Bu yozuvni biroz sekinlashtiradi (chunki u tranzaksiyada qo'shimcha maydonni yangilashni talab qiladi). Biroq, nafaqat ushbu so'rov, balki ushbu funktsiyadan foydalanadigan barcha boshqa so'rovlar ham sezilarli darajada tezlashadi. Shu bilan birga, qaysi funktsiyani amalga oshirishni hal qilish nisbatan oson. Ikkita asosiy parametr: mumkin bo'lgan kirish qiymatlari soni (tegishli jadvalda qancha yozuvlar bo'ladi) va u boshqa funktsiyalarda qanchalik tez-tez ishlatiladi.

Analoglar

Zamonaviy tijorat ma'lumotlar bazasida ham xuddi shunday mexanizmlar mavjud: FAST REFRESH (Oracle) va INDEXED VIEW (Microsoft SQL Server). PostgreSQL-da MATERIALIZED VIEW tranzaksiyada yangilanishi mumkin emas, faqat so'rov bo'yicha (va hatto juda qattiq cheklovlar bilan), shuning uchun biz buni hisobga olmaymiz. Lekin ular foydalanishni sezilarli darajada cheklaydigan bir nechta muammolarga ega.

Birinchidan, agar siz allaqachon oddiy VIEW ni yaratgan bo'lsangiz, moddiylashtirishni yoqishingiz mumkin. Aks holda, ushbu materializatsiyadan foydalanish uchun yangi yaratilgan ko'rinishga kirish uchun qolgan so'rovlarni qayta yozishingiz kerak bo'ladi. Yoki hamma narsani avvalgidek qoldiring, lekin oldindan hisoblangan ma'lumotlar mavjud bo'lsa, u hech bo'lmaganda samarasiz bo'ladi, lekin ko'p so'rovlar har doim ham uni ishlatmaydi, lekin uni qayta hisoblab chiqadi.

Ikkinchidan, ular juda ko'p cheklovlarga ega:

Oracle

5.3.8.4 Tez yangilash bo'yicha umumiy cheklovlar

Materiallashtirilgan ko'rinishning aniqlovchi so'rovi quyidagicha cheklangan:

  • Moddiylashtirilgan ko'rinishda takrorlanmaydigan iboralarga havolalar bo'lmasligi kerak SYSDATE va ROWNUM.
  • Moddiylashtirilgan ko'rinishda havolalar bo'lmasligi kerak RAW or LONG RAW ma'lumotlar turlari.
  • U o'z ichiga olmaydi SELECT ro'yxat pastki so'rovi.
  • U analitik funktsiyalarni o'z ichiga olmaydi (masalan, RANK) SELECT modda.
  • U bo'lgan jadvalga havola qila olmaydi XMLIndex indeksi aniqlanadi.
  • U o'z ichiga olmaydi MODEL modda.
  • U o'z ichiga olmaydi HAVING pastki so'rovli band.
  • U mavjud so'rovlarni o'z ichiga olmaydi ANY, ALLyoki NOT EXISTS.
  • U o'z ichiga olmaydi [START WITH …] CONNECT BY modda.
  • Turli saytlarda bir nechta batafsil jadvallarni o'z ichiga olmaydi.
  • ON COMMIT moddiylashtirilgan ko'rinishlarda masofaviy tafsilotlar jadvallari bo'lishi mumkin emas.
  • Ichki oʻrnatilgan koʻrinishlar birlashma yoki yigʻma boʻlishi kerak.
  • Moddiylashtirilgan qoʻshilish koʻrinishlari va a bilan moddiylashtirilgan yigʻma koʻrinishlar GROUP BY bandni indeks bilan tashkil etilgan jadvaldan tanlay olmaydi.

5.3.8.5 Faqat qo'shilishlar bilan materiallashtirilgan ko'rinishlardagi Tez yangilash bo'yicha cheklovlar

Materiallashtirilgan ko‘rinishlar uchun so‘rovlarni faqat birlashma va agregatlarsiz aniqlashda tez yangilanish bo‘yicha quyidagi cheklovlar mavjud:

  • Barcha cheklovlar «Tez yangilash bo'yicha umumiy cheklovlar".
  • Ular ega bo'lolmaydi GROUP BY bandlar yoki birikmalar.
  • Barcha jadvallarning qatorlari FROM ro'yxatda ko'rsatilishi kerak SELECT so'rov ro'yxati.
  • Materiallashtirilgan ko'rinish jurnallari barcha asosiy jadvallar uchun qatorlar bilan mavjud bo'lishi kerak FROM so'rov ro'yxati.
  • Ob'ekt turi ustunini o'z ichiga olgan oddiy birikmalar bilan bir nechta jadvallardan tez yangilanadigan materiallashtirilgan ko'rinishni yarata olmaysiz. SELECT tasdiqlash.

Shuningdek, siz tanlagan yangilash usuli quyidagi hollarda optimal darajada samarali bo'lmaydi:

  • Aniqlovchi so'rov ichki birlashma kabi harakat qiladigan tashqi birikmadan foydalanadi. Agar aniqlovchi so'rovda shunday birlashma mavjud bo'lsa, ichki birlashmani o'z ichiga olishi uchun aniqlovchi so'rovni qayta yozishni o'ylab ko'ring.
  • The SELECT materiallashtirilgan ko'rinish ro'yxati bir nechta jadvallarning ustunlaridagi ifodalarni o'z ichiga oladi.

5.3.8.6 Agregatlar bilan moddiylashtirilgan ko'rinishlarda tez yangilanish bo'yicha cheklovlar

Agregatlar yoki birlashmalar bilan moddiylashtirilgan ko'rinishlar uchun so'rovlarni aniqlash tez yangilashda quyidagi cheklovlarga ega:

Tez yangilash ikkalasi uchun ham qo'llab-quvvatlanadi ON COMMIT va ON DEMAND moddiylashtirilgan qarashlar, ammo quyidagi cheklovlar qo'llaniladi:

  • Materiallashtirilgan ko'rinishdagi barcha jadvallar moddiylashtirilgan ko'rish jurnallariga ega bo'lishi kerak va materiallashtirilgan ko'rish jurnallari quyidagilarga ega bo'lishi kerak:
    • Materiallashtirilgan ko'rinishda havola qilingan jadvalning barcha ustunlarini o'z ichiga oladi.
    • bilan belgilang ROWID va INCLUDING NEW VALUES.
    • Belgilang SEQUENCE agar jadval qo'shimchalar/to'g'ridan-to'g'ri yuklashlar, o'chirishlar va yangilanishlar aralashmasiga ega bo'lishi kutilsa.

  • faqat SUM, COUNT, AVG, STDDEV, VARIANCE, MIN va MAX tez yangilash uchun qo'llab-quvvatlanadi.
  • COUNT(*) belgilanishi kerak.
  • Agregat funktsiyalar faqat ifodaning eng tashqi qismi sifatida paydo bo'lishi kerak. Ya'ni, kabi agregatlar AVG(AVG(x)) or AVG(x)+ AVG(x) ruxsat berilmaydi.
  • Har bir agregat uchun, masalan AVG(expr), mos keladigan COUNT(expr) mavjud bo'lishi kerak. Oracle buni tavsiya qiladi SUM(expr) belgilanishi.
  • If VARIANCE(expr) or STDDEV(expr) belgilangan, COUNT(expr) va SUM(expr) belgilanishi kerak. Oracle buni tavsiya qiladi SUM(expr *expr) belgilanishi.
  • The SELECT belgilash so'rovidagi ustun bir nechta asosiy jadvallar ustunlari bilan murakkab ifoda bo'lishi mumkin emas. Buning mumkin bo'lgan vaqtinchalik yechimi ichki materiallashtirilgan ko'rinishdan foydalanishdir.
  • The SELECT ro'yxat hammasini o'z ichiga olishi kerak GROUP BY ustunlar.
  • Moddiylashtirilgan ko'rinish bir yoki bir nechta uzoq jadvallarga asoslanmagan.
  • Agar siz a dan foydalansangiz CHAR materiallashtirilgan ko'rinish jurnalining filtr ustunlaridagi ma'lumotlar turi, asosiy saytning belgilar to'plami va materiallashtirilgan ko'rinish bir xil bo'lishi kerak.
  • Agar materiallashtirilgan ko'rinishda quyidagilardan biriga ega bo'lsa, tez yangilash faqat an'anaviy DML qo'shimchalarida va to'g'ridan-to'g'ri yuklarda qo'llab-quvvatlanadi.
    • bilan moddiylashtirilgan ko'rinishlar MIN or MAX agregatlar
    • Moddiylashtirilgan qarashlar mavjud SUM(expr) lekin yoq COUNT(expr)
    • Moddiy ko'rinishlarsiz COUNT(*)

    Bunday materiallashtirilgan ko'rinish faqat qo'shish uchun materiallashtirilgan ko'rinish deb ataladi.

  • bilan moddiylashtirilgan ko'rinish MAX or MIN o'chirish yoki aralashgan DML iboralaridan so'ng tezda yangilanadi, agar u bo'lmasa WHERE modda.
    Oʻchirish yoki aralashtirilgan DMLdan soʻng maksimal/min tezlikda yangilanish faqat qoʻshish holati bilan bir xil harakatga ega emas. Ta'sir qilingan guruhlar uchun maksimal/min qiymatlarini o'chiradi va qayta hisoblaydi. Uning ishlashiga ta'sirini bilishingiz kerak.
  • Nomlangan ko'rinishlar yoki pastki so'rovlar bilan moddiylashtirilgan ko'rinishlar FROM ko'rinishlar to'liq birlashtirilsa, bandni tezda yangilash mumkin. Qaysi ko'rinishlar birlashishi haqida ma'lumot olish uchun qarang Oracle ma'lumotlar bazasi SQL tiliga havola.
  • Agar tashqi birikmalar bo'lmasa, sizda o'zboshimchalik bilan tanlov va qo'shilishlar bo'lishi mumkin WHERE modda.
  • Tashqi birlashmalari bilan materiallashtirilgan agregat ko'rinishlar an'anaviy DML va to'g'ridan-to'g'ri yuklardan so'ng tezda yangilanadi, faqat tashqi jadval o'zgartirilgan bo'lsa. Bundan tashqari, ichki birlashma jadvalining birlashma ustunlarida noyob cheklovlar mavjud bo'lishi kerak. Agar tashqi birikmalar mavjud bo'lsa, barcha birikmalar orqali ulanishi kerak ANDs va tenglikdan foydalanish kerak (=) operatori.
  • bilan moddiylashtirilgan ko'rinishlar uchun CUBE, ROLLUP, guruhlash to'plamlari yoki ularni birlashtirish uchun quyidagi cheklovlar qo'llaniladi:
    • The SELECT ro'yxat a bo'lishi mumkin bo'lgan guruhlash ajratuvchisini o'z ichiga olishi kerak GROUPING_ID hamma uchun funksiya GROUP BY ifodalar yoki GROUPING har biri uchun bittadan ishlaydi GROUP BY ifoda. Masalan, agar GROUP BY moddiylashtirilgan ko'rinishning bandi "GROUP BY CUBE(a, b)", keyin SELECT ro'yxatda "bo'lishi kerak"GROUPING_ID(a, b)» yoki «GROUPING(a) AND GROUPING(b)» moddiylashtirilgan ko'rinish tez yangilanishi uchun.
    • GROUP BY hech qanday takroriy guruhlarga olib kelmasligi kerak. Masalan, "GROUP BY a, ROLLUP(a, b)"Tez yangilanmaydi, chunki u takroriy guruhlarga olib keladi"(a), (a, b), AND (a)".

5.3.8.7 UNION ALL bilan materiallashtirilgan ko‘rinishlarni tez yangilash bo‘yicha cheklovlar

bilan moddiylashtirilgan ko'rinishlar UNION ALL operatorni qo'llab-quvvatlashni sozlash REFRESH FAST quyidagi shartlar bajarilsa, variant:

  • Aniqlovchi so'rovda bo'lishi kerak UNION ALL yuqori darajadagi operator.

    The UNION ALL operatorni quyi so'rovga kiritib bo'lmaydi, bundan mustasno: The UNION ALL ning pastki so'rovida bo'lishi mumkin FROM belgilovchi so'rov shaklda bo'lishi sharti bilan band SELECT * FROM (bilan ko'rish yoki quyi so'rov UNION ALL) quyidagi misoldagi kabi:

    KO'RISH ko'rinishini_with_unionall AS YARATING
    (SELECT c.rowid crid, c.cust_id, 2 umarker
     FROM mijozlardan c WHERE c.cust_last_name = 'Smit'
     HAMMA ittifoq
     SELECT c.rowid crid, c.cust_id, 3 umarker
     FROM mijozlardan c WHERE c.cust_last_name = 'Jons');
    
    MATERIALIZALANGAN KO'RISHNI YARATING unionall_inside_view_mv
    AS TALABGA TEZ YANGILASH
    TANLOV * FROM view_with_unionall;
    

    Ko'rinishga e'tibor bering view_with_unionall tez yangilash talablarini qondiradi.

  • Har bir so'rov blokidagi UNION ALL so'rov agregatlar bilan tez yangilanadigan materiallashtirilgan ko'rinish yoki birikmalar bilan tez yangilanadigan materiallashtirilgan ko'rinish talablariga javob berishi kerak.

    Tez yangilanadigan materiallashtirilgan ko'rinishning mos keladigan turi uchun kerak bo'lganda, tegishli materiallashtirilgan ko'rinish jurnallari jadvallarda yaratilishi kerak.
    Shuni esda tutingki, Oracle ma'lumotlar bazasi, shuningdek, birlashma bilan faqat bitta jadvalning materiallashtirilgan ko'rinishining maxsus holatiga ruxsat beradi ROWID ustuniga kiritilgan SELECT ro'yxati va moddiylashtirilgan ko'rish jurnalida. Bu ko'rinishning aniqlovchi so'rovida ko'rsatilgan view_with_unionall.

  • The SELECT har bir so'rov ro'yxati a bo'lishi kerak UNION ALL marker va UNION ALL ustun har birida alohida doimiy raqamli yoki satr qiymatiga ega bo'lishi kerak UNION ALL filiali. Bundan tashqari, marker ustuni bir xil tartib holatida paydo bo'lishi kerak SELECT har bir so'rov blokining ro'yxati. Qarang"UNION ALL Marker va so'rovlarni qayta yozish» haqida qo'shimcha ma'lumot olish uchun UNION ALL belgilar.
  • Tashqi birlashmalar, faqat qo'shish uchun yig'ilgan materiallashtirilgan ko'rinish so'rovlari va masofaviy jadvallar kabi ba'zi xususiyatlar moddiylashtirilgan ko'rinishlar uchun qo'llab-quvvatlanmaydi. UNION ALL. Ammo shuni yodda tutingki, replikatsiyada foydalanilgan, birlashmalar yoki agregatlarni o'z ichiga olmagan moddiylashtirilgan ko'rinishlar qachon tez yangilanishi mumkin. UNION ALL yoki masofaviy jadvallar ishlatiladi.
  • Tez yangilanadigan materiallashtirilgan ko'rinishni yaratish uchun moslikni ishga tushirish parametri 9.2.0 yoki undan yuqori bo'lishi kerak. UNION ALL.

Men Oracle muxlislarini xafa qilishni xohlamayman, lekin ularning cheklovlar ro'yxatiga ko'ra, bu mexanizm umumiy holatda emas, balki qandaydir modeldan foydalangan holda, balki minglab hindular tomonidan yozilganga o'xshaydi, bu erda hamma uchun imkoniyat berilgan. o'z filialini yozing va ularning har biri qo'lidan kelganini qildi va qildi. Haqiqiy mantiq uchun ushbu mexanizmdan foydalanish minalangan maydonda yurishga o'xshaydi. Siz istalgan vaqtda aniq bo'lmagan cheklovlardan birini bosib mina olishingiz mumkin. Bu qanday ishlaydi - bu alohida savol, ammo bu maqola doirasidan tashqarida.

Microsoft SQL Server

Qo'shimcha talablar

SET opsiyalari va deterministik funktsiya talablariga qo'shimcha ravishda quyidagi talablar bajarilishi kerak:

  • Amalga oshiruvchi foydalanuvchi CREATE INDEX ko'rinishning egasi bo'lishi kerak.
  • Indeksni yaratganingizda, IGNORE_DUP_KEY parametr OFF (standart sozlama) ga o'rnatilishi kerak.
  • Jadvallar ikki qismli nomlar bilan havola qilinishi kerak, sxemasi.stol nomi ko'rinish ta'rifida.
  • Ko'rinishda havola qilingan foydalanuvchi tomonidan belgilangan funksiyalar yordamida yaratilishi kerak WITH SCHEMABINDING variant.
  • Ko'rinishda havola qilingan foydalanuvchi tomonidan belgilangan har qanday funksiyalar ikki qismli nomlar bilan havola qilinishi kerak, ..
  • Foydalanuvchi tomonidan belgilangan funksiyaning ma'lumotlarga kirish xususiyati bo'lishi kerak NO SQL, va tashqi kirish xususiyati bo'lishi kerak NO.
  • Umumiy tilning ishlash vaqti (CLR) funktsiyalari ko'rinishning tanlangan ro'yxatida paydo bo'lishi mumkin, lekin klasterli indeks kaliti ta'rifining bir qismi bo'lishi mumkin emas. CLR funksiyalari ko'rinishdagi WHERE bandida yoki JOIN operatsiyasining ON bandida ko'rsatilmaydi.
  • Ko'rinish ta'rifida foydalaniladigan CLR foydalanuvchi tomonidan belgilangan turdagi CLR funktsiyalari va usullari quyidagi jadvalda ko'rsatilganidek o'rnatilgan xususiyatlarga ega bo'lishi kerak.

    mulk
    Eslatma

    DETERMINISTIC = ROS
    Microsoft .NET Framework usulining atributi sifatida aniq e'lon qilinishi kerak.

    PRECISE = ROS
    .NET Framework usulining atributi sifatida aniq e'lon qilinishi kerak.

    MA'LUMOTLARGA ACCESS = SQL YO'Q
    DataAccess atributini DataAccessKind.None va SystemDataAccess atributini SystemDataAccessKind.None ga o‘rnatish orqali aniqlanadi.

    tashqi kirish = YO'Q
    Bu xususiyat CLR tartiblari uchun sukut bo‘yicha YO‘Q hisoblanadi.

  • Ko'rinish yordamida yaratilishi kerak WITH SCHEMABINDING variant.
  • Ko'rinish faqat ko'rinish bilan bir xil ma'lumotlar bazasida joylashgan asosiy jadvallarga murojaat qilishi kerak. Ko'rinish boshqa ko'rinishlarga havola qila olmaydi.
  • Ko'rinish ta'rifidagi SELECT iborasida quyidagi Transact-SQL elementlari bo'lmasligi kerak:

    COUNT
    ROWSET funksiyalari (OPENDATASOURCE, OPENQUERY, OPENROWSET, VA OPENXML)
    OUTER qo'shiladi (LEFT, RIGHTyoki FULL)

    Olingan jadval (a ko'rsatilishi bilan aniqlanadi SELECT dagi bayonot FROM bandi)
    O'z-o'zidan qo'shilish
    Foydalanish orqali ustunlarni belgilash SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPyoki AVG
    Umumiy jadval ifodasi (CTE)

    suzmoq1, matn, ntext, surat, XMLyoki fayllar oqimi ustunlar
    Quyi soʻrov
    OVER tartiblash yoki jamlash oyna funksiyalarini o'z ichiga olgan band

    To'liq matnli predikatlar (CONTAINS, FREETEXT)
    SUM null bo'ladigan ifodaga murojaat qiluvchi funksiya
    ORDER BY

    CLR foydalanuvchi tomonidan belgilangan agregat funktsiyasi
    TOP
    CUBE, ROLLUPyoki GROUPING SETS operatorlari

    MIN, MAX
    UNION, EXCEPTyoki INTERSECT operatorlari
    TABLESAMPLE

    Jadval o'zgaruvchilari
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Noyob ustunlar to'plami
    Inline (TVF) yoki ko'p bayonotli jadval qiymatli funktsiyalar (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Indekslangan ko'rinish o'z ichiga olishi mumkin suzmoq ustunlar; ammo bunday ustunlarni klasterlangan indeks kalitiga kiritish mumkin emas.

  • If GROUP BY mavjud bo'lsa, VIEW ta'rifi o'z ichiga olishi kerak COUNT_BIG(*) va o'z ichiga olmaydi HAVING. Ular GROUP BY cheklovlar faqat indekslangan ko'rinish ta'rifiga nisbatan qo'llaniladi. So'rov o'zining bajarilish rejasida indekslangan ko'rinishdan foydalanishi mumkin, hatto u ularni qoniqtirmasa ham GROUP BY cheklovlar.
  • Agar ko'rinish ta'rifi a bo'lsa GROUP BY bandida, noyob klasterli indeksning kaliti faqat ko'rsatilgan ustunlarga murojaat qilishi mumkin GROUP BY modda.

Bu erda hindular ishtirok etmagani aniq, chunki ular buni "biz kam ishlaymiz, lekin yaxshi" sxemasi bo'yicha qilishga qaror qilishdi. Ya'ni, ular dalada ko'proq minalar bor, lekin ularning joylashuvi shaffofroq. Eng achinarlisi bu cheklovdir:

Ko'rinish faqat ko'rinish bilan bir xil ma'lumotlar bazasida joylashgan asosiy jadvallarga murojaat qilishi kerak. Ko'rinish boshqa ko'rinishlarga havola qila olmaydi.

Bizning terminologiyamizda bu funktsiya boshqa moddiylashtirilgan funktsiyaga kira olmasligini anglatadi. Bu kurtakdagi barcha mafkurani kesadi.
Bundan tashqari, ushbu cheklov (va undan keyingi matnda) foydalanish holatlarini sezilarli darajada kamaytiradi:

Ko'rinish ta'rifidagi SELECT iborasida quyidagi Transact-SQL elementlari bo'lmasligi kerak:

COUNT
ROWSET funksiyalari (OPENDATASOURCE, OPENQUERY, OPENROWSET, VA OPENXML)
OUTER qo'shiladi (LEFT, RIGHTyoki FULL)

Olingan jadval (a ko'rsatilishi bilan aniqlanadi SELECT dagi bayonot FROM bandi)
O'z-o'zidan qo'shilish
Foydalanish orqali ustunlarni belgilash SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPyoki AVG
Umumiy jadval ifodasi (CTE)

suzmoq1, matn, ntext, surat, XMLyoki fayllar oqimi ustunlar
Quyi soʻrov
OVER tartiblash yoki jamlash oyna funksiyalarini o'z ichiga olgan band

To'liq matnli predikatlar (CONTAINS, FREETEXT)
SUM null bo'ladigan ifodaga murojaat qiluvchi funksiya
ORDER BY

CLR foydalanuvchi tomonidan belgilangan agregat funktsiyasi
TOP
CUBE, ROLLUPyoki GROUPING SETS operatorlari

MIN, MAX
UNION, EXCEPTyoki INTERSECT operatorlari
TABLESAMPLE

Jadval o'zgaruvchilari
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Noyob ustunlar to'plami
Inline (TVF) yoki ko'p bayonotli jadval qiymatli funktsiyalar (MSTVF)
OFFSET

CHECKSUM_AGG

OUTTER JOINS, UNION, ORDER BY va boshqalar taqiqlanadi. Nimani ishlatish mumkin emasligini emas, balki nimadan foydalanish mumkinligini belgilash osonroq bo'lishi mumkin edi. Ro'yxat, ehtimol, ancha qisqaroq bo'lar edi.

Xulosa qilib aytadigan bo'lsak: LGPL texnologiyasidagi har bir (tijoriy) ma'lumotlar bazasi bo'yicha katta cheklovlar to'plami va ularning hech biri (bitta mantiqiy, texnik istisno bundan mustasno). Ammo shuni ta'kidlash kerakki, ushbu mexanizmni relyatsion mantiqda amalga oshirish tavsiflangan funktsional mantiqqa qaraganda biroz qiyinroq.

Реализация

U qanday ishlaydi? PostgreSQL "virtual mashina" sifatida ishlatiladi. Ichkarida so'rovlarni tuzadigan murakkab algoritm mavjud. Bu yerga manba kodi. Va bu erda faqat bir nechta if bo'lgan evristikaning katta to'plami mavjud emas. Shunday qilib, agar sizda o'qish uchun bir necha oy bo'lsa, siz arxitekturani tushunishga harakat qilishingiz mumkin.

U samarali ishlaydimi? Juda samarali. Afsuski, buni isbotlash qiyin. Faqat shuni aytishim mumkinki, agar siz katta ilovalarda mavjud bo'lgan minglab so'rovlarni hisobga olsangiz, ular o'rtacha hisobda yaxshi ishlab chiquvchiga qaraganda samaraliroq. Zo'r SQL dasturchisi har qanday so'rovni samaraliroq yozishi mumkin, ammo minglab so'rovlar bilan u buni amalga oshirish uchun motivatsiya yoki vaqtga ega bo'lmaydi. Endi samaradorlikning isboti sifatida keltira oladigan yagona narsa shundaki, ushbu DBMSda qurilgan platformada bir nechta loyihalar ishlamoqda. ERP tizimlari, minglab turli MATERIALIZE qilingan funksiyalarga ega, minglab foydalanuvchilar va oddiy ikki protsessorli serverda ishlaydigan yuzlab million yozuvlarga ega terabayt ma'lumotlar bazalari. Biroq, har kim yuklab olish orqali samaradorlikni tekshirishi/rad etishi mumkin platforma va PostgreSQL, yoqilgan SQL so'rovlarini yozish va u erda mantiq va ma'lumotlarni o'zgartirishga harakat qilish.

Keyingi maqolalarda men funktsiyalarga qanday cheklovlar o'rnatishingiz, o'zgartirish seanslari bilan ishlashingiz va boshqalar haqida gapirib beraman.

Manba: www.habr.com

a Izoh qo'shish