Mengimbangi menulis dan membaca dalam pangkalan data

Mengimbangi menulis dan membaca dalam pangkalan data
Dalam sebelumnya artikel Saya menerangkan konsep dan pelaksanaan pangkalan data yang dibina berdasarkan fungsi, bukannya jadual dan medan seperti dalam pangkalan data hubungan. Ia memberikan banyak contoh yang menunjukkan kelebihan pendekatan ini berbanding pendekatan klasik. Ramai mendapati mereka tidak cukup meyakinkan.

Dalam artikel ini, saya akan menunjukkan bagaimana konsep ini membolehkan anda mengimbangi penulisan dan membaca dengan cepat dan mudah ke pangkalan data tanpa sebarang perubahan dalam logik operasi. Fungsi yang serupa telah cuba dilaksanakan dalam DBMS komersial moden (khususnya, Oracle dan Microsoft SQL Server). Pada penghujung artikel saya akan menunjukkan bahawa apa yang mereka lakukan, secara sederhana, tidak berjaya dengan baik.

ОписаниС

Seperti sebelum ini, untuk pemahaman yang lebih baik saya akan memulakan penerangan dengan contoh. Katakan kita perlu melaksanakan logik yang akan mengembalikan senarai jabatan dengan bilangan pekerja di dalamnya dan jumlah gaji mereka.

Dalam pangkalan data berfungsi ia akan kelihatan seperti ini:

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

Kerumitan melaksanakan pertanyaan ini dalam mana-mana DBMS akan bersamaan dengan O(bilangan pekerja)kerana pengiraan ini memerlukan pengimbasan keseluruhan jadual pekerja dan kemudian mengumpulkan mereka mengikut jabatan. Terdapat juga beberapa tambahan kecil (kami percaya terdapat lebih ramai pekerja daripada jabatan) bergantung pada pelan yang dipilih O(nombor log pekerja) atau O(bilangan jabatan) untuk berkumpulan dan sebagainya.

Adalah jelas bahawa overhed pelaksanaan mungkin berbeza dalam DBMS yang berbeza, tetapi kerumitan tidak akan berubah dalam apa jua cara.

Dalam pelaksanaan yang dicadangkan, DBMS berfungsi akan menjana satu subquery yang akan mengira nilai yang diperlukan untuk jabatan, dan kemudian membuat JOIN dengan jadual jabatan untuk mendapatkan nama. Walau bagaimanapun, untuk setiap fungsi, apabila mengisytiharkan, adalah mungkin untuk menetapkan penanda MATERIALIZED khas. Sistem secara automatik akan mencipta medan yang sepadan untuk setiap fungsi tersebut. Apabila menukar nilai fungsi, nilai medan juga akan berubah dalam transaksi yang sama. Apabila mengakses fungsi ini, medan pra-kira akan diakses.

Khususnya, jika anda menetapkan MATERIALIZED untuk fungsi kiraPekerja ΠΈ gajiSum, kemudian dua medan akan ditambah ke jadual dengan senarai jabatan, yang akan menyimpan bilangan pekerja dan jumlah gaji mereka. Setiap kali terdapat perubahan dalam pekerja, gaji atau gabungan jabatan mereka, sistem secara automatik akan menukar nilai bidang ini. Pertanyaan di atas akan mengakses medan ini secara langsung dan akan dilaksanakan dalam O(bilangan jabatan).

Apakah sekatan? Hanya satu perkara: fungsi sedemikian mesti mempunyai bilangan terhingga nilai input yang mana nilainya ditentukan. Jika tidak, adalah mustahil untuk membina jadual yang menyimpan semua nilainya, kerana tidak boleh ada jadual dengan bilangan baris yang tidak terhingga.

Contoh:

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

Fungsi ini ditakrifkan untuk bilangan nilai N yang tidak terhingga (contohnya, sebarang nilai negatif adalah sesuai). Oleh itu, anda tidak boleh meletakkan MATERIALIZED padanya. Jadi ini adalah batasan logik, bukan teknikal (iaitu, bukan kerana kami tidak dapat melaksanakannya). Jika tidak, tiada sekatan. Anda boleh menggunakan pengumpulan, pengisihan, DAN dan ATAU, PARTITION, rekursi, dsb.

Sebagai contoh, dalam masalah 2.2 artikel sebelumnya, anda boleh meletakkan MATERIALIZED pada kedua-dua fungsi:

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;

Sistem itu sendiri akan membuat satu jadual dengan kekunci jenis Pelanggan, Produk ΠΈ INTEGER, akan menambah dua medan padanya dan akan mengemas kini nilai medan di dalamnya dengan sebarang perubahan. Apabila panggilan lanjut ke fungsi ini dibuat, ia tidak akan dikira, sebaliknya nilai akan dibaca dari medan yang sepadan.

Menggunakan mekanisme ini, anda boleh, sebagai contoh, menyingkirkan rekursi (CTE) dalam pertanyaan. Khususnya, pertimbangkan kumpulan yang membentuk pokok menggunakan perhubungan anak/ibu bapa (setiap kumpulan mempunyai pautan kepada induknya):

parent = DATA Group (Group);

Dalam pangkalan data berfungsi, logik rekursi boleh ditentukan seperti berikut:

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;

Sejak untuk fungsi isParent ditanda MATERIALIZED, maka jadual dengan dua kekunci (kumpulan) akan dibuat untuknya, di mana medan isParent akan benar hanya jika kunci pertama ialah anak kepada kunci kedua. Bilangan entri dalam jadual ini akan sama dengan bilangan kumpulan yang didarab dengan purata kedalaman pokok. Jika anda perlu, sebagai contoh, untuk mengira bilangan keturunan kumpulan tertentu, anda boleh menggunakan fungsi ini:

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

Tidak akan ada CTE dalam pertanyaan SQL. Sebaliknya akan ada GROUP BY yang mudah.

Menggunakan mekanisme ini, anda juga boleh menyahnormalkan pangkalan data dengan mudah jika perlu:

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

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

Apabila memanggil fungsi tarikh untuk baris pesanan, medan yang terdapat indeks akan dibaca dari jadual dengan baris pesanan. Apabila tarikh pesanan berubah, sistem itu sendiri secara automatik akan mengira semula tarikh tidak normal dalam baris.

Kelebihan

Untuk apa keseluruhan mekanisme ini? Dalam DBMS klasik, tanpa menulis semula pertanyaan, pembangun atau DBA hanya boleh menukar indeks, menentukan statistik dan memberitahu perancang pertanyaan cara melaksanakannya (dan PETUNJUK hanya tersedia dalam DBMS komersial). Tidak kira seberapa keras mereka mencuba, mereka tidak akan dapat menyelesaikan pertanyaan pertama dalam artikel dalam O (bilangan jabatan) tanpa mengubah pertanyaan atau menambah pencetus. Dalam skim yang dicadangkan, pada peringkat pembangunan anda tidak perlu memikirkan tentang struktur storan data dan pengagregatan yang hendak digunakan. Semua ini boleh ditukar dengan mudah dengan cepat, terus beroperasi.

Dalam amalan ia kelihatan seperti ini. Sesetengah orang membangunkan logik secara langsung berdasarkan tugas yang ada. Mereka tidak memahami algoritma dan kerumitannya, mahupun rancangan pelaksanaan, mahupun jenis cantuman, mahupun komponen teknikal lain. Mereka ini lebih banyak penganalisis perniagaan daripada pemaju. Kemudian, semua ini masuk ke dalam ujian atau operasi. Membolehkan pengelogan pertanyaan yang telah lama dijalankan. Apabila pertanyaan panjang dikesan, maka orang lain (lebih teknikal - pada asasnya DBA) memutuskan untuk mendayakan MATERIALIZED pada beberapa fungsi perantaraan. Ini melambatkan sedikit rakaman (kerana ia memerlukan mengemas kini medan tambahan dalam transaksi). Walau bagaimanapun, bukan sahaja pertanyaan ini dipercepatkan dengan ketara, tetapi juga semua orang lain yang menggunakan fungsi ini. Pada masa yang sama, memutuskan fungsi mana yang hendak direalisasikan agak mudah. Dua parameter utama: bilangan nilai input yang mungkin (ini ialah bilangan rekod dalam jadual yang sepadan), dan kekerapan ia digunakan dalam fungsi lain.

Analog

DBMS komersil moden mempunyai mekanisme yang serupa: MATERIALIZED VIEW dengan FAST REFRESH (Oracle) dan INDEXED VIEW (Microsoft SQL Server). Dalam PostgreSQL, MATERIALIZED VIEW tidak boleh dikemas kini dalam transaksi, tetapi hanya atas permintaan (dan walaupun dengan sekatan yang sangat ketat), jadi kami tidak menganggapnya. Tetapi mereka mempunyai beberapa masalah yang mengehadkan penggunaannya dengan ketara.

Pertama, anda hanya boleh mendayakan pewujudan jika anda telah membuat VIEW biasa. Jika tidak, anda perlu menulis semula permintaan yang tinggal untuk mengakses paparan yang baru dibuat untuk menggunakan pewujudan ini. Atau biarkan segala-galanya seperti sedia ada, tetapi ia akan menjadi sekurang-kurangnya tidak berkesan jika terdapat data tertentu yang telah dikira sebelumnya, tetapi banyak pertanyaan tidak selalu menggunakannya, tetapi mengira semula.

Kedua, mereka mempunyai sejumlah besar sekatan:

Oracle

5.3.8.4 Sekatan Umum pada Muat Semula Cepat

Pertanyaan mentakrifkan pandangan terwujud adalah terhad seperti berikut:

  • Pandangan terwujud tidak boleh mengandungi rujukan kepada ungkapan tidak berulang seperti SYSDATE and ROWNUM.
  • Pandangan yang diwujudkan mestilah tidak mengandungi rujukan kepada RAW or LONG RAW jenis data.
  • Ia tidak boleh mengandungi a SELECT senarai subquery.
  • Ia tidak boleh mengandungi fungsi analisis (contohnya, RANK) di dalam SELECT Klausa.
  • Ia tidak boleh merujuk jadual di mana an XMLIndex indeks ditakrifkan.
  • Ia tidak boleh mengandungi a MODEL Klausa.
  • Ia tidak boleh mengandungi a HAVING klausa dengan subkueri.
  • Ia tidak boleh mengandungi pertanyaan bersarang yang mempunyai ANY, ALL, Atau NOT EXISTS.
  • Ia tidak boleh mengandungi a [START WITH …] CONNECT BY Klausa.
  • Ia tidak boleh mengandungi berbilang jadual butiran di tapak yang berbeza.
  • ON COMMIT pandangan terwujud tidak boleh mempunyai jadual butiran jauh.
  • Paparan terwujud bersarang mesti mempunyai gabungan atau agregat.
  • Pandangan bergabung terwujud dan pandangan agregat terwujud dengan a GROUP BY klausa tidak boleh memilih daripada jadual tersusun indeks.

5.3.8.5 Sekatan ke atas Muat Semula Pantas pada Paparan Terwujud dengan Gabungan Sahaja

Mentakrifkan pertanyaan untuk paparan terwujud dengan gabungan sahaja dan tiada agregat mempunyai sekatan berikut pada muat semula pantas:

  • Semua sekatan daripada Β«Sekatan Umum pada Muat Semula Cepat".
  • Mereka tidak boleh mempunyai GROUP BY klausa atau agregat.
  • Rowid semua jadual dalam FROM senarai mesti muncul dalam SELECT senarai pertanyaan.
  • Log paparan terwujud mesti wujud dengan rowids untuk semua jadual asas dalam FROM senarai pertanyaan.
  • Anda tidak boleh mencipta paparan terwujud yang boleh dimuat semula dengan pantas daripada berbilang jadual dengan cantuman ringkas yang menyertakan lajur jenis objek dalam SELECT kenyataan.

Selain itu, kaedah muat semula yang anda pilih tidak akan cekap secara optimum jika:

  • Pertanyaan penentuan menggunakan sambung luar yang berkelakuan seperti sambung dalam. Jika pertanyaan penentu mengandungi sambungan sedemikian, pertimbangkan untuk menulis semula pertanyaan penentuan untuk mengandungi sambung dalam.
  • . SELECT senarai paparan terwujud mengandungi ungkapan pada lajur daripada berbilang jadual.

5.3.8.6 Sekatan ke atas Muat Semula Pantas pada Paparan Terwujud dengan Agregat

Mentakrifkan pertanyaan untuk paparan terwujud dengan agregat atau gabungan mempunyai sekatan berikut pada muat semula pantas:

Penyegaran pantas disokong untuk kedua-duanya ON COMMIT and ON DEMAND pandangan terwujud, namun sekatan berikut dikenakan:

  • Semua jadual dalam paparan terwujud mesti mempunyai log paparan terwujud, dan log paparan terwujud mesti:
    • Mengandungi semua lajur daripada jadual yang dirujuk dalam paparan terwujud.
    • Nyatakan dengan ROWID and INCLUDING NEW VALUES.
    • nyatakan SEQUENCE klausa jika jadual dijangka mempunyai campuran sisipan/pemuatan langsung, pemadaman dan kemas kini.

  • Hanya SUM, COUNT, AVG, STDDEV, VARIANCE, MIN and MAX disokong untuk penyegaran pantas.
  • COUNT(*) mesti dinyatakan.
  • Fungsi agregat mesti berlaku hanya sebagai bahagian paling luar ungkapan. Iaitu, agregat seperti AVG(AVG(x)) or AVG(x)+ AVG(x) adalah tidak dibenarkan.
  • Bagi setiap agregat seperti AVG(expr), yang sepadan COUNT(expr) mesti hadir. Oracle mengesyorkan itu SUM(expr) dinyatakan.
  • If VARIANCE(expr) or STDDEV(expr) dinyatakan, COUNT(expr) and SUM(expr) mesti dinyatakan. Oracle mengesyorkan itu SUM(expr *expr) dinyatakan.
  • . SELECT lajur dalam pertanyaan penentuan tidak boleh menjadi ungkapan kompleks dengan lajur daripada berbilang jadual asas. Penyelesaian yang mungkin untuk ini adalah dengan menggunakan pandangan terwujud bersarang.
  • . SELECT senarai mesti mengandungi semua GROUP BY lajur.
  • Pandangan terwujud tidak berdasarkan satu atau lebih jadual jauh.
  • Sekiranya anda menggunakan a CHAR jenis data dalam lajur penapis log paparan terwujud, set aksara tapak induk dan paparan terwujud mestilah sama.
  • Jika paparan terwujud mempunyai salah satu daripada yang berikut, maka muat semula pantas hanya disokong pada sisipan DML konvensional dan beban langsung.
    • Pandangan terwujud dengan MIN or MAX agregat
    • Pandangan terwujud yang mempunyai SUM(expr) tetapi tidak COUNT(expr)
    • Pandangan terwujud tanpa COUNT(*)

    Pandangan terwujud sedemikian dipanggil pandangan terwujud sisipan sahaja.

  • Pandangan terwujud dengan MAX or MIN boleh dimuat semula dengan pantas selepas memadam atau mencampurkan kenyataan DML jika ia tidak mempunyai a WHERE Klausa.
    Muat semula pantas maks/min selepas pemadaman atau DML bercampur tidak mempunyai gelagat yang sama seperti kes sisipan sahaja. Ia memadam dan mengira semula nilai maks/min untuk kumpulan yang terjejas. Anda perlu sedar tentang kesan prestasinya.
  • Pandangan terwujud dengan paparan dinamakan atau subquery dalam FROM klausa boleh dimuat semula dengan cepat dengan syarat pandangan boleh digabungkan sepenuhnya. Untuk maklumat tentang pandangan yang akan digabungkan, lihat Rujukan Bahasa SQL Pangkalan Data Oracle.
  • Jika tiada cantuman luar, anda mungkin mempunyai pilihan dan cantuman sewenang-wenangnya dalam WHERE Klausa.
  • Paparan agregat terwujud dengan cantuman luar boleh dimuat semula dengan pantas selepas DML konvensional dan beban langsung, dengan syarat hanya jadual luar telah diubah suai. Selain itu, kekangan unik mesti wujud pada lajur sambung jadual sambung dalam. Jika terdapat cantuman luar, semua cantuman mesti disambungkan oleh ANDs dan mesti menggunakan kesamarataan (=) pengendali.
  • Untuk pandangan terwujud dengan CUBE, ROLLUP, set kumpulan atau gabungannya, sekatan berikut dikenakan:
    • . SELECT senarai harus mengandungi pembeza kumpulan yang boleh menjadi a GROUPING_ID berfungsi pada semua GROUP BY ungkapan atau GROUPING berfungsi satu untuk setiap satu GROUP BY ungkapan. Sebagai contoh, jika GROUP BY klausa pandangan terwujud ialah "GROUP BY CUBE(a, b)", kemudian SELECT senarai hendaklah mengandungi sama ada "GROUPING_ID(a, b)Β» atau Β«GROUPING(a) AND GROUPING(b)Β» untuk paparan yang diwujudkan supaya boleh dimuat semula dengan pantas.
    • GROUP BY tidak seharusnya menghasilkan sebarang kumpulan pendua. Sebagai contoh, "GROUP BY a, ROLLUP(a, b)" tidak boleh dimuat semula dengan pantas kerana ia menghasilkan kumpulan pendua "(a), (a, b), AND (a)".

5.3.8.7 Sekatan ke atas Muat Semula Pantas pada Paparan Terwujud dengan UNION ALL

Pandangan terwujud dengan UNION ALL set operator menyokong REFRESH FAST pilihan jika syarat berikut dipenuhi:

  • Pertanyaan yang menentukan mesti mempunyai UNION ALL operator di peringkat atasan.

    . UNION ALL operator tidak boleh dibenamkan di dalam subkueri, dengan satu pengecualian: The UNION ALL boleh berada dalam subquery dalam FROM klausa dengan syarat pertanyaan yang menentukan adalah dalam bentuk SELECT * FROM (lihat atau subquery dengan UNION ALL) seperti contoh berikut:

    CIPTA VIEW view_with_unionall AS (PILIH c.rowid crid, c.cust_id, 2 umarker DARI pelanggan c WHERE c.cust_last_name = 'Smith' UNION SEMUA PILIH c.rowid crid, c.cust_id, 3 umarker DARI pelanggan c WHERE c.cust_last_name 'Jones'); CIPTA PANDANGAN TERBENTUK unionall_inside_view_mv SEMAKAN CEPAT ATAS PERMINTAAN SEBAGAI PILIHAN * DARI view_with_unionall;
    

    Perhatikan bahawa pandangan view_with_unionall memenuhi keperluan untuk penyegaran pantas.

  • Setiap blok pertanyaan dalam UNION ALL pertanyaan mesti memenuhi keperluan paparan terwujud yang boleh dimuat semula dengan pantas dengan agregat atau paparan terwujud yang boleh dimuat semula pantas dengan gabungan.

    Log paparan terwujud yang sesuai mesti dibuat pada jadual seperti yang diperlukan untuk jenis paparan terwujud yang boleh dimuat semula pantas yang sepadan.
    Ambil perhatian bahawa Pangkalan Data Oracle juga membenarkan kes khas paparan terwujud jadual tunggal dengan gabungan hanya dengan syarat ROWID lajur telah dimasukkan ke dalam SELECT senarai dan dalam log paparan terwujud. Ini ditunjukkan dalam pertanyaan penentu pandangan view_with_unionall.

  • . SELECT senarai setiap pertanyaan mesti mengandungi a UNION ALL penanda, dan UNION ALL lajur mesti mempunyai nilai angka atau rentetan malar yang berbeza dalam setiap lajur UNION ALL cawangan. Selanjutnya, lajur penanda mesti muncul dalam kedudukan ordinal yang sama dalam SELECT senarai setiap blok pertanyaan. Lihat"KESATUAN SEMUA Penanda dan Tulis Semula PertanyaanΒ» untuk maklumat lanjut mengenai UNION ALL penanda.
  • Sesetengah ciri seperti sambung luar, pertanyaan paparan terwujud agregat sisip sahaja dan jadual jauh tidak disokong untuk paparan terwujud dengan UNION ALL. Walau bagaimanapun, ambil perhatian bahawa pandangan terwujud yang digunakan dalam replikasi, yang tidak mengandungi cantuman atau agregat, boleh dimuat semula dengan pantas apabila UNION ALL atau meja jauh digunakan.
  • Parameter permulaan keserasian mesti ditetapkan kepada 9.2.0 atau lebih tinggi untuk mencipta paparan terwujud yang boleh dimuat semula dengan pantas dengan UNION ALL.

Saya tidak mahu menyinggung perasaan peminat Oracle, tetapi berdasarkan senarai sekatan mereka, nampaknya mekanisme ini ditulis bukan dalam kes umum, menggunakan beberapa jenis model, tetapi oleh beribu-ribu orang India, di mana semua orang diberi peluang untuk menulis cabang mereka sendiri, dan masing-masing melakukan apa yang dia mampu. Menggunakan mekanisme ini untuk logik sebenar adalah seperti berjalan melalui medan ranjau. Anda boleh mendapatkan lombong pada bila-bila masa dengan memukul salah satu sekatan yang tidak jelas. Cara ia berfungsi juga merupakan soalan yang berasingan, tetapi ia di luar skop artikel ini.

Microsoft SQL Server

Keperluan tambahan

Sebagai tambahan kepada pilihan SET dan keperluan fungsi deterministik, keperluan berikut mesti dipenuhi:

  • Pengguna yang melaksanakan CREATE INDEX mestilah pemilik pandangan.
  • Apabila anda mencipta indeks, IGNORE_DUP_KEY pilihan mesti ditetapkan kepada MATI (tetapan lalai).
  • Jadual mesti dirujuk dengan nama dua bahagian, skim.nama jadual dalam definisi pandangan.
  • Fungsi yang ditentukan pengguna yang dirujuk dalam paparan mesti dibuat dengan menggunakan WITH SCHEMABINDING pilihan.
  • Mana-mana fungsi yang ditentukan pengguna yang dirujuk dalam paparan mesti dirujuk dengan nama dua bahagian, ..
  • Sifat capaian data bagi fungsi yang ditentukan pengguna mestilah NO SQL, dan sifat akses luaran mestilah NO.
  • Fungsi masa jalan bahasa biasa (CLR) boleh muncul dalam senarai pilihan paparan, tetapi tidak boleh menjadi sebahagian daripada definisi kunci indeks berkelompok. Fungsi CLR tidak boleh muncul dalam klausa WHERE pandangan atau klausa ON operasi JOIN dalam paparan.
  • Fungsi dan kaedah CLR jenis yang ditentukan pengguna CLR yang digunakan dalam definisi paparan mesti mempunyai sifat yang ditetapkan seperti yang ditunjukkan dalam jadual berikut.

    Harta
    Nota

    DETERMINISTIK = BENAR
    Mesti diisytiharkan secara eksplisit sebagai atribut kaedah Microsoft .NET Framework.

    TEPAT = BENAR
    Mesti diisytiharkan secara eksplisit sebagai atribut kaedah .NET Framework.

    AKSES DATA = TIADA SQL
    Ditentukan dengan menetapkan atribut DataAccess kepada DataAccessKind.None dan atribut SystemDataAccess kepada SystemDataAccessKind.None.

    AKSES LUAR = NO
    Harta ini lalai kepada TIDAK untuk rutin CLR.

  • Pandangan mesti dibuat dengan menggunakan WITH SCHEMABINDING pilihan.
  • Paparan mesti merujuk hanya jadual asas yang berada dalam pangkalan data yang sama dengan paparan. Pandangan tidak boleh merujuk pandangan lain.
  • Pernyataan SELECT dalam definisi paparan tidak boleh mengandungi elemen Transact-SQL berikut:

    COUNT
    fungsi ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, DAN OPENXML)
    OUTER menyertai (LEFT, RIGHT, Atau FULL)

    Jadual terbitan (ditakrifkan dengan menyatakan a SELECT penyataan di FROM fasal)
    Bergabung sendiri
    Menentukan lajur dengan menggunakan SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARP, Atau AVG
    Ungkapan jadual biasa (CTE)

    terapung1, teks, nteks, gambar, XML, Atau aliran fail lajur
    Subkueri
    OVER klausa, yang merangkumi fungsi tetingkap kedudukan atau agregat

    Predikat teks penuh (CONTAINS, FREETEXT)
    SUM fungsi yang merujuk kepada ungkapan nullable
    ORDER BY

    Fungsi agregat yang ditentukan pengguna CLR
    TOP
    CUBE, ROLLUP, Atau GROUPING SETS pengendali

    MIN, MAX
    UNION, EXCEPT, Atau INTERSECT pengendali
    TABLESAMPLE

    Pemboleh ubah jadual
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Set lajur jarang
    Sebaris (TVF) atau fungsi bernilai jadual berbilang penyata (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Pandangan diindeks boleh mengandungi terapung lajur; walau bagaimanapun, lajur tersebut tidak boleh disertakan dalam kunci indeks berkelompok.

  • If GROUP BY hadir, definisi VIEW mesti mengandungi COUNT_BIG(*) dan tidak boleh mengandungi HAVING. Ini GROUP BY sekatan hanya terpakai pada definisi paparan diindeks. Pertanyaan boleh menggunakan paparan diindeks dalam pelan pelaksanaannya walaupun ia tidak memenuhinya GROUP BY sekatan.
  • Jika definisi paparan mengandungi a GROUP BY klausa, kunci indeks berkelompok unik boleh merujuk hanya lajur yang dinyatakan dalam GROUP BY Klausa.

Jelas di sini bahawa orang India tidak terlibat, kerana mereka memutuskan untuk melakukannya mengikut skema "kami akan melakukan sedikit, tetapi baik." Iaitu, mereka mempunyai lebih banyak lombong di lapangan, tetapi lokasi mereka lebih telus. Perkara yang paling mengecewakan ialah had ini:

Paparan mesti merujuk hanya jadual asas yang berada dalam pangkalan data yang sama dengan paparan. Pandangan tidak boleh merujuk pandangan lain.

Dalam istilah kami, ini bermakna fungsi tidak boleh mengakses fungsi terwujud lain. Ini mengurangkan semua ideologi dalam tunas.
Selain itu, had ini (dan seterusnya dalam teks) sangat mengurangkan kes penggunaan:

Pernyataan SELECT dalam definisi paparan tidak boleh mengandungi elemen Transact-SQL berikut:

COUNT
fungsi ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, DAN OPENXML)
OUTER menyertai (LEFT, RIGHT, Atau FULL)

Jadual terbitan (ditakrifkan dengan menyatakan a SELECT penyataan di FROM fasal)
Bergabung sendiri
Menentukan lajur dengan menggunakan SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARP, Atau AVG
Ungkapan jadual biasa (CTE)

terapung1, teks, nteks, gambar, XML, Atau aliran fail lajur
Subkueri
OVER klausa, yang merangkumi fungsi tetingkap kedudukan atau agregat

Predikat teks penuh (CONTAINS, FREETEXT)
SUM fungsi yang merujuk kepada ungkapan nullable
ORDER BY

Fungsi agregat yang ditentukan pengguna CLR
TOP
CUBE, ROLLUP, Atau GROUPING SETS pengendali

MIN, MAX
UNION, EXCEPT, Atau INTERSECT pengendali
TABLESAMPLE

Pemboleh ubah jadual
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Set lajur jarang
Sebaris (TVF) atau fungsi bernilai jadual berbilang penyata (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOIN, UNION, ORDER BY dan lain-lain adalah dilarang. Mungkin lebih mudah untuk menentukan apa yang boleh digunakan daripada apa yang tidak boleh digunakan. Senarai itu mungkin lebih pendek.

Untuk meringkaskan: satu set sekatan yang besar dalam setiap (mari ambil perhatian komersial) DBMS vs tiada (dengan pengecualian satu logik, bukan teknikal) dalam teknologi LGPL. Walau bagaimanapun, perlu diingatkan bahawa melaksanakan mekanisme ini dalam logik hubungan agak lebih sukar daripada dalam logik berfungsi yang diterangkan.

РСализация

Bagaimana ia berfungsi? PostgreSQL digunakan sebagai "mesin maya". Terdapat algoritma kompleks di dalamnya yang membina pertanyaan. Di sini kod sumber. Dan bukan hanya satu set heuristik yang besar dengan sekumpulan ifs. Jadi, jika anda mempunyai beberapa bulan untuk belajar, anda boleh cuba memahami seni bina.

Adakah ia berfungsi dengan berkesan? Agak berkesan. Malangnya, ini sukar untuk dibuktikan. Saya hanya boleh mengatakan bahawa jika anda menganggap beribu-ribu pertanyaan yang wujud dalam aplikasi besar, maka secara purata ia lebih cekap daripada pemaju yang baik. Pengaturcara SQL yang cemerlang boleh menulis sebarang pertanyaan dengan lebih cekap, tetapi dengan seribu pertanyaan dia tidak akan mempunyai motivasi atau masa untuk melakukannya. Satu-satunya perkara yang boleh saya sebutkan sekarang sebagai bukti keberkesanan ialah beberapa projek sedang bekerja pada platform yang dibina pada DBMS ini sistem ERP, yang mempunyai beribu-ribu fungsi MATERIALIZED berbeza, dengan beribu-ribu pengguna dan pangkalan data terabait dengan ratusan juta rekod berjalan pada pelayan dua pemproses biasa. Walau bagaimanapun, sesiapa sahaja boleh menyemak/menafikan keberkesanan dengan memuat turun platform dan PostgreSQL, menghidupkan log pertanyaan SQL dan cuba menukar logik dan data di sana.

Dalam artikel berikut, saya juga akan bercakap tentang cara anda boleh menetapkan sekatan pada fungsi, bekerja dengan sesi perubahan dan banyak lagi.

Sumber: www.habr.com

Tambah komen