قاعدة بيانات الكتابة وقراءة التوازن

صورة

في مقال سابق ، وصفت مفهوم وتنفيذ قاعدة بيانات مبنية على أساس الوظائف ، وليس على الجداول والحقول كما في قواعد البيانات العلائقية. أعطت العديد من الأمثلة التي تبين مزايا هذا النهج على الكلاسيكية. وجد الكثير منهم غير مقنعين بما فيه الكفاية.

في هذه المقالة ، سأبين كيف يتيح لك هذا المفهوم تحقيق التوازن بين الكتابة والقراءة بسرعة وسهولة في قاعدة البيانات دون أي تغيير في منطق العمل. لقد حاولوا تنفيذ وظائف مماثلة في أنظمة إدارة قواعد البيانات التجارية الحديثة (على وجه الخصوص ، 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 (عدد الإدارات) للتجميع وما إلى ذلك.

من الواضح أن النفقات العامة للتنفيذ يمكن أن تكون مختلفة في نظم إدارة قواعد البيانات المختلفة ، لكن التعقيد لن يتغير بأي طريقة.

في التطبيق المقترح ، ستشكل قواعد إدارة قواعد البيانات الوظيفية استعلامًا فرعيًا واحدًا ، والذي سيحسب القيم اللازمة للإدارة ، ثم يقوم بإنشاء 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 (على سبيل المثال ، أي قيمة سلبية مناسبة). لذلك ، لا يمكن وضعه مواد. وبالتالي ، يعد هذا عائقًا منطقيًا وليس تقنيًا (أي ، ليس لأننا لم نتمكن من تنفيذ هذا). خلاف ذلك ، لا قيود. يمكنك استخدام التجميع والفرز و 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 ;
سيقوم النظام نفسه بإنشاء جدول واحد مع مفاتيح أنواع العملاء والمنتج و INTEGER ، وإضافة حقلين إليه وتحديث قيم الحقل فيها مع أي تغييرات. عند إجراء المزيد من المكالمات لهذه الوظائف ، لن يتم حسابها ، ولكن سيتم قراءة القيم من الحقول المقابلة.

باستخدام هذه الآلية ، يمكنك ، على سبيل المثال ، التخلص من العودية (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 ;
نظرًا لأن MATERIALIZED مُلصقة على الدالة isParent ، فسيتم إنشاء جدول به مفتاحان (مجموعة) له ، يكون فيه الحقل 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 ;
عند استدعاء دالة التاريخ لسطر الطلب ، ستكون القراءة من الجدول مع خطوط ترتيب للحقل الذي يوجد فهرس له. عند تغيير تاريخ الطلب ، سيقوم النظام تلقائيًا بإعادة حساب التاريخ غير الطبيعي في السطر.

الفوائد


لماذا هذه الآلية كلها مطلوبة؟ في DBMSs الكلاسيكية ، بدون إعادة كتابة الاستعلامات ، يمكن للمطور أو DBA فقط تغيير الفهارس وتحديد الإحصائيات وإخبار مخطط الاستعلام عن كيفية تنفيذها (علاوة على ذلك ، تتوفر HINTs فقط في DBMSs التجارية). بغض النظر عن مدى صعوبة المحاولة ، فلن يتمكنوا من تلبية الطلب الأول في المقالة لـ O (عدد الأقسام) دون تغيير الطلبات وإضافة المشغلات. في المخطط المقترح ، في مرحلة التطوير ، لا يتعين عليك التفكير في بنية تخزين البيانات والتجمعات التي يجب استخدامها. كل هذا يمكن تغييره بسهولة على الطاير ، مباشرة في العملية.

في الممارسة العملية ، وهذا هو على النحو التالي. يطور بعض الأشخاص المنطق استنادًا إلى المهمة. ليست على دراية بالخوارزميات وتعقيداتها ، ولا في خطط التنفيذ ، ولا في أنواع join'ov ، ولا في أي مكون تقني آخر. هؤلاء الناس هم أكثر المحللين الأعمال من المطورين. ثم ، كل شيء يذهب إلى الاختبار أو العملية. يتم تمكين تسجيل الاستعلامات الطويلة. عند اكتشاف طلب طويل ، يقرر أشخاص آخرون (أكثر تقنية - في الواقع DBA) تضمين MATERIALIZED في بعض الوظائف الوسيطة. وبالتالي ، يتم إبطاء التسجيل قليلاً (نظرًا لأن تحديث حقل إضافي في معاملة مطلوب). ومع ذلك ، لا يتم تسريع هذا الطلب بشكل كبير ، ولكن أيضًا كل الطلبات الأخرى التي تستخدم هذه الوظيفة. في نفس الوقت ، يكون اتخاذ قرار بشأن الوظيفة المحددة التي يجب تحقيقها أمرًا بسيطًا نسبيًا. معلمتان أساسيتان: عدد قيم المدخلات المحتملة (بالضبط عدد السجلات التي ستكون في الجدول المقابل) ، وعدد مرات استخدامها في وظائف أخرى.

النظير


DBMSs التجارية الحديثة لديها آليات مماثلة: عرض المواد مع التحديث السريع (Oracle) و INDEXED VIEW (Microsoft SQL Server). في PostgreSQL MATERIALIZED VIEW ، لا يمكن التحديث في معاملة ، ولكن فقط عند الطلب (وحتى مع وجود قيود صارمة للغاية) ، لذلك نحن لا نعتبر ذلك. ولكن لديهم العديد من المشاكل ، مما يحد كثيرا من استخدامها.

أولاً ، لا يمكنك تمكين التجسيد إلا إذا كنت قد أنشأت بالفعل عرضًا منتظمًا. وإلا ، فسيتعين عليك إعادة كتابة الطلبات المتبقية للوصول إلى العرض الذي تم إنشاؤه حديثًا لاستخدام هذا التجسيد. أو اترك كل شيء كما هو ، ولكن سيكون على الأقل غير فعال إذا كانت هناك بعض البيانات المحسوبة بالفعل ، ولكن العديد من الاستعلامات لا تستخدمها دائمًا ، ولكن يتم حسابها مرة أخرى.

ثانياً ، لديهم عدد كبير من القيود:

وحي
5.3.8.4 القيود العامة على التحديث السريع

يقتصر الاستعلام المحدد في العرض المادي على النحو التالي:
  • يجب ألا يحتوي العرض المادي على إشارات إلى تعبيرات غير مكررة مثل SYSDATE و SYSDATE .
  • يجب ألا يحتوي العرض المادي على مراجع لأنواع بيانات RAW أو LONG RAW .
  • لا يمكن أن يحتوي على استعلام فرعي لقائمة SELECT .
  • لا يمكن أن يحتوي على وظائف تحليلية (على سبيل المثال ، تصنيف) في جملة SELECT .
  • لا يمكن الرجوع إلى جدول يتم تعريف فهرس XMLIndex .
  • لا يمكن أن تحتوي على جملة MODEL .
  • لا يمكن أن يحتوي على جملة HAVING مع استعلام فرعي.
  • لا يمكن أن يحتوي على استعلامات متداخلة لها ANY أو EXISTS أو NOT EXISTS .
  • لا يمكن أن يحتوي على جملة [START WITH …] CONNECT BY .
  • لا يمكن أن يحتوي على جداول تفاصيل متعددة في مواقع مختلفة.
  • لا يمكن أن تحتوي طرق العرض COMMIT ON COMMIT ON جداول تفصيلية عن بُعد.
  • يجب أن تحتوي طرق العرض المادية المتداخلة على صلة أو مجمعة.
  • لا يمكن تحديد طرق عرض الصلة الملموسة وطرق العرض التجميعية المضمّنة مع جملة GROUP BY من جدول منظم بالفهرس.

5.3.8.5 القيود المفروضة على التحديث السريع على طرق العرض المادية باستخدام الصلات فقط

تحديد استعلامات طرق العرض المادية مع الصلات فقط وليس هناك أي تجميعات القيود التالية على التحديث السريع:
  • جميع القيود المفروضة على " القيود العامة على التحديث السريع ".
  • لا يمكن أن تحتوي على GROUP BY أو مجاميع.
  • يجب أن تظهر Rowids من جميع الجداول في قائمة FROM في قائمة SELECT الاستعلام.
  • يجب أن توجد سجلات العرض الملموسة مع rowids لكل الجداول الأساسية في قائمة FROM للاستعلام.
  • لا يمكنك إنشاء طريقة عرض سريعة قابلة للتحديث من جداول متعددة مع صلات بسيطة تتضمن عمود نوع كائن في SELECT .

أيضًا ، لن تكون طريقة التحديث التي تختارها فعالة على النحو الأمثل إذا:
  • يستخدم الاستعلام المحدد صلة خارجية تتصرف مثل صلة داخلية. إذا كان الاستعلام المحدد يحتوي على مثل هذا الصلة ، ففكر في إعادة كتابة الاستعلام المحدد ليتضمن صلة داخلية.
  • تحتوي قائمة SELECT للعرض المادي على تعبيرات على أعمدة من جداول متعددة.

5.3.8.6 القيود المفروضة على التحديث السريع على المشاهدات المادية مع المجاميع

تحديد استعلامات طرق العرض الملموسة مع التجميعات أو الصلات لها القيود التالية على التحديث السريع:

يتم دعم التحديث السريع لكلا COMMIT ON COMMIT و ON DEMAND ، ولكن تنطبق القيود التالية:
  • يجب أن تحتوي جميع الجداول في طريقة العرض الملموسة على سجلات عرض مادية ، ويجب أن تكون سجلات المشاهدة الموضحة:
    • احتواء جميع الأعمدة من الجدول المشار إليه في طريقة العرض الملموسة.
    • حدد مع ROWID INCLUDING VALUES NEW .
    • حدد جملة SEQUENCE إذا كان من المتوقع أن يحتوي الجدول على مزيج من عمليات الإدراج / التحميل المباشر ، الحذف ، والتحديثات.

  • يتم دعم SUM و COUNT و AVG و VARIANCE و VARIANCE و MIN و MAX فقط للتحديث السريع.
  • يجب تحديد COUNT(*) .
  • يجب أن تحدث الدالات التجميعية فقط باعتبارها أقصى جزء من التعبير. أي أنه لا يُسمح بتجميعات مثل AVG(AVG(x)) أو AVG(x) + AVG(x) .
  • لكل مجموعة مثل AVG(expr) ، يجب أن يكون COUNT(expr) المقابل موجودًا. توصي Oracle بتحديد SUM(expr) .
  • إذا تم تحديد VARIANCE(expr) أو STDDEV(expr ) ، فيجب تحديد COUNT(expr) و SUM(expr) . توصي Oracle بتحديد SUM(expr *expr) .
  • لا يمكن أن يكون العمود SELECT في استعلام التعريف تعبيرًا معقدًا مع أعمدة من جداول أساسية متعددة. للمشكلة المحتملة لهذا استخدام طريقة عرض المتداخلة المتداخلة.
  • يجب أن تحتوي قائمة SELECT على جميع أعمدة GROUP BY .
  • طريقة العرض الملموسة لا تستند إلى جدول بعيد أو أكثر.
  • إذا كنت تستخدم نوع بيانات CHAR في أعمدة التصفية في سجل عرض ملموس ، فيجب أن تكون مجموعات الأحرف في الموقع الرئيسي وطريقة العرض الملموسة هي نفسها.
  • إذا كان العرض المادي يحتوي على واحد مما يلي ، فلن يتم دعم التحديث السريع إلا في عمليات إدراج DML التقليدية والأحمال المباشرة.
    • المشاهدات المادية مع مجاميع MIN أو MAX
    • المشاهدات المادية التي تحتوي على SUM(expr) ولكن لا تحتوي على COUNT(expr)
    • المشاهدات المادية دون COUNT(*)

    تسمى طريقة العرض الملموسة هذه طريقة عرض يتم إدراجها فقط.
  • طريقة العرض MAX مع MAX أو MIN قابلة للتحديث بسرعة بعد حذف أو خلط بيانات DML إذا لم يكن لها WHERE .
    لا يكون للتحديث السريع كحد أقصى / دقيقة بعد الحذف أو DML المختلط نفس سلوك حالة الإدراج فقط. يقوم بحذف وإعادة حساب القيم القصوى / الدقيقة للمجموعات المتأثرة. يجب أن تكون مدركًا لتأثير أدائها.
  • يمكن تحديث طرق العرض المادية مع طرق العرض المسماة أو الاستعلامات الفرعية في جملة FROM بشرط أن يتم دمج طرق العرض بالكامل. للحصول على معلومات حول طرق العرض التي سيتم دمجها ، راجع مرجع لغة Oracle Database SQL .
  • إذا لم تكن هناك روابط خارجية ، فقد يكون لديك اختيارات تعسفية ووصلات في WHERE .
  • يمكن تجديد طرق العرض التجميعية المادية مع الوصلات الخارجية بسرعة بعد DML التقليدية والأحمال المباشرة ، بشرط تعديل الجدول الخارجي فقط. أيضًا ، يجب أن توجد قيود فريدة على أعمدة الصلة بجدول الصلة الداخلي. إذا كان هناك روابط خارجية ، فيجب أن تكون جميع الروابط متصلة بواسطة AND ويجب أن تستخدم عامل المساواة ( = ).
  • بالنسبة إلى طرق ROLLUP باستخدام CUBE أو ROLLUP أو مجموعات التجميع أو متسلسلة لها ، يتم تطبيق القيود التالية:
    • يجب أن تحتوي قائمة SELECT على أداة تمييز للتجميع يمكن أن تكون إما دالة GROUPING_ID في جميع تعبيرات GROUP BY أو وظائف GROUPING واحدة لكل تعبير GROUP BY . على سبيل المثال ، إذا كانت جملة GROUP BY في المشاهدة CUBE(a, b) هي " 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 في المستوى العلوي.

    لا يمكن تضمين عامل التشغيل UNION ALL داخل استعلام فرعي ، باستثناء واحد: يمكن أن يكون UNION ALL في استعلام فرعي في جملة FROM بشرط أن يكون الاستعلام المحدد بالنموذج SELECT * FROM (عرض أو استعلام فرعي مع UNION ALL ) كما يلي على سبيل المثال:
      إنشاء عرض view_with_unionall AS
     (SELECT c.rowid crid، c.cust_id، 2 umarker
      من العملاء c WHERE c.cust_last_name = 'Smith'
      اتحاد الجميع
      اختر c.rowid crid، c.cust_id، 3 umarker
      من العملاء c WHERE c.cust_last_name = 'Jones') ؛
    
     CREATE MATERIALIZED VIEW unionall_inside_view_mv
     تحديث سريع على الطلب AS
     SELECT * FROM view_with_unionall؛
    
    لاحظ أن طريقة العرض view_with_unionall تلبي متطلبات التحديث السريع.
  • يجب أن تفي كل كتلة استعلام في استعلام UNION ALL بمتطلبات طريقة العرض الملموسة القابلة للتحديث السريع مع المجاميع أو طريقة العرض الملموسة القابلة للتحديث السريع مع وصلات.

    يجب إنشاء سجلات العرض الملموسة المناسبة على الجداول كما هو مطلوب لنوع العرض المادي القابل للتحديث السريع.
    لاحظ أن قاعدة بيانات Oracle تسمح أيضًا بالحالة الخاصة ROWID عرض مادية لجدول واحد مع وصلات فقط بشرط تضمين عمود ROWID في قائمة SELECT وفي سجل العرض المادي. يظهر هذا في الاستعلام المحدد view_with_unionall العرض view_with_unionall .
  • يجب أن تتضمن قائمة SELECT لكل استعلام علامة UNION ALL ويجب أن يحتوي العمود UNION ALL على قيمة رقمية ثابتة أو سلسلة ثابتة في كل فرع من فروع UNION ALL . علاوة على ذلك ، يجب أن يظهر عمود العلامة في الموضع الترتيبي نفسه في قائمة SELECT لكل كتلة استعلام. راجع " UNION ALL Marker and Query Rewrrite " لمزيد من المعلومات حول علامات UNION ALL .
  • بعض الميزات ، مثل الوصلات الخارجية ، واستعلامات طريقة العرض التجميعية المدمجة فقط ، والجداول غير البعيدة غير مدعومة UNION باستخدام UNION ALL . لاحظ ، مع ذلك ، أن طرق العرض الملموسة المستخدمة في النسخ المتماثل ، والتي لا تحتوي على روابط أو تجميعات ، يمكن تحديثها بسرعة عند استخدام UNION ALL أو الجداول البعيدة.
  • يجب ضبط معلمة تهيئة التوافق على 9.2.0 أو أعلى لإنشاء طريقة مشاهدة سريعة قابلة للتحديث باستخدام UNION ALL .

لا أريد الإساءة إلى معجبي Oracle ، ولكن استنادًا إلى قائمة القيود الخاصة بهم ، يبدو أن هذه الآلية لم تتم كتابتها في الحالة العامة باستخدام نوع من النماذج ، ولكن الآلاف من الهنود ، حيث سُمح للجميع بكتابة سلسلة الرسائل الخاصة بهم ، ويمكن لكل منهم وفعل. استخدام هذه الآلية لمنطق حقيقي يشبه المشي في حقل ألغام. في أي وقت ، يمكنك الحصول على منجم ، وضرب أحد القيود غير الواضحة. كيف يعمل هذا أيضًا مسألة منفصلة ، لكنها خارج نطاق هذه المقالة.

مايكروسوفت مزود خادم

متطلبات إضافية


بالإضافة إلى خيارات SET ومتطلبات الوظيفة الحتمية ، يجب تلبية المتطلبات التالية:
  • يجب أن يكون المستخدم الذي يقوم بتنفيذ CREATE INDEX هو مالك العرض.
  • عند إنشاء الفهرس ، يجب تعيين الخيار IGNORE_DUP_KEY على OFF (الإعداد الافتراضي).
  • يجب الرجوع إلى الجداول بأسماء من جزأين ، المخطط . tablename في تعريف العرض.
  • يجب إنشاء الوظائف المعرفة من قبل المستخدم المشار إليها في طريقة العرض باستخدام خيار WITH SCHEMABINDING .
  • يجب الرجوع إلى أي وظائف معرفة من قِبل المستخدم والمشار إليها في العرض بأسماء من جزأين ، <schema> . <وظيفة> .
  • يجب أن تكون خاصية الوصول إلى البيانات الخاصة بوظيفة معرفة من قبل المستخدم NO SQL ، ويجب أن تكون خاصية الوصول الخارجي NO .
  • يمكن أن تظهر وظائف وقت تشغيل اللغة العامة (CLR) في قائمة تحديد طريقة العرض ، ولكن لا يمكن أن تكون جزءًا من تعريف مفتاح الفهرس المجمع. لا يمكن أن تظهر وظائف CLR في جملة WHERE للعرض أو جملة ON لعملية JOIN في المشاهدة.
  • يجب أن يكون لوظائف وطرق CLR للأنواع المعرفة من قبل المستخدم والمستخدمة في تعريف العرض الخصائص المحددة كما هو موضح في الجدول التالي.
    ممتلكاتمذكرة
    DETERMINISTIC = صحيحيجب التصريح صراحة كخاصية مميزة لطريقة Microsoft .NET Framework.
    دقيقة = صحيحيجب التصريح صراحة كخاصية للأسلوب .NET Framework.
    الوصول إلى البيانات = لا SQLيتم تحديده عن طريق تعيين سمة DataAccess إلى DataAccessKind.None والخاصية SystemDataAccess إلى SystemDataAccessKind.None.
    الوصول الخارجي = لاهذه الخاصية الافتراضية إلى NO لإجراءات CLR.
  • يجب إنشاء العرض باستخدام خيار WITH SCHEMABINDING .
  • يجب أن يشير العرض إلى الجداول الأساسية الموجودة في نفس قاعدة البيانات مثل طريقة العرض. لا يمكن للعرض الرجوع إلى طرق عرض أخرى.
  • يجب ألا تحتوي عبارة SELECT في تعريف العرض على عناصر Transact-SQL التالية:
    COUNTوظائف ROWSET ( OPENDATASOURCE ، OPENQUERY ، OPENROWSET ، OPENXML )انضمام OUTER ( LEFT أو RIGHT أو FULL )
    جدول مشتق (معرف بواسطة تحديد SELECT في جملة FROM )، ينضم النفستحديد الأعمدة باستخدام SELECT * أو SELECT <table_name>.*
    DISTINCTSTDEV أو STDEVP أو VAR أو VARP أو AVGتعبير جدول شائع (CTE)
    تعويم الأعمدة 1 أو النص أو ntext أو الصورة أو XML أو filestreamفرعيجملة OVER ، والتي تتضمن وظائف نافذة الترتيب أو التجميع
    النص الكامل يتنبأ ( CONTAINS ، FREETEXT )دالة SUM تشير إلى تعبير فارغORDER BY
    وظيفة CLR المعرفة من قبل المستخدمTOPعوامل تشغيل CUBE أو ROLLUP أو ROLLUP GROUPING SETS
    MIN ، MAXعوامل التشغيل UNION أو EXCEPT أو INTERSECTTABLESAMPLE
    متغيرات الجدولOUTER APPLY أو CROSS APPLYPIVOT ، UNPIVOT
    مجموعات أعمدة متفرقةالدالات المضمنة (TVF) أو وظائف متعددة القيم الجدول (MSTVF)OFFSET
    CHECKSUM_AGG

    1 يمكن أن تحتوي طريقة العرض المفهرسة على أعمدة عائمة . ومع ذلك ، لا يمكن تضمين هذه الأعمدة في مفتاح الفهرس متفاوت المسافات.
  • في حالة وجود GROUP BY ، يجب أن يحتوي تعريف VIEW على COUNT_BIG(*) ويجب ألا يحتوي على HAVING . تنطبق قيود GROUP BY فقط على تعريف طريقة العرض المفهرسة. يمكن أن يستخدم الاستعلام طريقة عرض مفهرسة في خطة التنفيذ الخاصة به ، حتى لو لم يكن مستوفياً لقيود GROUP BY هذه.
  • إذا كان تعريف طريقة العرض يحتوي على جملة GROUP BY ، فيمكن لمفتاح الفهرس العنقودي الفريد الإشارة إلى الأعمدة المحددة في جملة GROUP BY .

هنا يمكنك أن ترى أن الهنود لم ينجذبوا ، لأنهم قرروا أن يفعلوا وفقًا للمخطط "سوف نفعل القليل ، ولكن الخير". أي أن لديهم المزيد من الألغام في الميدان ، لكن موقعها أكثر شفافية. الشيء الأكثر إثارة للحزن هو هذا القيد:
يجب أن يشير العرض إلى الجداول الأساسية الموجودة في نفس قاعدة البيانات مثل طريقة العرض. لا يمكن للعرض الرجوع إلى طرق عرض أخرى.

في مصطلحاتنا ، هذا يعني أن الوظيفة لا يمكنها الوصول إلى وظيفة أخرى ملموسة. إنها تقطع الأيديولوجية كلها في مهدها.
أيضًا ، يقلل هذا القيد (وكذلك في النص) بشكل كبير من حالات الاستخدام:
يجب ألا تحتوي عبارة SELECT في تعريف العرض على عناصر Transact-SQL التالية:
COUNTوظائف ROWSET ( OPENDATASOURCE ، OPENQUERY ، OPENROWSET ، OPENXML )انضمام OUTER ( LEFT أو RIGHT أو FULL )
جدول مشتق (معرف بواسطة تحديد SELECT في جملة FROM )، ينضم النفستحديد الأعمدة باستخدام SELECT * أو SELECT <table_name>.*
DISTINCTSTDEV أو STDEVP أو VAR أو VARP أو AVGتعبير جدول شائع (CTE)
تعويم الأعمدة 1 أو النص أو ntext أو الصورة أو XML أو filestreamفرعيجملة OVER ، والتي تتضمن وظائف نافذة الترتيب أو التجميع
النص الكامل يتنبأ ( CONTAINS ، FREETEXT )دالة SUM تشير إلى تعبير فارغORDER BY
وظيفة CLR المعرفة من قبل المستخدمTOPعوامل تشغيل CUBE أو ROLLUP أو ROLLUP GROUPING SETS
MIN ، MAXعوامل التشغيل UNION أو EXCEPT أو INTERSECTTABLESAMPLE
متغيرات الجدولOUTER APPLY أو CROSS APPLYPIVOT ، UNPIVOT
مجموعات أعمدة متفرقةالدالات المضمنة (TVF) أو وظائف متعددة القيم الجدول (MSTVF)OFFSET
CHECKSUM_AGG

يحظر الانضمام إلى الخارج والاتحاد والنظم BY وغيرها. ربما كان من السهل الإشارة إلى ما يمكن استخدامه أكثر من غيره. القائمة ربما تكون أصغر بكثير.

لتلخيص: مجموعة كبيرة من القيود في كل (لاحظت التجارية) DBMS مقابل لا شيء (باستثناء واحد منطقي وليس تقني) في تقنية LGPL. ومع ذلك ، تجدر الإشارة إلى أن تنفيذ هذه الآلية في المنطق العلائقي أكثر تعقيدًا إلى حد ما مما هو عليه في الوظيفة الموصوفة.

تطبيق


كيف يعمل؟ يستخدم بوستجرس ك "آلة افتراضية". يوجد في الداخل خوارزمية معقدة تبني الاستفسارات. هنا هو شفرة المصدر . وليس هناك مجرد مجموعة كبيرة من الاستدلال مع مجموعة من ifs. لذلك ، إذا كان لديك بضعة أشهر للدراسة ، فيمكنك محاولة فهم الهندسة المعمارية.

هل تعمل بكفاءة؟ فعال بما فيه الكفاية. لسوء الحظ ، إثبات هذا صعب. لا أستطيع إلا أن أقول إنك إذا نظرت في آلاف الطلبات الموجودة في التطبيقات الكبيرة ، فستكون في المتوسط ​​أكثر فاعلية من المطور الجيد. يمكن لمبرمج SQL ممتاز كتابة أي استعلام بشكل أكثر كفاءة ، ولكن مع وجود ألف استفسار ، لن يكون لديه أي دافع أو وقت للقيام بذلك. الشيء الوحيد الذي يمكنني الآن تقديمه كدليل على الفعالية هو أنه على أساس المنصة المبنية على قواعد البيانات هذه ، تعمل العديد من مشاريع نظام ERP التي يوجد فيها الآلاف من وظائف MATERIALIZED المختلفة ، مع الآلاف من المستخدمين وقواعد بيانات terrabyte مع مئات الملايين من السجلات العاملة على خادم ثنائي المعالج العادية. ومع ذلك ، يمكن لأي شخص اختبار / دحض الفعالية عن طريق تنزيل النظام الأساسي و PostgreSQL ، مما يتيح تسجيل استعلام SQL ومحاولة تغيير المنطق والبيانات هناك.

في المقالات التالية ، سأتحدث أيضًا عن كيفية تعليق القيود على الوظائف ، والعمل مع جلسات التغيير ، وغير ذلك الكثير.

Source: https://habr.com/ru/post/ar459066/


All Articles