تعادل در یک پایگاه داده می نویسد و می خواند

تعادل در یک پایگاه داده می نویسد و می خواند
در قبلی مقاله من مفهوم و پیاده سازی پایگاه داده ای را که بر اساس توابع ساخته شده است، به جای جداول و فیلدها در پایگاه داده های رابطه ای توضیح دادم. مثال‌های زیادی ارائه می‌کند که مزایای این رویکرد را نسبت به روش کلاسیک نشان می‌دهد. بسیاری آنها را به اندازه کافی قانع کننده نمی دانستند.

در این مقاله، من نشان خواهم داد که چگونه این مفهوم به شما اجازه می دهد تا به سرعت و به راحتی بین نوشته ها و خواندن ها در پایگاه داده بدون هیچ تغییری در منطق عملیات، تعادل برقرار کنید. عملکرد مشابهی سعی شده است در 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 عملکردی یک زیرپرس و جو ایجاد می‌کند که مقادیر مورد نیاز بخش را محاسبه می‌کند و سپس برای به دست آوردن نام، یک 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);

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

هنگام فراخوانی یک تابع تاریخ برای خط سفارش، فیلدی که برای آن شاخص وجود دارد از جدول با خطوط سفارش خوانده می شود. هنگامی که تاریخ سفارش تغییر می کند، خود سیستم به طور خودکار تاریخ غیرعادی شده در خط را دوباره محاسبه می کند.

مزایا

کل این مکانیسم برای چیست؟ در 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.
  • نمای تحقق یافته نباید حاوی ارجاعاتی به آن باشد RAW or LONG RAW انواع داده ها
  • نمی تواند حاوی الف باشد SELECT فهرست فرعی
  • نمی تواند شامل توابع تحلیلی باشد (به عنوان مثال، RANK) در SELECT بند
  • نمی تواند به جدولی ارجاع دهد که در آن یک XMLIndex شاخص تعریف شده است.
  • نمی تواند حاوی الف باشد MODEL بند
  • نمی تواند حاوی الف باشد HAVING بند با استعلام فرعی
  • نمی تواند شامل پرس و جوهای تو در تو باشد ANY, ALL، یا NOT EXISTS.
  • نمی تواند حاوی الف باشد [START WITH …] CONNECT BY بند
  • نمی تواند شامل چندین جدول جزئیات در سایت های مختلف باشد.
  • ON COMMIT نماهای تحقق یافته نمی توانند جداول جزئیات از راه دور داشته باشند.
  • نماهای مادی تو در تو باید دارای پیوند یا تجمیع باشند.
  • نماهای پیوستن مادی و نماهای انبوه مادی شده با الف GROUP BY بند نمی تواند از جدول سازماندهی شده با فهرست انتخاب شود.

5.3.8.5 محدودیت‌های تازه‌سازی سریع در نماهای مادی‌شده فقط با پیوستن

تعریف پرس‌و‌جوها برای نماهای تحقق‌یافته فقط با پیوستن و بدون تجمیع، محدودیت‌های زیر را برای بازخوانی سریع دارد:

  • تمام محدودیت ها از «محدودیت های عمومی در Fast Refresh".
  • نمی توانند داشته باشند GROUP BY بندها یا مجموع.
  • ردیف تمام جداول در FROM لیست باید در SELECT لیست پرس و جو
  • گزارش‌های نمای مادی‌شده باید با ردیف‌هایی برای همه جداول پایه در وجود داشته باشند FROM لیست پرس و جو
  • نمی‌توانید یک نمای مادی‌شده با قابلیت تجدید سریع از چندین جدول با اتصالات ساده ایجاد کنید که شامل یک ستون نوع شی در SELECT بیانیه.

همچنین، روش به‌روزرسانی که انتخاب می‌کنید کارآمدی مطلوبی نخواهد داشت اگر:

  • کوئری تعریف کننده از یک اتصال بیرونی استفاده می کند که مانند یک اتصال داخلی عمل می کند. اگر پرس و جوی تعریف کننده شامل چنین اتصالی است، بازنویسی پرس و جو تعریف کننده را در نظر بگیرید تا حاوی یک اتصال داخلی باشد.
  • La 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) مشخص شود.
  • La SELECT ستون در پرس و جوی تعیین کننده نمی تواند یک عبارت پیچیده با ستون هایی از چندین جداول پایه باشد. یک راه حل ممکن برای این کار استفاده از یک نمای مادی تو در تو است.
  • La SELECT لیست باید شامل همه باشد GROUP BY ستون ها.
  • نمای تحقق یافته بر اساس یک یا چند جدول راه دور نیست.
  • اگر از یک CHAR نوع داده در ستون‌های فیلتر یک گزارش مشاهده متریال‌شده، مجموعه کاراکترهای سایت اصلی و نمای تحقق‌یافته باید یکسان باشند.
  • اگر نمای تحقق‌یافته دارای یکی از موارد زیر باشد، تازه‌سازی سریع فقط در درج‌های DML معمولی و بارهای مستقیم پشتیبانی می‌شود.
    • دیدگاه های مادی شده با MIN or MAX مصالح
    • دیدگاه های مادی شده که دارند SUM(expr) اما نه COUNT(expr)
    • دیدگاه های مادی شده بدون COUNT(*)

    چنین نمای مادی شده، نمای مادی شده فقط درج نامیده می شود.

  • یک دیدگاه مادی شده با MAX or MIN پس از حذف یا مخلوط شدن عبارات DML در صورتی که a نداشته باشد، به سرعت قابل بازخوانی است WHERE بند
    حداکثر/دقیقه تازه‌سازی سریع پس از حذف یا ترکیب DML رفتاری مشابه مورد فقط درج ندارد. مقادیر حداکثر/دقیقه را برای گروه‌های آسیب‌دیده حذف و دوباره محاسبه می‌کند. شما باید از تاثیر عملکرد آن آگاه باشید.
  • نماهای مادی شده با نماهای نامگذاری شده یا پرسش های فرعی در FROM بند را می توان به سرعت به روز کرد، مشروط بر اینکه نماها کاملاً ادغام شوند. برای اطلاع از اینکه کدام نماها ادغام خواهند شد، رجوع کنید به مرجع زبان پایگاه داده Oracle SQL.
  • اگر هیچ اتصال خارجی وجود نداشته باشد، ممکن است انتخاب های دلخواه داشته باشید و به آن بپیوندید WHERE بند
  • نماهای متریال شده با اتصالات بیرونی پس از DML معمولی و بارهای مستقیم به سرعت قابل تجدید هستند، مشروط بر اینکه فقط جدول بیرونی اصلاح شده باشد. همچنین، محدودیت‌های منحصربه‌فردی باید در ستون‌های اتصال جدول اتصال داخلی وجود داشته باشد. اگر اتصالات بیرونی وجود داشته باشد، همه اتصالات باید توسط متصل شوند ANDs و باید از برابری (=) اپراتور.
  • برای نماهای تحقق یافته با CUBE, ROLLUP، گروه بندی مجموعه ها یا الحاق آنها، محدودیت های زیر اعمال می شود:
    • La 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 اپراتور در سطح بالا

    La UNION ALL اپراتور را نمی توان در یک زیرپرسوجو جاسازی کرد، با یک استثنا: The UNION ALL می تواند در یک پرسش فرعی در FROM شرط به شرطی که پرس و جوی تعریف کننده به شکل باشد SELECT * FROM (مشاهده یا درخواست فرعی با UNION ALL) مانند مثال زیر:

    ایجاد نمای 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 شرایط لازم برای تازه سازی سریع را برآورده می کند.

  • هر بلوک پرس و جو در UNION ALL پرس و جو باید الزامات یک نمای مادیت شده با قابلیت بازخوانی سریع با تجمیع یا یک نمای مادیت شده با قابلیت تجدید سریع با اتصالات را برآورده کند.

    گزارش‌های نمای متریال‌سازی شده مناسب باید بر روی جداول برای نوع متناظر نمای مادی‌سازی‌شده با قابلیت بازخوانی سریع ایجاد شوند.
    توجه داشته باشید که پایگاه داده Oracle همچنین اجازه می‌دهد حالت خاص یک نمای منفرد جدولی با اتصالات تنها ارائه شود ROWID ستون در گنجانده شده است SELECT لیست و در گزارش مشاهده متریال شده. این در پرس و جوی تعیین کننده view نشان داده شده است view_with_unionall.

  • La SELECT لیست هر پرس و جو باید شامل الف باشد UNION ALL نشانگر، و UNION ALL ستون باید دارای یک مقدار ثابت عددی یا رشته ای در هر کدام باشد UNION ALL شاخه. علاوه بر این، ستون نشانگر باید در همان موقعیت ترتیبی در نشانگر ظاهر شود SELECT لیست هر بلوک پرس و جو دیدن "UNION ALL نشانگر و بازنویسی پرس و جو» برای اطلاعات بیشتر در مورد UNION ALL نشانگرها
  • برخی از ویژگی‌ها مانند اتصال‌های بیرونی، جستارهای نمای انباشته‌شده فقط درج و جداول راه دور برای نماهای تحقق‌یافته با UNION ALL. با این حال، توجه داشته باشید که نماهای مادی مورد استفاده در همانندسازی، که حاوی پیوند یا تجمیع نیستند، می توانند به سرعت به روز شوند. UNION ALL یا جداول از راه دور استفاده می شود.
  • پارامتر تنظیم اولیه سازگاری باید روی 9.2.0 یا بالاتر تنظیم شود تا یک نمای واقعی قابل بازخوانی سریع ایجاد شود. UNION ALL.

من نمی خواهم طرفداران اوراکل را توهین کنم، اما با توجه به لیست محدودیت های آنها، به نظر می رسد که این مکانیسم نه در حالت کلی و با استفاده از نوعی مدل، بلکه توسط هزاران هندی نوشته شده است، جایی که به همه این فرصت داده شده است که شاخه خود را بنویسند، و هر کدام از آنها آنچه می توانست انجام داد و انجام داد. استفاده از این مکانیسم برای منطق واقعی مانند قدم زدن در یک میدان مین است. شما می توانید در هر زمان با زدن یکی از محدودیت های غیر آشکار، مین دریافت کنید. نحوه عملکرد آن نیز یک سوال جداگانه است، اما از حوصله این مقاله خارج است.

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 * or SELECT <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 APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    مجموعه ستون های پراکنده
    توابع درون خطی (TVF) یا توابع با ارزش جدول چند بیانیه (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 نمای نمایه شده می تواند شامل باشد شناور ستون ها؛ با این حال، چنین ستون هایی را نمی توان در کلید فهرست خوشه ای گنجاند.

  • 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 * or SELECT <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 APPLY or CROSS APPLY
PIVOT, UNPIVOT

مجموعه ستون های پراکنده
توابع درون خطی (TVF) یا توابع با ارزش جدول چند بیانیه (MSTVF)
OFFSET

CHECKSUM_AGG

پیوستن خارجی، اتحادیه، سفارش توسط و غیره ممنوع است. شاید تعیین اینکه چه چیزی قابل استفاده است به جای اینکه چه چیزی قابل استفاده نباشد، ممکن است آسان تر باشد. لیست احتمالاً بسیار کوتاهتر خواهد بود.

به طور خلاصه: مجموعه عظیمی از محدودیت‌ها در هر DBMS (بیایید توجه کنیم تجاری) در مقابل هیچ یک (به استثنای یک مورد منطقی، نه فنی) در فناوری LGPL. با این حال، باید توجه داشت که اجرای این مکانیسم در منطق رابطه ای تا حدودی دشوارتر از منطق تابعی توصیف شده است.

اجرا

چگونه کار می کند؟ PostgreSQL به عنوان یک "ماشین مجازی" استفاده می شود. یک الگوریتم پیچیده در داخل وجود دارد که پرس و جوها را ایجاد می کند. اینجا منبع. و فقط مجموعه بزرگی از اکتشافی با دسته ای از اگرها وجود ندارد. بنابراین، اگر چند ماه برای مطالعه دارید، می توانید سعی کنید معماری را درک کنید.

آیا به طور موثر عمل می کند؟ کاملا موثر. متأسفانه اثبات این امر دشوار است. فقط می توانم بگویم که اگر هزاران پرس و جو را در برنامه های بزرگ در نظر بگیرید، به طور متوسط ​​آنها کارآمدتر از یک توسعه دهنده خوب هستند. یک برنامه نویس عالی SQL می تواند هر پرس و جو را کارآمدتر بنویسد، اما با هزاران پرس و جو انگیزه یا زمانی برای انجام آن را نخواهد داشت. تنها چیزی که اکنون می توانم به عنوان اثبات اثربخشی ذکر کنم این است که چندین پروژه بر روی پلتفرم ساخته شده بر روی این DBMS کار می کنند. سیستم های ERP، که دارای هزاران عملکرد مختلف MATERIALIZED هستند، با هزاران کاربر و پایگاه داده ترابایتی با صدها میلیون رکورد در حال اجرا بر روی یک سرور معمولی دو پردازنده. با این حال، هر کسی می تواند با دانلود کردن، اثربخشی را بررسی یا رد کند سکو و PostgreSQL، روشن شد پرس‌وجوهای SQL را ثبت کرده و سعی می‌کنید منطق و داده‌ها را در آنجا تغییر دهید.

در مقالات بعدی، من همچنین در مورد اینکه چگونه می توانید محدودیت هایی برای عملکردها، کار با جلسات تغییر و موارد دیگر ایجاد کنید، صحبت خواهم کرد.

منبع: www.habr.com

اضافه کردن نظر