Өгөгдлийн санд бичих, унших үйлдлийг тэнцвэржүүлэх

Өгөгдлийн санд бичих, унших үйлдлийг тэнцвэржүүлэх
Өмнөх хэсэгт нийтлэл Би харилцааны өгөгдлийн сан шиг хүснэгт, талбар гэхээсээ илүү функцууд дээр суурилсан мэдээллийн сангийн тухай ойлголт, хэрэгжилтийг тайлбарласан. Энэ аргын сонгодог аргаас давуу талыг харуулсан олон жишээг өгсөн. Олон хүмүүс тэднийг хангалттай үнэмшилгүй гэж үзсэн.

Энэ нийтлэлд би энэ ойлголт нь үйлдлийн логикийг өөрчлөхгүйгээр мэдээллийн санд бичих, уншихыг хурдан, хялбар тэнцвэржүүлэх боломжийг танд үзүүлэх болно. Үүнтэй төстэй функцийг орчин үеийн арилжааны DBMS-д (ялангуяа 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);

Аливаа DBMS-д энэ хүсэлтийг гүйцэтгэх нарийн төвөгтэй байдал нь үүнтэй тэнцүү байх болно O (ажилчдын тоо)Учир нь энэ тооцоонд ажилчдын хүснэгтийг бүхэлд нь сканнердаж, дараа нь хэлтэсээр нь бүлэглэх шаардлагатай. Сонгосон төлөвлөгөөнөөс хамааран жижиг (тэнхимээс илүү олон ажилтан байгаа гэдэгт бид итгэдэг) нэмэгдэл байх болно. O(ажилчдын тоо бүртгэл) буюу O (тэнхимийн тоо) бүлэглэх гэх мэт.

Гүйцэтгэлийн нэмэлт зардал нь өөр өөр DBMS-д өөр байж болох ч нарийн төвөгтэй байдал нь ямар ч байдлаар өөрчлөгдөхгүй нь ойлгомжтой.

Санал болгож буй хэрэгжүүлэх явцад функциональ DBMS нь хэлтэст шаардлагатай утгыг тооцоолох нэг дэд асуулга үүсгэж, дараа нь нэрийг авахын тулд хэлтсийн хүснэгттэй НЭГДСЭН хийгдэнэ. Гэсэн хэдий ч функц бүрийн хувьд зарлахдаа тусгай МАТЕРИАЛЖУУЛСАН маркер тавих боломжтой. Систем нь ийм функц бүрт тохирох талбарыг автоматаар үүсгэх болно. Функцийн утгыг өөрчлөх үед тухайн гүйлгээнд талбарын утга мөн өөрчлөгдөнө. Энэ функцэд хандах үед урьдчилан тооцоолсон талбарт хандах болно.

Ялангуяа, хэрэв та функцүүдэд MATERIALIZED тохируулсан бол ажилчдын тоо и цалингийн нийлбэр, дараа нь хоёр талбарыг хэлтсийн жагсаалттай хүснэгтэд нэмж, ажилчдын тоо, нийт цалинг хадгалах болно. Ажилчид, тэдний цалин эсвэл хэлтсийн харьяалалд өөрчлөлт орох бүрд систем нь эдгээр талбаруудын утгыг автоматаар өөрчилдөг. Дээрх асуулга нь эдгээр талбарт шууд хандах бөгөөд үүнийг гүйцэтгэх болно O (тэнхимийн тоо).

Ямар хязгаарлалтууд байдаг вэ? Зөвхөн нэг зүйл: ийм функц нь түүний утгыг тодорхойлсон хязгаарлагдмал тооны оролтын утгатай байх ёстой. Үгүй бол хязгааргүй тооны мөртэй хүснэгт байж болохгүй тул бүх утгыг нь хадгалдаг хүснэгтийг бүтээх боломжгүй болно.

Жишээ нь:

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

Энэ функц нь N-ийн хязгааргүй тооны утгуудын хувьд тодорхойлогддог (жишээлбэл, ямар ч сөрөг утга тохиромжтой). Иймд та үүн дээр МАТЕРИАЛЖУУЛСАН тавьж болохгүй. Тиймээс энэ бол техникийн хязгаарлалт биш (өөрөөр хэлбэл бид үүнийг хэрэгжүүлж чадаагүйгээс биш) логик хязгаарлалт юм. Үгүй бол ямар ч хязгаарлалт байхгүй. Та бүлэглэх, эрэмбэлэх, БА болон OR, 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;

Функцийг дуудах үед он сар өдөр захиалгын шугамын хувьд индекс байгаа талбарыг захиалгын мөр бүхий хүснэгтээс унших болно. Захиалгын огноо өөрчлөгдөхөд систем өөрөө шугам дахь хэвийн бус огноог автоматаар дахин тооцоолох болно.

Ашиг тус

Энэ бүх механизм юунд зориулагдсан бэ? Сонгодог DBMS-д асуултуудыг дахин бичихгүйгээр хөгжүүлэгч эсвэл DBA нь зөвхөн индексийг өөрчлөх, статистикийг тодорхойлох, асуулга төлөвлөгчид тэдгээрийг хэрхэн гүйцэтгэхийг хэлж өгөх боломжтой (мөн ЗӨВЛӨГӨӨ нь зөвхөн арилжааны DBMS-д байдаг). Хичнээн хичээсэн ч тэд нийтлэл дэх эхний асуултыг гүйцээж чадахгүй O (тэнхимийн тоо) асуулгыг өөрчлөх эсвэл триггер нэмэхгүйгээр. Санал болгож буй схемд, боловсруулах шатанд та өгөгдөл хадгалах бүтэц, ямар нэгтгэлийг ашиглах талаар бодох шаардлагагүй болно. Энэ бүгдийг шууд үйл ажиллагааны явцад амархан өөрчлөх боломжтой.

Практик дээр энэ нь иймэрхүү харагдаж байна. Зарим хүмүүс даалгавар дээрээ үндэслэн логикийг шууд хөгжүүлдэг. Тэд алгоритм, тэдгээрийн нарийн төвөгтэй байдал, гүйцэтгэлийн төлөвлөгөө, холболтын төрлүүд болон бусад техникийн бүрэлдэхүүн хэсгүүдийг ойлгодоггүй. Эдгээр хүмүүс хөгжүүлэгчид гэхээсээ илүү бизнесийн шинжээчид байдаг. Дараа нь энэ бүхэн туршилт эсвэл ажиллагаанд ордог. Удаан ажиллаж буй асуулгын бүртгэлийг идэвхжүүлдэг. Урт хайлт илэрсэн үед бусад хүмүүс (илүү техникийн - үндсэндээ DBA) зарим завсрын функц дээр MATERIALIZED-г идэвхжүүлэхээр шийддэг. Энэ нь бичлэгийг бага зэрэг удаашруулдаг (учир нь энэ нь гүйлгээний нэмэлт талбарыг шинэчлэх шаардлагатай болдог). Гэсэн хэдий ч зөвхөн энэ асуулга төдийгүй энэ функцийг ашигладаг бусад бүх хүсэлтийг хурдасгадаг. Үүний зэрэгцээ аль функцийг хэрэгжүүлэхийг шийдэх нь харьцангуй хялбар байдаг. Хоёр үндсэн параметр: оролтын боломжит утгуудын тоо (энэ нь харгалзах хүснэгтэд хичнээн бичлэг байх болно), бусад функцүүдэд хэр олон удаа ашиглагддаг.

Аналоги

Орчин үеийн арилжааны DBMS нь ижил төстэй механизмтай байдаг: FAST REFRESH (Oracle) бүхий MATRIALIZED VIEW болон INDEXED VIEW (Microsoft SQL Server). PostgreSQL-д MATERIALIZED VIEW-ийг гүйлгээнд шинэчлэх боломжгүй, зөвхөн хүсэлтийн дагуу (мөн маш хатуу хязгаарлалттай байсан ч) бид үүнийг авч үзэхгүй. Гэхдээ тэдний хэрэглээг ихээхэн хязгаарладаг хэд хэдэн асуудал байдаг.

Нэгдүгээрт, та ердийн 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 материалжуулсан харагдац нь алсын дэлгэрэнгүй хүснэгттэй байж болохгүй.
  • Оруулсан материалжуулсан харагдац нь нэгдэх эсвэл нэгтгэсэн байх ёстой.
  • Материалжуулсан нэгдэх харагдац болон материалжуулсан нэгтгэсэн харагдацыг a 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 мэдээллийн сангийн 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) дараах жишээн дээрх шиг:

    CREATE VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM customer 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 ХЭРЭГЛЭЭД ШУУРХАЙ СЭРГЭЭГЭЭР СОНГОХ БОЛОМЖТОЙ * 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 Marker болон Query дахин бичих» талаар дэлгэрэнгүй мэдээллийг авна уу UNION ALL тэмдэглэгээ.
  • Гаднах холболтууд, зөвхөн оруулахын тулд нэгтгэсэн материалжуулсан харагдацын асуулга, алсын хүснэгт зэрэг зарим функцууд нь материалжуулсан харагдацыг дэмждэггүй. UNION ALL. Гэсэн хэдий ч нэгдэл эсвэл нэгтгэл агуулаагүй хуулбарлахад ашигласан материалжуулсан харагдацыг хурдан шинэчлэх боломжтой гэдгийг анхаарна уу. UNION ALL эсвэл алсын хүснэгтүүдийг ашигладаг.
  • Тохиромжтой байдлыг эхлүүлэх параметрийг 9.2.0 буюу түүнээс дээш болгож тохируулсан байх ёстой. UNION ALL.

Би Oracle-ийн шүтэн бишрэгчдийг гомдоохыг хүсэхгүй байна, гэхдээ тэдний хязгаарлалтын жагсаалтаас харахад энэ механизмыг ерөнхийд нь биш, ямар нэгэн загвар ашиглан бичсэн байсан юм шиг санагдаж байна, гэхдээ хүн бүрт ийм боломж олгосон олон мянган индианчууд. Өөрийнхөө салбарыг бичээд, тус бүр нь чадах бүхнээ хийсэн. Энэ механизмыг бодит логикоор ашиглах нь уурхайн талбай дундуур алхахтай адил юм. Тодорхой бус хязгаарлалтын аль нэгийг дарснаар та хүссэн үедээ уурхай авч болно. Энэ нь хэрхэн ажилладаг нь бас тусдаа асуулт боловч энэ нийтлэлийн хамрах хүрээнээс гадуур юм.

Microsoft SQL Server

Нэмэлт шаардлага

SET сонголтууд болон детерминистик функцийн шаардлагуудаас гадна дараахь шаардлагыг хангасан байх ёстой.

  • Гүйцэтгэх хэрэглэгч CREATE INDEX үзвэрийн эзэн байх ёстой.
  • Та индексийг үүсгэх үед IGNORE_DUP_KEY сонголтыг OFF (үндсэн тохиргоо) болгож тохируулах ёстой.
  • Хүснэгтүүдийг хоёр хэсгээс бүрдсэн нэрээр иш татсан байх ёстой. схем.ширээний нэр харах тодорхойлолтод.
  • Харагдах байдал дээр иш татсан хэрэглэгчийн тодорхойлсон функцуудыг ашиглан үүсгэгдсэн байх ёстой WITH SCHEMABINDING сонголт.
  • Харагдахад иш татсан хэрэглэгчийн тодорхойлсон аливаа функцийг хоёр хэсгээс бүрдсэн нэрээр лавлах ёстой. ..
  • Хэрэглэгчийн тодорхойлсон функцийн өгөгдөлд хандах шинж чанар нь байх ёстой NO SQL, мөн гадаад хандалтын өмч байх ёстой NO.
  • Нийтлэг хэлний ажиллах цагийн (CLR) функцууд нь харагдацын сонгох жагсаалтад гарч ирж болох боловч кластерийн индексийн түлхүүрийн тодорхойлолтын нэг хэсэг байж болохгүй. CLR функцууд нь харагдацын WHERE заалт эсвэл JOIN үйлдлийн ON заалтад харагдах боломжгүй.
  • Харах тодорхойлолтод ашигласан CLR хэрэглэгчийн тодорхойлсон төрлүүдийн CLR функцууд болон аргууд нь дараах хүснэгтэд үзүүлсэн шинж чанаруудтай байх ёстой.

    Эд хөрөнгийн
    Тайлбар

    DETERMINISTIC = ҮНЭН
    Microsoft .NET Framework аргын шинж чанар гэж тодорхой зарласан байх ёстой.

    НАРИЙН = ҮНЭН
    .NET Framework аргын шинж чанар гэж тодорхой зарласан байх ёстой.

    ӨГӨГДӨЛ ХАНДАХ = SQL БАЙХГҮЙ
    DataAccess атрибутыг DataAccessKind.None, SystemDataAccess шинж чанарыг SystemDataAccessKind.None гэж тохируулснаар тодорхойлогддог.

    ГАДААД ХАНДАХ = ҮГҮЙ
    Энэ шинж чанар нь CLR горимын хувьд өгөгдмөл NO гэсэн утгатай.

  • -г ашиглан харагдац үүсгэх ёстой 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

    Сийрэг баганын багц
    Inline (TVF) эсвэл олон мэдэгдлийн хүснэгтийн үнэ цэнэтэй функцууд (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Индексжүүлсэн харагдац нь агуулж болно ° в ° гч багана; Гэсэн хэдий ч ийм багануудыг кластерийн индексийн түлхүүрт оруулах боломжгүй.

  • If GROUP BY байгаа бол VIEW тодорхойлолтыг агуулсан байх ёстой COUNT_BIG(*) мөн агуулаагүй байх ёстой HAVING. Эдгээр нь GROUP BY хязгаарлалт нь зөвхөн индексжүүлсэн харах тодорхойлолтод хамаарна. Асуулга нь эдгээрийг хангахгүй байсан ч гүйцэтгэлийн төлөвлөгөөндөө индексжүүлсэн харагдацыг ашиглаж болно GROUP BY хязгаарлалт.
  • Хэрэв харах тодорхойлолт нь a 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

Сийрэг баганын багц
Inline (TVF) эсвэл олон мэдэгдлийн хүснэгтийн үнэ цэнэтэй функцууд (MSTVF)
OFFSET

CHECKSUM_AGG

ГАДААД НЭГДСЭН, НЭГДСЭН, ORDER BY болон бусад зүйлийг хориглоно. Юуг ашиглах боломжгүйг биш харин юуг ашиглаж болохыг тодорхойлох нь илүү хялбар байсан байх. Жагсаалт магадгүй хамаагүй богино байх болно.

Дүгнэж хэлэхэд: LGPL технологийн бүх (арилжааны) DBMS-ийн эсрэг (техникийн бус логик нэгийг эс тооцвол) асар том хязгаарлалтууд байдаг. Гэсэн хэдий ч энэ механизмыг харилцааны логикт хэрэгжүүлэх нь тайлбарласан функциональ логикоос арай илүү хэцүү гэдгийг тэмдэглэх нь зүйтэй.

Реализация

Хэрхэн ажилладаг? PostgreSQL-ийг "виртуал машин" болгон ашигладаг. Дотор нь асуулга үүсгэдэг нарийн төвөгтэй алгоритм байдаг. Энд эх сурвалж. Зөвхөн олон тооны ifs бүхий эвристикийн том багц байдаггүй. Тиймээс, хэрэв танд хоёр сар суралцах хугацаа байгаа бол архитектурыг ойлгохыг оролдож болно.

Энэ нь үр дүнтэй ажилладаг уу? Нэлээд үр дүнтэй. Харамсалтай нь үүнийг батлахад хэцүү. Хэрэв та том програмуудад байдаг олон мянган асуултуудыг авч үзвэл тэдгээр нь сайн хөгжүүлэгчийнхээс илүү үр дүнтэй байдаг гэж би хэлж чадна. Маш сайн SQL програмист ямар ч асуултыг илүү үр дүнтэй бичиж чаддаг ч мянган асуулттай бол түүнд үүнийг хийх хүсэл эрмэлзэл, цаг хугацаа байхгүй болно. Одоо миний үр дүнтэй байдлын нотолгоо болгож чадах цорын ганц зүйл бол энэ DBMS дээр суурилсан платформ дээр хэд хэдэн төсөл ажиллаж байгаа явдал юм. ERP системүүд, мянга мянган хэрэглэгчтэй, олон зуун сая бичлэг бүхий терабайт мэдээллийн сантай, олон мянган янз бүрийн МАТЕРИАЛЖУУЛСАН функцтэй, энгийн хоёр процессортой сервер дээр ажилладаг. Гэсэн хэдий ч хэн ч татаж авах замаар үр нөлөөг шалгах/няцаах боломжтой платформ болон PostgreSQL, идэвхжсэн SQL асуулгыг бүртгэж, тэнд байгаа логик болон өгөгдлийг өөрчлөхийг оролдож байна.

Дараах нийтлэлүүдэд би функцэд хэрхэн хязгаарлалт тавих, өөрчлөлтийн сессүүдтэй ажиллах болон бусад олон зүйлийн талаар ярих болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх