ماذا سيكون المقال حول ، وبالتالي فإن الاسم يعني.
بالإضافة إلى ذلك ، سوف يشرح المؤلف سبب ضرورة ذلك من وجهة نظره ، بالإضافة إلى إخباره بأن SUBJ ليس مجرد تقنية عصرية ، ولكنه أيضًا "عمل ضروري بشكل مضاعف - ممتع ومفيد".
من المثير للاهتمام دائمًا أن نرى كيف يفعل العديد من الموهوبين شيئًا ما (لغة برمجة ، لماذا لا) ، ومعرفة بالضبط المشكلة التي يقومون بحلها والمهام التي حددوها لأنفسهم. وأيضا اختبار خلقهم على أنفسهم. عدم المقارنة مع الإبداعات الضخمة للجان العملاقة ، التي تضع الحفاظ على وئام الكون في المقدمة ، الذي يفهم كيف.
قارن ، على سبيل المثال ، مصير
FORTRAN و
PL / 1 . الذي سيتذكر الآن عن هذا PL / 1.
من وجهة النظر هذه ، على سبيل المثال ،
AWK ناجحة للغاية. تجدر الإشارة إلى أن
ألفريد أهو ، أحد مؤلفي
كتاب التنين ، باسم ألف ، هو
بيتر وينبرجر ، الذي كان له يد في فورتران 77 ، K هو
برايان كيرنيجان ، حيث سيكون بدونه. هذه اللغة مخصصة لمعالجة تدفقات النص أثناء التنقل في الأنابيب بين العمليات.
اللغة غير مطبوعة (
هذا ليس صحيحًا تمامًا ) ، يشبه بناء الجملة C تمامًا ، ولديه إمكانات التصفية ، والمصفوفات الترابطية ، وأحداث بدء / نهاية البث ، وحدث السطر الجديد ...
لقد أعجب المؤلف دائمًا بهذه اللغة أيضًا من خلال حقيقة أن المترجم الفوري لا يحتاج إلى تثبيته ، وهو موجود دائمًا في أنظمة شبيهة بـ UNIX ، وبموجب نظام Windows ، يكفي فقط نسخ الملف القابل للتنفيذ ويعمل كل شيء. ومع ذلك ، هذا ليس هو الحال.
في هذه العملية ، يتعين على المؤلف استخدام حزمة SQL + AWK في كثير من الأحيان ، وهذا هو السبب. SQL لا يزال لغة مبدئية مصممة للتحكم في تدفق البيانات. إنه يوفر فرصًا محدودة جدًا للعمل مع سياق تنفيذ الاستعلام في شكل وظائف تجميعية.
كيف ، على سبيل المثال ، لبناء رسم بياني ثنائي الأبعاد باستخدام SQL؟
ولكن لنفترض أن استخدام GROUP BY يعني الفرز ، وليس من دواعي سروري أن يكون لديك مئات الملايين (أو حتى أكثر) من الصفوف.
محدث: في التعليقات قاموا بتصحيح لي أن هذا ليس صحيحًا تمامًا (أو ليس صحيحًا على الإطلاق)يتمتع معالج SQL بالقدرة على تنفيذ الوظائف التجميعية في عملية إنشاء تجزئة وفقًا لمعايير التجميع. لهذا ، من الضروري أن تمتلك مساحة الذاكرة الخالية الكافية لوضع خريطة التجزئة في الذاكرة.
بعد ذلك ، سيتم تحديث سياقات المجموعات عند قراءة الجدول ، وفي نهاية هذه القراءة سيكون لدينا بالفعل نتيجة محسوبة.
يمكن تمديد نفس الأسلوب ليشمل وظائف النافذة (أدناه) ، وسيكون السياق "أكثر سمكا" فقط.
في الحالة التي يكون فيها عدد المجموعات غير معروف مقدمًا أو كبيرًا جدًا ، يضطر معالج SQL إلى إنشاء فهرس مؤقت وتشغيله في مسار ثانٍ.
في الحالات البسيطة ، على سبيل المثال ، مثل هنا - COUNT البسيط ، يكون الخيار العام ممكنًا - فهرس مؤقت (cx ، cy ، عدد) ، ثم مع عدد صغير من المجموعات ، ستكون جميعها في الذاكرة على الصفحات المخزنة مؤقتًا. في الحالات المعقدة ، وظائف النافذة ، تصبح حالة المجموعة غير تافهة وتسلسلها باستمرار (de) ليس على الإطلاق ما أمر به الطبيب.
ملخص: يلجأ معالج SQL إلى الفرز عندما يتعذر عليه تقدير عدد المجموعات بعد GROUP BY. ومع ذلك ، فإن التجميع حسب القيم المحسوبة هو (غالبًا) الحالة ذاتها.
لذلك ، عليك أن تفعل شيئًا مثل:
psql -t -q -c 'select x, y from samples' | gawk -f mk_hist2d.awk
حيث يقوم mk_hist2d.awk بتجميع الإحصاءات في الصفيف الترابطي ويعرضها عند الانتهاء من العمل
# mk_hist2d.awk { bucket[int($2*0.01), int($3*0.01)]+=$1; } END { for (i=0; i < 500; i++) for (j=0; j < 500; j++) { if ((i, j) in bucket) print i*100." "j*100." "bucket[i, j]; else print i*100." "j*100." 0"; } }
هناك واحد ولكن - يجب إرسال دفق البيانات الكامل من الخادم إلى الجهاز العامل ، وهذا ليس رخيصًا جدًا.
هل من الممكن الجمع بين اللطيف بطريقة أو بأخرى - تجميع الإحصائيات أثناء تنفيذ استعلام SQL ، ولكن دون اللجوء إلى الفرز؟ نعم ، على سبيل المثال ، باستخدام الوظائف التجميعية المخصصة.
الوظائف التجميعية المخصصة
Subj موجود في أنظمة مختلفة ، في كل مكان يتم القيام به قليلا بطريقتها الخاصة.
- PostgreSQL الوثائق هنا . مزيد من التفاصيل هنا .
هذا هو المكان الذي يتم فيه حساب الحد الأقصى لرصيد الحساب.
وهذا مثال يحسب ما هو أكثر في العمود المنطقي - صواب أو خطأ.
يبدو مثل هذا -
CREATE AGGREGATE mode(boolean) ( SFUNC = mode_bool_state, STYPE = INT[], FINALFUNC = mode_bool_final, INITCOND = '{0,0}' );
هنا SFUNC هي وظيفة تسمى لكل سطر في الدفق ،
الوسيطة الأولى في ذلك من النوع STYPE .
يتم استخدام FINALFUNC لإنهاء الحسابات وإرجاع قيمة التجميع.
INITCOND - تهيئة القيمة الأولية للحالة الداخلية ( STYPE ) ، تم تمريرها كوسيطة أولى.
نظرًا لأنه يمكن كتابة الوظائف في C (مما يعني أنه بالنسبة للحالة الداخلية يمكنك استخدام الذاكرة التي يتم تحريرها تلقائيًا عند إغلاق الطلب) ، فهذه أداة قوية للغاية. خارج نطاق استخدامه ، يجب أن يكون الشخص قادرًا على الاستمرار. - مرض التصلب العصبي المتعدد مزود
سابقا (2000) ، قبل الطلب ، كان من الضروري إنشاء كائن ActiveX ، للقيام التجميع باستخدام هذا الكائن.
الآن (2016+) يتم ذلك في بيئة CLR. سيتعين عليك إنشاء وظيفة مخصصة وإنشاء تجميع وتسجيله. ثم يمكنك إنشاء مجموع .
مثال لحساب المتوسط الهندسي ، وكذلك دمج السلاسل: مع معلمات إضافية ونوع المعرفة من قبل المستخدم لتخزين حالة وسيطة. - أوراكل
في Oracle ، يتم ذلك باستخدام خرطوشة بيانات ODCIAggregate (الواجهة).
لإنشاء مجموعتك الخاصة ، تحتاج إلى كتابة نوع مخصص يقوم بتنفيذ 4 طرق
- التهيئة (ODCIAggregateInitialize) ، ثابتة ، يجب أن تنشئ مثيلًا للنوع المرغوب وتعود خلال المعلمة
- التكرارات (ODCIAggregateIterate) ، تسمى في كل صف من البيانات
- دمج (ODCIAggregateMerge) ، يستخدم لدمج المجاميع المنفذة بالتوازي
- النهاية (ODCIAggregateTerminate) - إخراج النتيجة
أمثلة: 1 ، 2 ، 3 ، 4 . - DB2
لا توجد طريقة واضحة لاستخدام المجاميع المخصصة في DB2.
ولكن يمكنك تمرير وظيفة قياسية (وإن كان MAX) إلى نوع معرف من قبل المستخدم (في Java) وجعل النظام يقوم بتنفيذ استعلامات النموذج
CREATE TYPE Complex AS ( real DOUBLE, i DOUBLE ) … CREATE TABLE complexNumbers ( id INTEGER NOT NULL PRIMARY KEY, number Complex ) … SELECT sum..real, sum..i FROM ( SELECT GetAggrResult(MAX(BuildComplexSum(number))) FROM complexNumbers ) AS t(sum)
ما هو الجدير بالذكر في كل هذه الأنظمة؟
- بطريقة أو بأخرى ، ستحتاج إلى إنشاء بعض الكائنات في قاعدة البيانات. سواء كان ذلك الإجمالي أو النوع. كحد أدنى ، مطلوب الحقوق المناسبة. وتريد فقط إضافة عدد قليل من ركبته.
- قد تضطر إلى كتابة شيء بلغة أخرى ، سواء كانت C أو C # أو Java.
لدمج ما هو مكتوب في النظام ، مرة أخرى ، هناك حاجة إلى الحقوق. ولكن كل ما أريد ...
- صعوبة التهيئة. افترض أنك تريد قراءة الرسوم البيانية بأحجام سلة مختلفة. يبدو الأمر أسهل - سنشير إلى INITCOND المطلوب عند الإعلان عن الإجمالي (PostgreSQL) والعمل بأكمله. ولكن بعد كل حجم من السلة ، ستحتاج إلى مجموعتك الخاصة ، ومن أجل ذلك ، هناك حاجة إلى الحقوق.
هنا يمكنك اللجوء إلى خدعة قذرة وإزاحة معالج الاتحاد من خط التهيئة (للأمام) والبيانات ، وبناء السياق ليس في المنشئ ، ولكن عند استلام السطر الأول.
- ومع ذلك ، حتى مع القيود الموضحة ، تتيح لك المجاميع المخصصة حساب أي شيء.
- من المهم أن تتم موازاة المجاميع ، على الأقل PostgreSQL ، ويمكن لـ Oracle (Enterprise Edition) القيام بذلك. لهذا ، سيتعين على الحقيقة معرفة كيفية إجراء تسلسل / إلغاء تسلسل الحالات الوسيطة وأيضًا تجميدها المتلقاة من تدفقات مختلفة.
وظائف النافذة
ظهرت وظائف النافذة في معيار
SQL: 2003 . في الوقت الحالي ، يتم دعمها من قبل جميع الأنظمة المذكورة أعلاه. في جوهرها ، وظائف النافذة هي امتداد للعمل مع الوحدات. وبالطبع ، تعمل الدالات التجميعية المخصصة أيضًا في سياق مبني على إطارات.
التمديد هو هذا. وقبل SQL: 2003 ، عملت الدوال التجميعية في نافذة معينة ، والتي كانت إما مجموعة النتائج بأكملها أو جزء منها ، وهو ما يتوافق مع مجموعة قيم الحقول من تعبير GROUP BY. المستخدم لديه الآن بعض الحرية في التعامل مع هذه النافذة.
الفرق هو أن القيم المحسوبة باستخدام النوافذ تضاف إلى المخرجات في عمود منفصل ، ولا تتطلب أن ينهار الدفق بأكمله باستخدام الوظائف التجميعية. لذلك في طلب واحد ، يمكنك استخدام العديد من مجاميع النوافذ في سياقها الخاص (نافذة). قد يكون هناك العديد من الوظائف التجميعية من قبل ، لكنهم جميعا يعملون في نافذة واحدة.
ضربات كبيرة
- فوق ()
النافذة هي نتائج كاملة. دعنا نقول الاستعلام " select count (1) from Samples " بإرجاع 169. في هذه الحالة ، عند تشغيل " select count (1) over () من Samples " ، نحصل على عمود مكتوب 169 مرة 169 مرة. - فوق (جزء من)
إنه تمثيلي لـ GROUP BY ، لكل مجموعة من القيم يتم إنشاء نافذة يتم فيها تنفيذ الوظائف التجميعية. دعنا نقول أنه في جدول العينات ، يوجد عدد صحيح عمود واحد ، فالبيانات هي أرقام من 1 إلى 169.
ثم يقوم الاستعلام " select count (1) over (partition by (12 + val) / 13) من Samples " بإرجاع عمود تُكتب فيه القيمة 13 169 مرة.
- أكثر من (ترتيب حسب)
يمكن دمجه مع PARTITION BY ، مما يتيح لك تغيير حجم النافذة أثناء المؤشر بشكل ديناميكي ، في هذه الحالة ، تمتد النافذة من بداية المجموعة إلى موضع المؤشر الحالي. نتيجة لذلك ، بالنسبة للمجموعة ، لا تظهر القيمة نفسها في العمود التجميعي ، ولكن قيمتها الخاصة. مريحة لحساب المبالغ التراكمية. نتيجة الاستعلام
سيكون "اختيار sum (val) over (الترتيب حسب val) من Samples " بمثابة عمود يحتوي فيه العنصر nth على مجموع الأرقام الطبيعية من 1 إلى n. - فوق (الصفوف)
يسمح لك بتحديد إطارات النوافذ ، بدءًا من موضع المؤشر أو بداية / نهاية نطاق ORDER BY.
على سبيل المثال ، " ... ROWS 1 PRECEDING ... " تعني أن النافذة تتكون من السطر الحالي و 1 قبله. " ... الصفوف بين 1 التالية و 2 التالية ... " - تتكون النافذة من سطرين بعد المؤشر مباشرة.
يشير المسار الحالي في هذا الوضع إلى موضع المؤشر الحالي. على سبيل المثال ، يعني " الصفوف بين الصفوف الحالية والمتابعة التالية " من السطر الحالي إلى نهاية النطاق. - فوق (النطاق)
يختلف عن ROWS في ذلك يعني CURRENT ROW هنا بداية النافذة من بداية ORDER BY ، ونهاية النافذة - السطر الأخير من نطاق ORDER BY.
يختلف بناء جملة استخدام وظائف النافذة على أنظمة مختلفة اختلافًا طفيفًا.
لتلخيص ما ورد أعلاه ، لا يزال هناك شعور مؤلم بعض الشيء بأن المطورين ، بعد أن قاموا بتحليل بناء تقارير مختلفة في SQL ، سلطوا الضوء على الحالات الأكثر شيوعًا وخففوها بإحكام في بناء الجملة.
سجل عائدات وظائف
في مخرجات وظائف التجميع / النافذة ، يتوافق كل صف ناتج مع نطاق معين من الصفوف من دفق البيانات الواردة. في الحياة ، مثل هذه المراسلات لا وجود لها دائما.
على سبيل المثال ، يلزم بناء مصفوفة التغاير 10X10 (
لهذا ، قد يستغرق الأمر 672X672).
يمكن القيام بذلك في مسار واحد ، لهذا نقوم بتنفيذ الدالة التجميعية المكتوبة من قبلنا مع 10 معلمات رقمية. نتيجة عملها هي مجموعة سجلات من 10 صفوف من 10 قيم ، يشير كل عنصر من عناصر المصفوفة إلى جميع صفوف دفق الإدخال (بغض النظر عن عدد الصفوف الموجودة).
يمكننا القول - إذن ، في PostgreSQl ، على سبيل المثال ،
يمكنك إرجاع صفيف ثنائي الأبعاد من دالة (على سبيل المثال: ARRAY [[1،2] ، [3،4] '). أو مجرد إجراء تسلسل للمصفوفة في صف واحد.
إنه أمر جيد ، لكن ليس من الممكن دائمًا الحفاظ على حجم النتيجة ضمن الإطار مقبولًا لهذا النهج.
انحدار غنائيعلى سبيل المثال ، مهمتنا هي تعميم الهندسة.
حجم الأشكال الهندسية غير معروف لنا ، فقد يكون أيضًا ساحل أوراسيا من عشرات الملايين من النقاط. أو العكس ، هناك هندسة تقريبية للغاية ، تحتاج إلى سلاسة الخطوط. أرغب في تمرير المعلمات إلى التجميع والحصول على دفق البيانات بدلاً من ناقل أو سلسلة.
يمكنك ، بالطبع ، أن تقول إن المشكلة بعيدة المنال ، وأنه لا أحد يفعل ذلك ، حيث يتم تخزين الأشكال الهندسية في نظام إدارة قواعد البيانات بطريقة خاصة ، وهناك برامج خاصة لمعالجة الأشكال الهندسية ، ...
في الواقع ، من المريح تمامًا تخزين الأشكال الهندسية في الجداول العادية بطريقة لا معنى لها ، وذلك لأنه من خلال تحريك نقطة واحدة ، ليست هناك حاجة لإعادة كتابة النقطة بالكامل. قبل تسرب البيانات المكانية في كل مكان في DBMS ، كان ، على سبيل المثال ، في
ArcSDE .
بمجرد أن يتجاوز متوسط حجم النقطة النقطية حجم الصفحة ، يصبح العمل مع النقاط أكثر ربحية. إذا كانت هناك فرصة مادية للعمل مع تدفق النقاط ، فربما تعود عجلة التاريخ مرة أخرى.
لا تزال مصفوفة التغاير ليست مثالًا جيدًا على عدم التزامن بين تدفقات المدخلات والمخرجات ، حيث يتم الحصول على النتيجة بأكملها في وقت واحد في النهاية. افترض أنك تريد معالجة / ضغط دفق بيانات المصدر. في نفس الوقت
- هناك الكثير من البيانات ، فهي في "الكومة" بدون مؤشرات ، في الواقع كانت ببساطة "بسرعة" مكتوبة على القرص
- تحتاج إلى فرزها إلى فئات مختلفة ، وهي قليلة نسبيًا
- ضمن الفئات ، ومتوسط فترات زمنية ، تخزين متوسط فقط ، عدد القياسات والتباين
- كل هذا يجب القيام به بسرعة
ما هي الخيارات؟
- ضمن SQL ، يكون الفرز حسب الفترة الزمنية / الفئة مطلوبًا ، وهو ما يتناقض مع النقطة الأخيرة.
- إذا تم فرز البيانات بالفعل حسب الوقت (وهو في الواقع غير مضمون) ، وسيكون من الممكن نقل هذه الحقيقة إلى معالج SQL ، يمكنك القيام بوظائف النافذة وتمريرة واحدة.
- اكتب تطبيقًا منفصلاً سيفعل كل هذا. في PL / SQL أو ، على الأرجح ، نظرًا لوجود الكثير من البيانات ، في C / C ++.
- الوظائف التي ترجع السجلات. ربما يمكنهم مساعدتنا.
مزيد من التفاصيل حول A.4. هناك آليتان لهذا - الجداول المؤقتة ووظائف خطوط الأنابيب.
- وظائف الناقل.
ظهرت هذه الآلية في Oracle (بدءًا من 9i ، 2001) وتسمح للوظيفة التي أرجعت مجموعة السجلات بعدم تجميع البيانات ، ولكن لحسابها حسب الحاجة (عن طريق القياس مع تزامن stdout و stdin من عمليتين متصلتين عبر توجيه الإخراج).
أي قد تبدأ نتائج وظائف خطوط الأنابيب في المعالجة قبل الخروج من هذه الوظيفة. للقيام بذلك ، يكفي القول في تعريف الوظيفة
FUNCTION f_trans(p refcur_t) RETURN outrecset PIPELINED IS …
وتسجيل خطوط النتيجة في الجسم
LOOP … out_rec.var_char1 := in_rec.email; out_rec.var_char2 := in_rec.phone_number; PIPE ROW(out_rec); … END LOOP;
نتيجة لذلك ، لدينا
SELECT * FROM TABLE( refcur_pkg.f_trans( CURSOR(SELECT * FROM employees WHERE department_id = 60)));
ليست هناك حاجة إلى المجاميع المخصصة عند وجود وظائف خطوط الأنابيب.
برافو ، أوراكل!
منذ وقت ليس ببعيد (2014) ، ظهرت وظائف خطوط الأنابيب أيضًا في DB2 (IBM i 7.1 TR9 ، i 7.2 TR1). - الجداول المؤقتة.
بادئ ذي بدء ، يبدو أنه لا يمكن لـ MS SQL أو PostgreSQL إرجاع مؤشر من دالة تجميعية.
حسنًا ، دعنا ، عن طريق قياس وظائف خط الأنابيب ، نحصل على المؤشر كمعلمة ، وقم بمعالجته ، وأضفه إلى جدول مؤقت وأعد المؤشر إليه.
ومع ذلك ، في MS SQL ، لا يمكن تمرير المؤشر إلى إجراء مخزن بواسطة معلمة ، فمن الممكن فقط إنشاء مؤشر في الإجراء وإرجاع المعلمة خلال الإخراج. يمكن قول الشيء نفسه بالنسبة لـ PostgreSQL.
حسنًا ، حسنًا ، ما عليك سوى فتح المؤشر وطرحه ومعالجة القيم وحساب النتيجة وإضافتها إلى الجدول المؤقت وعرض المؤشر.
أو حتى أكثر بساطة ، نضيف نتائج الاستعلام إلى جدول مؤقت واحد ، ونعالجها ونعيد النتائج من خلال المؤشر إلى جدول مؤقت آخر.
ماذا يمكنني أن أقول. أولاً ، والأهم من ذلك ، قراءة البيانات من خلال المؤشر أبطأ من المعالجة في الدفق. ثانياً ، لماذا تحتاج إذن إلى معالج SQL على الإطلاق ، دعونا نقرأ الجداول التي تحتوي على مؤشرات ، وننشئ جداول مؤقتة بأيدينا ، ونكتب منطق الانضمام في حلقات ... إنه مثل إدراج أداة التجميع في C / C ++ ، وأحيانًا يمكنك التعامل مع نفسك ، لكن من الأفضل عدم إساءة استخدامه.
لذلك ، بعد أن نظرنا في سؤال مع إرجاع الدالات لمجموعة السجلات ، توصلنا إلى استنتاجات:
- المجاميع المخصصة لن تساعدنا حقًا هنا.
- في أي حال ، سوف تحتاج إلى إنشاء بعض الكائنات في قاعدة البيانات. سواء كان ذلك وظائف أو الجداول المؤقتة. كحد أدنى ، مطلوب الحقوق المناسبة. وتريد فقط معالجة بعض الأرقام.
- ومع ذلك ، حتى في ظل القيود الموضحة ، فإنها في بعض الأحيان ليست أنيقة للغاية ، ولكن مع هذه الطريقة يمكنك حل المشكلة.
ماذا بعد
في الواقع ، إذا كانت لدينا بالفعل فرصة لحل المشكلات ، فما الذي يحتاجه المؤلف؟
في الواقع ، يمكن لآلة تورنج أيضًا حساب أي شيء ، هل هو ليس سريعًا جدًا وغير مناسب للغاية.
نقوم بصياغة المتطلبات على النحو التالي:
- يجب أن يكون عامل تشغيل علائقي يمكن استخدامه على قدم المساواة مع الباقي (الاختيار ، الإسقاط ، ...)
- يجب أن يكون المشغل الذي يحول دفق البيانات إلى آخر
- لا يوجد التزامن بين تدفقات المدخلات والمخرجات
- تعريف المشغل يحدد هيكل تيار الإخراج
- يمتلك المشغل القدرة على التهيئة الديناميكي (في شكل دالة ، بدقة أكثر جسمها ، المحدد مباشرة في تعريف المشغل)
- وكذلك المدمر في شكل وظيفة (...)
- بالإضافة إلى وظيفة (...) تسمى في كل مرة يتم تلقي خط جديد من دفق الإدخال
- المشغل لديه سياق التنفيذ - مجموعة محددة من قبل المستخدم من المتغيرات و / أو المجموعات اللازمة للعمل
- لتشغيل هذا المشغل ، لا تحتاج إلى إنشاء كائنات قاعدة بيانات ، لا تحتاج إلى حقوق إضافية
- يتم تعريف كل ما هو مطلوب للعمل في مكان واحد ، بلغة واحدة
ذات
مرة ، قام المؤلف بإنشاء مثل هذا المشغل الذي يمد المعالج العصامي للمجموعة الفرعية المنفذة من
TTM / البرنامج التعليمي D. الآن يتم اقتراح نفس الفكرة ل SQL.
الأمر يستحق التحذير ، هنا ينتهي SQL ويبدأ الارتجال. يتم ترك الجملة كما كانت في الأصل ، في النهاية ، يمكن أن يكون السكر النحوي أي شيء ، فهو لا يغير الجوهر.
لذلك ، المشغل
مضغ يتكون من
- رأس يحتوي على قائمة حقول الإخراج وأنواعها.
كل حقل الإخراج (والمدخلات) هو متغير محلي.
على سبيل المثال: تعويم "مضغ {" var1 "،" var2 "integer}" يعني أنه سيكون هناك عمودين في دفق الإخراج - نقطة عائمة وأعداد صحيحة - الهيئات - قائمة من عمليات الاسترجاعات للأحداث ، في الوقت الحالي - بداية الدفق ، نهاية الدفق ، السطر. بواسطة بناء الجملة ، وظائف قريبة من PL / SQL. الدالة المحددة مسبقًا __interrupt () هي نظير لـ PIPE ، وهي تأخذ القيم من المتغيرات المقابلة لأعمدة الإخراج وتضعها في دفق الإخراج. في حالة تجاوز سعة المخزن المؤقت لدفق الإخراج ، سيتوقف عمل المعالج وسيبدأ العمل في جانب المتلقي للتيار.
على سبيل المثال: "hook" init "{var1: = 0؛ var2: = -1 ؛ } "
أسهل طريقة لإظهار الأمثلة.
- تمثيلي للدالة الإجمالية SUM.
تبدو ضخمة ، لكنها مجرد مثال ،
ليس من الضروري كتابة برنامج C لإضافة بضعة أرقام. - مجموع + متوسط
هنا نلفت الانتباه إلى حقيقة أن الجمع يحدث مرة واحدة فقط. - مجموع + مجموعة BY
- ROW_NUMBER () OVER ()
هل من الممكن تقديم مثال على هذا النهج يعطي نتائج غير قابلة للتحقيق بشكل أساسي بالطريقة المعتادة؟ لدينا لهم.
في بعض الأحيان يحدث أن يتم فرز البيانات تقريبا. قد يتم فرزها تمامًا ، لكنها غير معروفة بالتأكيد.
افترض أنه في المثال أعلاه (ضغط دفق البيانات) ، تأتي البيانات من مصادر مختلفة ، ويمكن أن تكون مختلطة قليلاً لأسباب مختلفة. أي T1 T2 T1 < T2.
, T1 T2 () , ( ) .
, , , , .
.
, .
.
هذا الثابت مميز فقط لهذه المشكلة ، وربما فقط لهذه التجربة.ونحن نستخدم هذا الاختراق على مسؤوليتنا لتجنب الفرز.لا تتوفر معرفتنا القياسية للمهمة بطريقة قياسية لإخبار معالج SQL ، ومن الصعب تخيله.واستخدام وظائف lambda يوفر طريقة عالمية لإجبار معالج SQL على القيام بما نحتاج إليه بالضبط.الخاتمة
التصميم المقترح لا يبدو صعب التنفيذ.في أي حال ، مع PL / SQL صالحة.الفكرة بحد ذاتها بسيطة وبديهية ولا تضيف كيانات جديدة إلى اللغة.هذه وحدة واحدة ، والتي ، إذا لزم الأمر ، تحل محل الوظائف التجميعية والنافذة ، GROUP BY.آلية تسمح لك بالاستغناء عن الفرز حيث لا توجد طريقة مع معالج SQL التقليدي.ولكن الأهم من ذلك ، إنها آلية تمنحك الحرية في فعل ما تريد بالطريقة الأكثر إلحاحًا مع البيانات.ملاحظة: بفضل Dorofei Proleskovsky لمشاركتها في إعداد المقال.