
در قبلی من مفهوم و پیاده سازی پایگاه داده ای را که بر اساس توابع ساخته شده است، به جای جداول و فیلدها در پایگاه داده های رابطه ای توضیح دادم. مثالهای زیادی ارائه میکند که مزایای این رویکرد را نسبت به روش کلاسیک نشان میدهد. بسیاری آنها را به اندازه کافی قانع کننده نمی دانستند.
در این مقاله، من نشان خواهم داد که چگونه این مفهوم به شما اجازه می دهد تا به سرعت و به راحتی بین نوشته ها و خواندن ها در پایگاه داده بدون هیچ تغییری در منطق عملیات، تعادل برقرار کنید. عملکرد مشابهی سعی شده است در DBMS های تجاری مدرن (به ویژه Oracle و Microsoft SQL Server) پیاده سازی شود. در پایان مقاله نشان خواهم داد که کاری که آنها انجام دادند، به بیان ملایم، خیلی خوب کار نکرد.
شرح
مانند قبل، برای درک بهتر، شرح را با مثال شروع می کنم. فرض کنید باید منطقی را پیاده سازی کنیم که فهرستی از بخش ها را با تعداد کارمندان و کل حقوق آنها برمی گرداند.
در یک پایگاه داده تابعی به شکل زیر است:
CLASS Department ‘Отдел’;
name ‘Наименование’ = DATA STRING[100] (Department);
کارمند کلاس «کارمند»؛
department 'Department' = داده های Department (کارمند)؛
salary 'حقوق' = داده عددی[10,2،XNUMX] (کارمند)؛
تعداد کارمندان (دپارتمان d) = countEmployees
جمع گروه ۱ اگر دپارتمان (کارمند e) = d باشد؛
salarySum 'کل حقوق' (دپارتمان d) =
مجموع حقوق گروه (کارمند e) اگر دپارتمان (e) = d;
SELECT name(Department d), countEmployees(d), salarySum(d);
پیچیدگی اجرای این پرس و جو در هر DBMS معادل خواهد بود O (تعداد کارمندان)زیرا این محاسبه مستلزم اسکن کل جدول کارکنان و سپس گروه بندی آنها بر اساس بخش است. همچنین بسته به طرح انتخابی، برخی مکمل های کوچک (ما معتقدیم تعداد کارکنان بسیار بیشتر از بخش ها است) وجود خواهد داشت O (تعداد ثبت نام کارمندان) یا O (تعداد بخش ها) برای گروه بندی و غیره
واضح است که سربار اجرا ممکن است در DBMS های مختلف متفاوت باشد، اما پیچیدگی آن به هیچ وجه تغییر نخواهد کرد.
در پیادهسازی پیشنهادی، DBMS عملکردی یک زیرپرس و جو ایجاد میکند که مقادیر مورد نیاز بخش را محاسبه میکند و سپس برای به دست آوردن نام، یک JOIN با جدول بخش ایجاد میکند. با این حال، برای هر تابع، هنگام اعلام، می توان یک نشانگر MATERIALIZED ویژه تنظیم کرد. سیستم به طور خودکار یک فیلد مربوطه را برای هر یک از این عملکردها ایجاد می کند. هنگام تغییر مقدار یک تابع، مقدار فیلد نیز در همان تراکنش تغییر می کند. هنگام دسترسی به این تابع، فیلد از پیش محاسبه شده قابل دسترسی خواهد بود.
به ویژه، اگر MATERIALIZED را برای توابع تنظیم کنید شمارش کارمندان и مجموع حقوق، سپس دو فیلد با لیست بخش ها به جدول اضافه می شود که تعداد کارمندان و کل حقوق آنها ذخیره می شود. هر زمان که تغییری در کارمندان، حقوق آنها یا وابستگیهای بخشها ایجاد شود، سیستم بهطور خودکار مقادیر این فیلدها را تغییر میدهد. کوئری فوق مستقیماً به این فیلدها دسترسی خواهد داشت و در آن اجرا می شود O (تعداد بخش ها).
محدودیت ها چیست؟ فقط یک چیز: چنین تابعی باید دارای تعداد محدودی از مقادیر ورودی باشد که مقدار آن برای آن تعریف شده است. در غیر این صورت، ساخت جدولی که تمام مقادیر آن را ذخیره می کند غیرممکن خواهد بود، زیرا جدولی با تعداد ردیف های نامحدود وجود ندارد.
به عنوان مثال:
employeesCount ‘Количество сотрудников с зарплатой > N’ (Department d, NUMERIC[10,2] N) =
GROUP SUM salary(Employee e) IF department(e) = d AND salary(e) > N;
این تابع برای تعداد نامتناهی از مقادیر N تعریف شده است (به عنوان مثال، هر مقدار منفی مناسب است). بنابراین، شما نمی توانید MATERIALIZED را روی آن قرار دهید. بنابراین این یک محدودیت منطقی است، نه فنی (یعنی نه به این دلیل که ما نتوانستیم آن را اجرا کنیم). در غیر این صورت محدودیتی وجود ندارد. می توانید از گروه بندی، مرتب سازی، AND و 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;
از آنجایی که برای عملکرد isParent MATERIALIZED مشخص شده است، سپس جدولی با دو کلید (گروه) برای آن ایجاد می شود که در آن فیلد isParent تنها در صورتی صادق خواهد بود که اولین کلید فرزند کلید دوم باشد. تعداد ورودی های این جدول برابر با تعداد گروه ها در عمق متوسط درخت خواهد بود. اگر به عنوان مثال نیاز به شمارش تعداد فرزندان یک گروه خاص دارید، می توانید از این تابع استفاده کنید:
childrenCount (Group g) = GROUP SUM 1 IF isParent(Group child, g);
CTE در پرس و جوی SQL وجود نخواهد داشت. در عوض یک GROUP BY ساده وجود خواهد داشت.
با استفاده از این مکانیسم، می توانید به راحتی پایگاه داده را در صورت لزوم غیرعادی کنید:
CLASS Order 'Заказ';
date 'Дата' = DATA DATE (Order);
کلاس OrderDetail 'خط سفارش';
order 'Order' = DATA Order (OrderDetail);
تاریخ 'تاریخ' (OrderDetail d) = date(order(d)) مادیسازی شده، اندیسگذاری شده؛
هنگام فراخوانی یک تابع تاریخ برای خط سفارش، فیلدی که برای آن شاخص وجود دارد از جدول با خطوط سفارش خوانده می شود. هنگامی که تاریخ سفارش تغییر می کند، خود سیستم به طور خودکار تاریخ غیرعادی شده در خط را دوباره محاسبه می کند.
مزایا
کل این مکانیسم برای چیست؟ در DBMS های کلاسیک، بدون بازنویسی پرس و جوها، یک توسعه دهنده یا DBA فقط می تواند ایندکس ها را تغییر دهد، آمار را تعیین کند و به برنامه ریز پرس و جو بگوید چگونه آنها را اجرا کند (و HINT ها فقط در DBMS های تجاری موجود هستند). هر چقدر هم که تلاش کنند، نمی توانند اولین پرس و جو در مقاله را تکمیل کنند O (تعداد بخش ها) بدون تغییر پرس و جو یا اضافه کردن محرک. در طرح پیشنهادی، در مرحله توسعه، لازم نیست به ساختار ذخیرهسازی دادهها و تجمیعهایی که باید استفاده کنید فکر کنید. همه اینها را می توان به راحتی در پرواز، به طور مستقیم در عملیات تغییر داد.
در عمل به این شکل به نظر می رسد. برخی افراد منطق را مستقیماً بر اساس وظیفه ای که در دست دارند توسعه می دهند. آنها نه الگوریتمها و پیچیدگیهای آنها را درک میکنند، نه برنامههای اجرایی، نه انواع اتصالها و نه هیچ جزء فنی دیگری را. این افراد بیشتر تحلیلگر کسب و کار هستند تا توسعه دهندگان. سپس، همه اینها وارد آزمایش یا عملیات می شود. ثبت پرس و جوهای طولانی مدت را فعال می کند. هنگامی که یک پرس و جو طولانی شناسایی می شود، آنگاه افراد دیگر (فنی تر - اساساً DBA) تصمیم می گیرند MATERIALIZED را در برخی از عملکردهای میانی فعال کنند. این کار ضبط را کمی کند می کند (زیرا نیاز به به روز رسانی یک فیلد اضافی در تراکنش دارد). با این حال، نه تنها این پرس و جو به طور قابل توجهی سرعت می یابد، بلکه تمام موارد دیگری که از این تابع استفاده می کنند نیز افزایش می یابد. در عین حال، تصمیم گیری در مورد اینکه کدام تابع باید تحقق یابد نسبتا آسان است. دو پارامتر اصلی: تعداد مقادیر ورودی ممکن (این تعداد رکورد در جدول مربوطه خواهد بود) و تعداد دفعات استفاده از آن در سایر توابع.
آنالوگ
DBMS های تجاری مدرن مکانیسم های مشابهی دارند: نمای مادی با تازه سازی سریع (Oracle) و نمای INDEXED (Microsoft SQL Server). در PostgreSQL، VIEW MATERIALIZED را نمی توان در یک تراکنش به روز کرد، اما فقط در صورت درخواست (و حتی با محدودیت های بسیار سخت)، بنابراین ما آن را در نظر نمی گیریم. اما آنها چندین مشکل دارند که استفاده از آنها را به طور قابل توجهی محدود می کند.
اولاً، فقط در صورتی میتوانید متریالسازی را فعال کنید که قبلاً یک VIEW معمولی ایجاد کرده باشید. در غیر این صورت، باید درخواستهای باقیمانده را برای دسترسی به نمای جدید ایجاد شده بازنویسی کنید تا از این متریالسازی استفاده کنید. یا همه چیز را همانطور که هست رها کنید، اما اگر داده های از قبل محاسبه شده خاصی وجود داشته باشد، حداقل بی اثر خواهد بود، اما بسیاری از پرس و جوها همیشه از آن استفاده نمی کنند، بلکه دوباره آن را محاسبه می کنند.
ثانیا، آنها محدودیت های زیادی دارند:
وحی
5.3.8.4 محدودیت های عمومی در Fast Refresh
پرس و جوی تعیین کننده نمای مادی شده به صورت زیر محدود می شود:
- نمای تحققیافته نباید حاوی ارجاعاتی به عبارات تکرار نشدنی باشد
SYSDATEوROWNUM.- نمای تحقق یافته نباید حاوی ارجاعاتی به آن باشد
RAWorLONGRAWانواع داده ها- نمی تواند حاوی الف باشد
SELECTفهرست فرعی- نمی تواند شامل توابع تحلیلی باشد (به عنوان مثال،
RANK) درSELECTبند- نمی تواند به جدولی ارجاع دهد که در آن یک
XMLIndexشاخص تعریف شده است.- نمی تواند حاوی الف باشد
MODELبند- نمی تواند حاوی الف باشد
HAVINGبند با استعلام فرعی- نمی تواند شامل پرس و جوهای تو در تو باشد
ANY,ALL، یاNOTEXISTS.- نمی تواند حاوی الف باشد
[START WITH …] CONNECT BYبند- نمی تواند شامل چندین جدول جزئیات در سایت های مختلف باشد.
ONCOMMITنماهای تحقق یافته نمی توانند جداول جزئیات از راه دور داشته باشند.- نماهای مادی تو در تو باید دارای پیوند یا تجمیع باشند.
- نماهای پیوستن مادی و نماهای انبوه مادی شده با الف
GROUPBYبند نمی تواند از جدول سازماندهی شده با فهرست انتخاب شود.5.3.8.5 محدودیتهای تازهسازی سریع در نماهای مادیشده فقط با پیوستن
تعریف پرسوجوها برای نماهای تحققیافته فقط با پیوستن و بدون تجمیع، محدودیتهای زیر را برای بازخوانی سریع دارد:
- تمام محدودیت ها از «".
- نمی توانند داشته باشند
GROUPBYبندها یا مجموع.- ردیف تمام جداول در
FROMلیست باید درSELECTلیست پرس و جو- گزارشهای نمای مادیشده باید با ردیفهایی برای همه جداول پایه در وجود داشته باشند
FROMلیست پرس و جو- نمیتوانید یک نمای مادیشده با قابلیت تجدید سریع از چندین جدول با اتصالات ساده ایجاد کنید که شامل یک ستون نوع شی در
SELECTبیانیه.همچنین، روش بهروزرسانی که انتخاب میکنید کارآمدی مطلوبی نخواهد داشت اگر:
- کوئری تعریف کننده از یک اتصال بیرونی استفاده می کند که مانند یک اتصال داخلی عمل می کند. اگر پرس و جوی تعریف کننده شامل چنین اتصالی است، بازنویسی پرس و جو تعریف کننده را در نظر بگیرید تا حاوی یک اتصال داخلی باشد.
- La
SELECTفهرست نمای مادی شده شامل عباراتی در ستونهایی از چندین جدول است.5.3.8.6 محدودیتهای بهروزرسانی سریع در نماهای مادی شده با مجموعها
تعریف پرسوجوها برای نماهای تحققیافته با مجموعها یا پیوندها دارای محدودیتهای زیر برای بهروزرسانی سریع است:
- تمام محدودیت ها از «".
تازه سازی سریع برای هر دو پشتیبانی می شود
ONCOMMITوONDEMANDدیدگاه های تحقق یافته، اما محدودیت های زیر اعمال می شود:
- همه جداول در نمای متریالشده باید دارای گزارشهای نمای مادیشده باشند و گزارشهای نمای مادیشده باید:
- شامل تمام ستونهای جدولی است که در نمای مادیشده ارجاع داده شده است.
- مشخص کنید با
ROWIDوINCLUDINGNEWVALUES.- مشخص
SEQUENCEاگر انتظار میرود جدول ترکیبی از درجها/بارگذاریهای مستقیم، حذفها و بهروزرسانیها را داشته باشد، شرط کنید.- تنها
SUM,COUNT,AVG,STDDEV,VARIANCE,MINوMAXبرای تازه سازی سریع پشتیبانی می شوند.COUNT(*)باید مشخص شود.- توابع جمع باید فقط به عنوان بیرونی ترین قسمت عبارت ظاهر شوند. یعنی سنگدانه هایی مانند
AVG(AVG(x))orAVG(x)+AVG(x)مجاز نیستند- برای هر مجموعه ای مانند
AVG(expr)، مربوطهCOUNT(expr)باید حضور داشته باشد. Oracle این را توصیه می کندSUM(expr)مشخص شود.- If
VARIANCE(expr)orSTDDEV(expr) مشخص شده است،COUNT(expr)وSUM(expr)باید مشخص شود. Oracle این را توصیه می کندSUM(expr *expr)مشخص شود.- La
SELECTستون در پرس و جوی تعیین کننده نمی تواند یک عبارت پیچیده با ستون هایی از چندین جداول پایه باشد. یک راه حل ممکن برای این کار استفاده از یک نمای مادی تو در تو است.- La
SELECTلیست باید شامل همه باشدGROUPBYستون ها.- نمای تحقق یافته بر اساس یک یا چند جدول راه دور نیست.
- اگر از یک
CHARنوع داده در ستونهای فیلتر یک گزارش مشاهده متریالشده، مجموعه کاراکترهای سایت اصلی و نمای تحققیافته باید یکسان باشند.- اگر نمای تحققیافته دارای یکی از موارد زیر باشد، تازهسازی سریع فقط در درجهای DML معمولی و بارهای مستقیم پشتیبانی میشود.
- دیدگاه های مادی شده با
MINorMAXمصالح- دیدگاه های مادی شده که دارند
SUM(expr)اما نهCOUNT(expr)- دیدگاه های مادی شده بدون
COUNT(*)چنین نمای مادی شده، نمای مادی شده فقط درج نامیده می شود.
- یک دیدگاه مادی شده با
MAXorMINپس از حذف یا مخلوط شدن عبارات DML در صورتی که a نداشته باشد، به سرعت قابل بازخوانی استWHEREبند
حداکثر/دقیقه تازهسازی سریع پس از حذف یا ترکیب DML رفتاری مشابه مورد فقط درج ندارد. مقادیر حداکثر/دقیقه را برای گروههای آسیبدیده حذف و دوباره محاسبه میکند. شما باید از تاثیر عملکرد آن آگاه باشید.- نماهای مادی شده با نماهای نامگذاری شده یا پرسش های فرعی در
FROMبند را می توان به سرعت به روز کرد، مشروط بر اینکه نماها کاملاً ادغام شوند. برای اطلاع از اینکه کدام نماها ادغام خواهند شد، رجوع کنید به .- اگر هیچ اتصال خارجی وجود نداشته باشد، ممکن است انتخاب های دلخواه داشته باشید و به آن بپیوندید
WHEREبند- نماهای متریال شده با اتصالات بیرونی پس از DML معمولی و بارهای مستقیم به سرعت قابل تجدید هستند، مشروط بر اینکه فقط جدول بیرونی اصلاح شده باشد. همچنین، محدودیتهای منحصربهفردی باید در ستونهای اتصال جدول اتصال داخلی وجود داشته باشد. اگر اتصالات بیرونی وجود داشته باشد، همه اتصالات باید توسط متصل شوند
ANDs و باید از برابری (=) اپراتور.- برای نماهای تحقق یافته با
CUBE,ROLLUP، گروه بندی مجموعه ها یا الحاق آنها، محدودیت های زیر اعمال می شود:
- La
SELECTلیست باید شامل گروه بندی متمایز کننده باشد که می تواند یک باشدGROUPING_IDعملکرد روی همهGROUPBYعبارات یاGROUPINGبرای هر کدام یک تابعGROUPBYاصطلاح. به عنوان مثال، اگرGROUPBYبند دیدگاه تحقق یافته این استGROUPBYCUBE(a, b)"، سپسSELECTلیست باید حاوی یکی از این موارد باشدGROUPING_ID(a, b)" یا "GROUPING(a)ANDGROUPING(b)» برای اینکه نمای مادی شده به سرعت قابل تجدید باشد.GROUPBYنباید منجر به گروه بندی تکراری شود. مثلا، "GROUP BY a, ROLLUP(a, b)"به سرعت قابل تجدید نیست زیرا منجر به گروه بندی های تکراری می شود"(a), (a, b), AND (a)".5.3.8.7 محدودیتهای بهروزرسانی سریع در نماهای مادیشده با UNION ALL
دیدگاه های مادی شده با
UNIONALLمجموعه پشتیبانی از اپراتورREFRESHFASTگزینه در صورتی که شرایط زیر برآورده شود:
- پرس و جوی تعریف کننده باید دارای این باشد
UNIONALLاپراتور در سطح بالاLa
UNIONALLاپراتور را نمی توان در یک زیرپرسوجو جاسازی کرد، با یک استثنا: TheUNIONALLمی تواند در یک پرسش فرعی درFROMشرط به شرطی که پرس و جوی تعریف کننده به شکل باشدSELECT * FROM(مشاهده یا درخواست فرعی باUNIONALL) مانند مثال زیر:ایجاد نمای view_with_unionall AS (انتخاب c.rowid crid، c.cust_id، 2 umarker از مشتریان c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid، c.cust_id، 3 umarker FROM مشتریان c_last c_last. "جونز")؛ ایجاد نمای متریال unionall_inside_view_mv تجدید سریع در صورت تقاضا به عنوان انتخاب * از view_with_unionall.توجه داشته باشید که نمای
view_with_unionallشرایط لازم برای تازه سازی سریع را برآورده می کند.- هر بلوک پرس و جو در
UNIONALLپرس و جو باید الزامات یک نمای مادیت شده با قابلیت بازخوانی سریع با تجمیع یا یک نمای مادیت شده با قابلیت تجدید سریع با اتصالات را برآورده کند.گزارشهای نمای متریالسازی شده مناسب باید بر روی جداول برای نوع متناظر نمای مادیسازیشده با قابلیت بازخوانی سریع ایجاد شوند.
توجه داشته باشید که پایگاه داده Oracle همچنین اجازه میدهد حالت خاص یک نمای منفرد جدولی با اتصالات تنها ارائه شودROWIDستون در گنجانده شده استSELECTلیست و در گزارش مشاهده متریال شده. این در پرس و جوی تعیین کننده view نشان داده شده استview_with_unionall.- La
SELECTلیست هر پرس و جو باید شامل الف باشدUNIONALLنشانگر، وUNIONALLستون باید دارای یک مقدار ثابت عددی یا رشته ای در هر کدام باشدUNIONALLشاخه. علاوه بر این، ستون نشانگر باید در همان موقعیت ترتیبی در نشانگر ظاهر شودSELECTلیست هر بلوک پرس و جو دیدن "» برای اطلاعات بیشتر در موردUNIONALLنشانگرها- برخی از ویژگیها مانند اتصالهای بیرونی، جستارهای نمای انباشتهشده فقط درج و جداول راه دور برای نماهای تحققیافته با
UNIONALL. با این حال، توجه داشته باشید که نماهای مادی مورد استفاده در همانندسازی، که حاوی پیوند یا تجمیع نیستند، می توانند به سرعت به روز شوند.UNIONALLیا جداول از راه دور استفاده می شود.- پارامتر تنظیم اولیه سازگاری باید روی 9.2.0 یا بالاتر تنظیم شود تا یک نمای واقعی قابل بازخوانی سریع ایجاد شود.
UNIONALL.
من نمی خواهم طرفداران اوراکل را توهین کنم، اما با توجه به لیست محدودیت های آنها، به نظر می رسد که این مکانیسم نه در حالت کلی و با استفاده از نوعی مدل، بلکه توسط هزاران هندی نوشته شده است، جایی که به همه این فرصت داده شده است که شاخه خود را بنویسند، و هر کدام از آنها آنچه می توانست انجام داد و انجام داد. استفاده از این مکانیسم برای منطق واقعی مانند قدم زدن در یک میدان مین است. شما می توانید در هر زمان با زدن یکی از محدودیت های غیر آشکار، مین دریافت کنید. نحوه عملکرد آن نیز یک سوال جداگانه است، اما از حوصله این مقاله خارج است.
SQL سرور مایکروسافت
الزامات اضافی
علاوه بر گزینه های SET و الزامات عملکرد قطعی، الزامات زیر باید برآورده شوند:
- کاربری که اجرا می کند
CREATE INDEXباید صاحب منظره باشد- وقتی ایندکس را ایجاد می کنید،
IGNORE_DUP_KEYگزینه باید روی OFF (تنظیم پیش فرض) تنظیم شود.- جداول باید با نام های دو قسمتی ارجاع داده شوند، طرح.نام جدول در تعریف view
- توابع تعریف شده توسط کاربر که در نمای ارجاع داده می شوند باید با استفاده از عبارت ایجاد شوند
WITH SCHEMABINDINGگزینه.- هر توابع تعریف شده توسط کاربر که در نمای ارجاع داده می شود باید با نام های دو بخشی ارجاع داده شود. ..
- ویژگی دسترسی به داده یک تابع تعریف شده توسط کاربر باید باشد
NO SQLو ویژگی دسترسی خارجی باید باشدNO.- توابع زمان اجرا زبان رایج (CLR) می توانند در لیست انتخابی نمای ظاهر شوند، اما نمی توانند بخشی از تعریف کلید فهرست خوشه ای باشند. توابع CLR نمی توانند در عبارت WHERE view یا عبارت ON یک عملیات JOIN در view ظاهر شوند.
- توابع و روشهای CLR انواع تعریف شده توسط کاربر CLR که در تعریف view استفاده میشوند باید دارای ویژگیهایی باشند که در جدول زیر نشان داده شده است.
نوع ملک مورد نظر
توجه داشته باشید:قطعی = واقعی
باید به صراحت به عنوان ویژگی روش Microsoft .NET Framework اعلام شود.دقیق = درست
باید به صراحت به عنوان ویژگی متد .NET Framework اعلام شود.دسترسی به داده = بدون SQL
با تنظیم ویژگی DataAccess روی DataAccessKind.None و مشخصه SystemDataAccess روی SystemDataAccessKind.None تعیین می شود.دسترسی خارجی = NO
این ویژگی برای روتین های CLR روی NO پیش فرض قرار می گیرد.- نما باید با استفاده از
WITH SCHEMABINDINGگزینه.- نما باید فقط به جداول پایه که در پایگاه داده یکسانی هستند ارجاع دهد. نما نمی تواند به نماهای دیگر ارجاع دهد.
- دستور SELECT در تعریف view نباید حاوی عناصر Transact-SQL زیر باشد:
COUNT
توابع ROWSET (OPENDATASOURCE,OPENQUERY,OPENROWSET، وOPENXML)
OUTERمی پیوندد(LEFT,RIGHT، یاFULL)جدول مشتق شده (با مشخص کردن a
SELECTبیانیه درFROMعبارت)
خود ملحق می شود
تعیین ستون ها با استفاده ازSELECT *orSELECT <table_name>.*
DISTINCT
STDEV,STDEVP,VAR,VARP، یاAVG
عبارت جدول رایج (CTE)شناور1, متن, متن, تصویر, XML، یا جریان فایل ستون ها
زیر پرس و جو
OVERبند، که شامل رتبه بندی یا توابع پنجره جمع می شودمحمولات تمام متن (
CONTAINS,FREETEXT)
SUMتابعی که به یک عبارت nullable ارجاع می دهد
ORDER BYتابع کل تعریف شده توسط کاربر CLR
TOP
CUBE,ROLLUP، یاGROUPING SETSاپراتور
MIN,MAX
UNION,EXCEPT، یاINTERSECTاپراتور
TABLESAMPLEمتغیرهای جدول
OUTER APPLYorCROSS APPLY
PIVOT,UNPIVOTمجموعه ستون های پراکنده
توابع درون خطی (TVF) یا توابع با ارزش جدول چند بیانیه (MSTVF)
OFFSET
CHECKSUM_AGG1 نمای نمایه شده می تواند شامل باشد شناور ستون ها؛ با این حال، چنین ستون هایی را نمی توان در کلید فهرست خوشه ای گنجاند.
- If
GROUP BYوجود دارد، تعریف VIEW باید شامل باشدCOUNT_BIG(*)و نباید شامل شودHAVINGاست. اینهاGROUP BYمحدودیت ها فقط برای تعریف نمای نمایه شده قابل اعمال هستند. یک پرس و جو می تواند از نمای نمایه شده در طرح اجرای خود استفاده کند حتی اگر این موارد را برآورده نکندGROUP BYمحدودیت های.- اگر تعریف view حاوی الف باشد
GROUP BYبند، کلید ایندکس خوشهای منحصربهفرد میتواند تنها به ستونهای مشخصشده در آن ارجاع دهدGROUP BYبند
در اینجا واضح است که هندی ها درگیر نبودند، زیرا آنها تصمیم گرفتند این کار را طبق این طرح انجام دهند "ما کم، اما خوب انجام خواهیم داد." یعنی مین های بیشتری در میدان دارند اما مکانشان شفاف تر است. ناامید کننده ترین چیز این محدودیت است:
نما باید فقط به جداول پایه که در پایگاه داده یکسانی هستند ارجاع دهد. نما نمی تواند به نماهای دیگر ارجاع دهد.
در اصطلاح ما، این بدان معنی است که یک تابع نمی تواند به تابع مادیت شده دیگری دسترسی داشته باشد. این همه ایدئولوژی را در جوانه از بین می برد.
همچنین، این محدودیت (و بیشتر در متن) موارد استفاده را تا حد زیادی کاهش می دهد:
دستور SELECT در تعریف view نباید حاوی عناصر Transact-SQL زیر باشد:
COUNT
توابع ROWSET (OPENDATASOURCE,OPENQUERY,OPENROWSET، وOPENXML)
OUTERمی پیوندد(LEFT,RIGHT، یاFULL)جدول مشتق شده (با مشخص کردن a
SELECTبیانیه درFROMعبارت)
خود ملحق می شود
تعیین ستون ها با استفاده ازSELECT *orSELECT <table_name>.*
DISTINCT
STDEV,STDEVP,VAR,VARP، یاAVG
عبارت جدول رایج (CTE)شناور1, متن, متن, تصویر, XML، یا جریان فایل ستون ها
زیر پرس و جو
OVERبند، که شامل رتبه بندی یا توابع پنجره جمع می شودمحمولات تمام متن (
CONTAINS,FREETEXT)
SUMتابعی که به یک عبارت nullable ارجاع می دهد
ORDER BYتابع کل تعریف شده توسط کاربر CLR
TOP
CUBE,ROLLUP، یاGROUPING SETSاپراتور
MIN,MAX
UNION,EXCEPT، یاINTERSECTاپراتور
TABLESAMPLEمتغیرهای جدول
OUTER APPLYorCROSS APPLY
PIVOT,UNPIVOTمجموعه ستون های پراکنده
توابع درون خطی (TVF) یا توابع با ارزش جدول چند بیانیه (MSTVF)
OFFSET
CHECKSUM_AGG
پیوستن خارجی، اتحادیه، سفارش توسط و غیره ممنوع است. شاید تعیین اینکه چه چیزی قابل استفاده است به جای اینکه چه چیزی قابل استفاده نباشد، ممکن است آسان تر باشد. لیست احتمالاً بسیار کوتاهتر خواهد بود.
به طور خلاصه: مجموعه عظیمی از محدودیتها در هر DBMS (بیایید توجه کنیم تجاری) در مقابل هیچ یک (به استثنای یک مورد منطقی، نه فنی) در فناوری LGPL. با این حال، باید توجه داشت که اجرای این مکانیسم در منطق رابطه ای تا حدودی دشوارتر از منطق تابعی توصیف شده است.
اجرا
چگونه کار می کند؟ PostgreSQL به عنوان یک "ماشین مجازی" استفاده می شود. یک الگوریتم پیچیده در داخل وجود دارد که پرس و جوها را ایجاد می کند. اینجا . و فقط مجموعه بزرگی از اکتشافی با دسته ای از اگرها وجود ندارد. بنابراین، اگر چند ماه برای مطالعه دارید، می توانید سعی کنید معماری را درک کنید.
آیا به طور موثر عمل می کند؟ کاملا موثر. متأسفانه اثبات این امر دشوار است. فقط می توانم بگویم که اگر هزاران پرس و جو را در برنامه های بزرگ در نظر بگیرید، به طور متوسط آنها کارآمدتر از یک توسعه دهنده خوب هستند. یک برنامه نویس عالی SQL می تواند هر پرس و جو را کارآمدتر بنویسد، اما با هزاران پرس و جو انگیزه یا زمانی برای انجام آن را نخواهد داشت. تنها چیزی که اکنون می توانم به عنوان اثبات اثربخشی ذکر کنم این است که چندین پروژه بر روی پلتفرم ساخته شده بر روی این DBMS کار می کنند. ، که دارای هزاران عملکرد مختلف MATERIALIZED هستند، با هزاران کاربر و پایگاه داده ترابایتی با صدها میلیون رکورد در حال اجرا بر روی یک سرور معمولی دو پردازنده. با این حال، هر کسی می تواند با دانلود کردن، اثربخشی را بررسی یا رد کند و PostgreSQL، پرسوجوهای SQL را ثبت کرده و سعی میکنید منطق و دادهها را در آنجا تغییر دهید.
در مقالات بعدی، من همچنین در مورد اینکه چگونه می توانید محدودیت هایی برای عملکردها، کار با جلسات تغییر و موارد دیگر ایجاد کنید، صحبت خواهم کرد.
منبع: www.habr.com
