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

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

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

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

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

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

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

سيقوم النظام نفسه بإنشاء جدول واحد بمفاتيح الكتابة التسجيل كعميل, منتج и 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;

منذ لهذه الوظيفة com.isParent تم وضع علامة MATERIALIZED، ثم سيتم إنشاء جدول به مفتاحين (مجموعتين)، حيث يكون الحقل com.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;

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

المزايا

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

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

النظير

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

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

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

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 لا يمكن أن تحتوي طرق العرض المتحققة على جداول تفاصيل بعيدة.
  • يجب أن تحتوي طرق العرض الفعلية المتداخلة على صلة أو تجميع.
  • وجهات نظر الانضمام المتحققة وطرق العرض المجمعة المتحققة مع أ GROUP BY لا يمكن تحديد جملة من جدول منظم بالفهرس.

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

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

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

كما أن طريقة التحديث التي تختارها لن تكون فعالة على النحو الأمثل إذا:

  • يستخدم الاستعلام المحدد صلة خارجية تعمل مثل صلة داخلية. إذا كان الاستعلام التعريفي يحتوي على مثل هذه الصلة، ففكر في إعادة كتابة الاستعلام التعريفي ليحتوي على صلة داخلية.
  • 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) يجب أن يكون حاضر. توصي أوراكل بذلك SUM(expr) تكون محددة.
  • If VARIANCE(expr) or STDDEV(expr) محدد، COUNT(expr) و SUM(expr) يجب تحديدها. توصي أوراكل بذلك SUM(expr *expr) تكون محددة.
  • SELECT لا يمكن أن يكون العمود الموجود في الاستعلام المحدد تعبيرًا معقدًا يحتوي على أعمدة من جداول أساسية متعددة. الحل البديل المحتمل لذلك هو استخدام طريقة عرض متداخلة.
  • SELECT يجب أن تحتوي القائمة على الكل GROUP BY الأعمدة.
  • لا يعتمد العرض الفعلي على واحد أو أكثر من الجداول البعيدة.
  • إذا كنت تستخدم CHAR نوع البيانات في أعمدة التصفية لسجل العرض الفعلي، يجب أن تكون مجموعات الأحرف الخاصة بالموقع الرئيسي والعرض الفعلي هي نفسها.
  • إذا كان العرض الفعلي يشتمل على أحد العناصر التالية، فسيتم دعم التحديث السريع فقط على إدراجات DML التقليدية والأحمال المباشرة.
    • وجهات نظر ملموسة مع MIN or MAX المجاميع
    • وجهات النظر المادية التي لديها SUM(expr) لكن لا COUNT(expr)
    • مناظر مجسدة بدون COUNT(*)

    يُطلق على هذا العرض المتحقق اسم العرض المتحقق للإدراج فقط.

  • وجهة نظر متجسدة مع MAX or MIN يمكن تحديثه بسرعة بعد حذف عبارات DML أو خلطها إذا لم يكن بها ملف WHERE الشرط.
    الحد الأقصى/الدقيقة للتحديث السريع بعد الحذف أو DML المختلط ليس له نفس سلوك حالة الإدراج فقط. يقوم بحذف وإعادة حساب القيم القصوى / الدقيقة للمجموعات المتأثرة. يجب أن تكون على دراية بتأثير أدائها.
  • طرق عرض متحققة مع طرق عرض مسماة أو استعلامات فرعية في ملف FROM يمكن تحديث الجملة بسرعة بشرط إمكانية دمج طرق العرض بالكامل. للحصول على معلومات حول طرق العرض التي سيتم دمجها، راجع مرجع لغة SQL لقاعدة بيانات أوراكل.
  • إذا لم تكن هناك صلات خارجية، فقد يكون لديك تحديدات وروابط عشوائية في WHERE الشرط.
  • تكون طرق العرض المجمعة المادية ذات الصلات الخارجية قابلة للتحديث بسرعة بعد DML التقليدي والأحمال المباشرة، بشرط تعديل الجدول الخارجي فقط. بالإضافة إلى ذلك، يجب أن توجد قيود فريدة على أعمدة الربط لجدول الربط الداخلي. إذا كانت هناك صلات خارجية، فيجب ربط كافة الصلات عن طريق ANDق ويجب استخدام المساواة (=) المشغل أو العامل.
  • للحصول على آراء محققة مع CUBE, ROLLUPأو تجميع المجموعات أو تسلسلها، تنطبق القيود التالية:
    • 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 عامل على أعلى مستوى.

    UNION ALL لا يمكن تضمين عامل التشغيل داخل استعلام فرعي، مع استثناء واحد: The UNION ALL يمكن أن يكون في استعلام فرعي في FROM شرط بشرط أن يكون الاستعلام التعريفي من النموذج SELECT * FROM (عرض أو استعلام فرعي مع UNION ALL) كما في المثال التالي:

    إنشاء عرض view_with_unionall AS
    (حدد c.rowid crid، c.cust_id، 2 umarker
     من العملاء ج حيث c.cust_last_name = 'Smith'
     الاتحاد الكل
     حدد c.rowid crid، c.cust_id، 3 umarker
     من العملاء ج حيث c.cust_last_name = 'Jones')؛
    
    إنشاء عرض مادي unionall_inside_view_mv
    قم بالتحديث بسرعة عند الطلب
    اختر * من view_with_unionall؛
    

    لاحظ أن الرأي view_with_unionall يلبي متطلبات التحديث السريع.

  • كل كتلة استعلام في UNION ALL يجب أن يفي الاستعلام بمتطلبات العرض الفعلي السريع القابل للتحديث مع التجميعات أو العرض الفعلي السريع القابل للتحديث مع الصلات.

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

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

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

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

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

بالإضافة إلى خيارات SET ومتطلبات الوظيفة الحتمية، يجب استيفاء المتطلبات التالية:

  • المستخدم الذي ينفذ CREATE INDEX يجب أن يكون صاحب الرأي.
  • عند إنشاء الفهرس، IGNORE_DUP_KEY يجب ضبط الخيار على OFF (الإعداد الافتراضي).
  • يجب أن تتم الإشارة إلى الجداول بأسماء مكونة من جزأين، مخطط.TABLENAME في تعريف العرض.
  • يجب إنشاء الوظائف المعرفة من قبل المستخدم والمشار إليها في طريقة العرض باستخدام WITH SCHEMABINDING الخيار.
  • يجب الإشارة إلى أي وظائف معرفة من قبل المستخدم يتم الرجوع إليها في طريقة العرض بأسماء مكونة من جزأين، ..
  • يجب أن تكون خاصية الوصول إلى البيانات للوظيفة المعرفة من قبل المستخدم NO SQLويجب أن تكون خاصية الوصول الخارجي NO.
  • يمكن أن تظهر وظائف وقت تشغيل اللغة العامة (CLR) في القائمة المحددة لطريقة العرض، ولكن لا يمكن أن تكون جزءًا من تعريف مفتاح الفهرس المجمع. لا يمكن أن تظهر وظائف CLR في جملة WHERE الخاصة بطريقة العرض أو جملة ON الخاصة بعملية JOIN في طريقة العرض.
  • يجب أن تحتوي وظائف CLR وأساليب الأنواع المعرفة من قبل المستخدم CLR المستخدمة في تعريف العرض على مجموعة الخصائص كما هو موضح في الجدول التالي.

    الممتلكات
    ملاحظات

    الحتمية = صحيح
    يجب أن يتم التصريح عنها بشكل صريح كسمة لأسلوب Microsoft .NET Framework.

    دقيق = صحيح
    يجب أن يتم التصريح عنها بشكل صريح كسمة لأسلوب ‎.NET Framework.

    الوصول إلى البيانات = لا يوجد SQL
    يتم تحديده عن طريق تعيين سمة DataAccess إلى DataAccessKind.None وسمة SystemDataAccess إلى SystemDataAccessKind.None.

    الوصول الخارجي = لا
    يتم تعيين هذه الخاصية افتراضيًا على NO لإجراءات CLR.

  • يجب إنشاء العرض باستخدام WITH SCHEMABINDING الخيار.
  • يجب أن تشير طريقة العرض فقط إلى الجداول الأساسية الموجودة في نفس قاعدة البيانات مثل طريقة العرض. لا يمكن أن تشير طريقة العرض إلى طرق عرض أخرى.
  • يجب ألا تحتوي عبارة SELECT في تعريف العرض على عناصر Transact-SQL التالية:

    COUNT
    وظائف مجموعة الصفوف (OPENDATASOURCE, OPENQUERY, OPENROWSET، و OPENXML)
    OUTER ينضم(LEFT, RIGHTالطرق أو FULL)

    الجدول المشتق (يتم تعريفه عن طريق تحديد أ 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

    مجموعات أعمدة متفرقة
    وظائف مضمنة (TVF) أو وظائف ذات قيمة جدولية متعددة البيانات (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 يمكن أن يحتوي العرض المفهرس الطفو أعمدة؛ ومع ذلك، لا يمكن تضمين مثل هذه الأعمدة في مفتاح الفهرس متفاوت المسافات.

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

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

يجب أن تشير طريقة العرض فقط إلى الجداول الأساسية الموجودة في نفس قاعدة البيانات مثل طريقة العرض. لا يمكن أن تشير طريقة العرض إلى طرق عرض أخرى.

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

يجب ألا تحتوي عبارة SELECT في تعريف العرض على عناصر Transact-SQL التالية:

COUNT
وظائف مجموعة الصفوف (OPENDATASOURCE, OPENQUERY, OPENROWSET، و OPENXML)
OUTER ينضم(LEFT, RIGHTالطرق أو FULL)

الجدول المشتق (يتم تعريفه عن طريق تحديد أ 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

مجموعات أعمدة متفرقة
وظائف مضمنة (TVF) أو وظائف ذات قيمة جدولية متعددة البيانات (MSTVF)
OFFSET

CHECKSUM_AGG

يحظر الانضمام الخارجي، والاتحاد، والطلب بواسطة وغيرها. ربما كان من الأسهل تحديد ما يمكن استخدامه بدلاً من تحديد ما لا يمكن استخدامه. من المحتمل أن تكون القائمة أصغر بكثير.

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

تطبيق

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

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

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

المصدر: www.habr.com

إضافة تعليق