MySQL الوظائف: سلسلة، رقمية، محددة من قبل المستخدم، مخزنة

⚡ ملخص ذكي

MySQL تقوم الدوال بتحويل البيانات قبل تخزينها أو استرجاعها، وتعيد نتيجة محسوبة واحدة. تشرح هذه المقالة الدوال المدمجة للسلاسل النصية والأرقام والتواريخ، ثم توضح كيف تُوسّع الدوال المخزنة والمُعرّفة من قِبل المستخدم محرك قاعدة البيانات نفسه.

  • 🔤 دوال السلاسل النصية: تقوم الدوال UCASE و LCASE و CONCAT بإعادة تشكيل النص في وقت الاستعلام؛ وتسمي العمود المحسوب بـ AS بحيث تحمل مجموعة النتائج عنوانًا قابلاً للقراءة.
  • 🔢 رقمية Operaتورس: تقوم الدالة DIV بقسمة الأعداد الصحيحة، وتعيد الدالة / ناتج القسمة العشري، وتعيد الدالة % (أو MOD) باقي القسمة.
  • 📅 وظائف التاريخ: تقوم الدالة DATE_FORMAT بتحويل قيمة YYYY-MM-DD المخزنة إلى أي نمط عرض، مثل %d-%m-%Y، دون تغيير سطر واحد من كود التطبيق.
  • 🛠️ الوظائف المخزنة: تقوم الدالة CREATE FUNCTION بتسجيل منطق قابل لإعادة الاستخدام داخل الخادم؛ قم بتعريفها على أنها غير حتمية كلما استدعى الجسم الدالة CURDATE() أو NOW().
  • ⚙️ الوظائف المحددة من قبل المستخدم: إجراءات خارجية مكتوبة بلغة C أو C++ يتم تجميعها في الخادم ثم تتصرف تمامًا مثل الوظائف الأصلية.
  • 🚀 تأثير الأداء: يؤدي دفع العمليات الحسابية إلى قاعدة البيانات إلى إزالة المنطق المكرر من كل تطبيق عميل وتقليل عدد مرات الوصول إلى الشبكة.

ما هي MySQL المهام؟

MySQL يمكن أن تفعل أكثر بكثير من مجرد تخزين البيانات واسترجاعها. فإنه يمكن أيضا إجراء عمليات التلاعب على البيانات قبل استرجاعها أو حفظها. هذا هو المكان الذي MySQL هنا يأتي دور الدوال. الدوال هي ببساطة أجزاء من التعليمات البرمجية التي تُنفذ عملية ما ثم تُعيد نتيجة. بعض الدوال تقبل مُعاملات، بينما لا تقبل دوال أخرى أي مُعاملات.

لنلقِ نظرة سريعة على مثال. بشكل افتراضي، MySQL يحفظ أنواع بيانات التاريخ بتنسيق "YYYY-MM-DD". لنفترض أننا أنشأنا تطبيقًا ويريد المستخدمون إرجاع التاريخ بتنسيق "DD-MM-YYYY". يمكننا استخدام MySQL تُستخدم الدالة المدمجة DATE_FORMAT لتحقيق ذلك. تُعدّ DATE_FORMAT إحدى أكثر الدوال استخدامًا في MySQLوسنتناول هذا الموضوع بالتفصيل لاحقاً في هذا الدرس.

مهما كان نوعها، فإن الدالة دائماً ما تُرجع قيمة واحدة, قد يقبل صفرًا أو أكثر من المعاملات داخل الأقواس، و يمكن استخدامها في أي مكان يُسمح فيه باستخدام تعبير ما — في قائمة SELECT، أو عبارة WHERE، أو عبارة ORDER BY.

لماذا الاستخدام MySQL المهام؟

الآن وقد عرفنا ما هي الدالة، فإن السؤال التالي هو لماذا يجب علينا دفع هذا العمل إلى قاعدة البيانات على الإطلاق.

لماذا استخدام MySQL وظائف

كما يوضح الرسم البياني أعلاه، تأخذ الدالة قيمة إدخال، وتطبق المنطق مرة واحدة داخل محرك قاعدة البيانات، وتعيد نتيجة واحدة إلى كل تطبيق يطلبها.

قد يفكر المبرمجون: "لماذا نتعب أنفسنا بـ MySQL هل يمكن تحقيق نفس التأثير باستخدام لغة برمجة نصية أو لغة برمجة؟ صحيح أنه يمكننا تحقيق ذلك عن طريق كتابة إجراء في برنامج التطبيق.

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

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

سبب آخر للنظر فيه MySQL تتمثل وظائفها في أنها تساعد في تقليل حركة مرور الشبكة في تطبيقات العميل/الخادملا تحتاج طبقة الأعمال إلا إلى استدعاء الدالة المخزنة، دون الحاجة إلى جلب البيانات الخام عبر الشبكة لمعالجتها. في المتوسط، يمكن أن يُحسّن استخدام الدوال أداء النظام بشكل كبير.

انواع من MySQL وظائف

بعد تحديد "ماذا" و"لماذا"، يمكننا الآن النظر إلى مجموعات الدوال الثلاث MySQL يوفر: وظائف مدمجة، ووظائف مخزنة، ووظائف معرفة من قبل المستخدم.

المدمج في وظائف

MySQL يأتي البرنامج مزودًا بعدد من الوظائف المدمجة - وهي وظائف تم تنفيذها بالفعل في MySQL الخادم. فهي تسمح لنا بإجراء أنواع عديدة من المعالجة على البيانات، وتندرج ضمن المجموعات الشائعة الاستخدام التالية.

  • وظائف سلسلة - العمل على أنواع البيانات السلسلة
  • وظائف رقمية - العمل على أنواع البيانات الرقمية
  • وظائف التاريخ - العمل على أنواع بيانات التاريخ
  • وظائف مجمعة - العمل على جميع أنواع البيانات المذكورة أعلاه وإنتاج مجموعات نتائج موجزة.
  • وظائف أخرى - MySQL كما يدعم أنواعًا أخرى من الوظائف المدمجة، لكننا سنقتصر في هذا الدرس على المجموعات المذكورة أعلاه.

لنلقِ نظرة الآن على كل مجموعة من المجموعات المذكورة أعلاه بالتفصيل. سنشرح الوظائف الأكثر استخدامًا باستخدام قاعدة بيانات "Myflixdb" النموذجية.

وظائف سلسلة

تتعامل دوال السلاسل النصية مع القيم النصية. في جدول الأفلام لدينا، تُخزَّن العناوين باستخدام مزيج من الأحرف الصغيرة والكبيرة. لنفترض أننا نريد استعلامًا يُعيد العناوين بأحرف كبيرة. تأخذ دالة "UCASE" سلسلة نصية كمعامل، وتحوّل كل حرف إلى حرف كبير، كما يوضح النص البرمجي أدناه.

SELECT `movie_id`, `title`, UCASE(`title`) AS `upper_case_title` FROM `movies`;

هنا

  • UCASE(`title`) هي الدالة المدمجة التي تأخذ العنوان كمعامل وتعيده بأحرف كبيرة.
  • AS `upper_case_title` يُعطي العمود المحسوب اسمًا بديلًا، بحيث تحمل مجموعة النتائج عنوانًا قابلًا للقراءة بدلًا من التعبير الخام.

تنفيذ البرنامج النصي أعلاه في MySQL يُظهر لنا برنامج Workbench النتائج الموضحة أدناه عند استخدامه مع قاعدة بيانات Myflixdb.

movie_id الاسم عنوان بأحرف كبيرة
16 67% مذنب 67% مذنب
6 الملائكة والشياطين ملائكة وشياطين
4 Code الاسم: بلاك الاسم الرمزي: أسود
5 بنات أبي الصغيرات بنات أبي الصغيرات
7 دافينشي Code شيفرة دافنشي
2 نسيان سارة مارشال نسيان سارة مارشال
9 Honey moonالمتطلبات البيئية هوني MOONERS
19 فيلم 3 الفيلم الثالث
1 قراصنة الكاريبي 4 قراصنة الكاريبي 4
18 فيلم تجريبي فيلم تجريبي
17 الديكتاتور العظيم الديكتاتور العظيم
3 X رجال X-MEN

هناك رفيقان جديران بالذكر إلى جانب UCASE: LCASE يحوّل سلسلة نصية إلى أحرف صغيرة، و كونكات يجمع هذا الأمر سلسلتين نصيتين أو أكثر في سلسلة نصية واحدة. للاطلاع على القائمة الكاملة، راجع MySQL مرجع دالة السلسلة.

وظائف رقمية

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

العمليات الحسابية

MySQL يدعم عوامل التشغيل الحسابية التالية، والتي يمكن استخدامها لإجراء العمليات الحسابية في عبارات SQL.

الاسم الوصف
DIV تقسيم صحيح
/ تقسيم
- فرعيةtracالإنتاج
+ إضافة
* تضاعف
٪ أو وزارة الدفاع معام

فيما يلي أمثلة على كل عامل.

القسمة الصحيحة (DIV) — تتجاهل دالة DIV الجزء الكسري وتعيد العدد الصحيح فقط.

SELECT 23 DIV 6;

تنفيذ البرنامج النصي أعلاه يعطينا 3.

عامل القسمة (/) — على عكس DIV، فإن عامل القسمة يحتفظ بالجزء العشري من النتيجة.

SELECT 23 / 6;

تنفيذ البرنامج النصي أعلاه يعطينا 3.8333.

فرعيةtracعامل الطرح (-)

SELECT 23 - 6;

تنفيذ البرنامج النصي أعلاه يعطينا 17.

عامل الجمع (+)

SELECT 23 + 6;

تنفيذ البرنامج النصي أعلاه يعطينا 29.

عامل الضرب (*)

SELECT 23 * 6 AS `multiplication_result`;

النتيجة:

multiplication_result
138

عامل باقي القسمة (٪ أو MOD)

يقسم عامل باقي القسمة N على M ويعطينا الباقي. لنلقِ نظرة على مثال عامل باقي القسمة، باستخدام نفس القيم كما في الأمثلة السابقة.

SELECT 23 % 6;
-- OR, equivalently:
SELECT 23 MOD 6;

تنفيذ أي من النصين البرمجيين يعطينا 5.

دعونا الآن نلقي نظرة على بعض الوظائف الرقمية الشائعة في MySQL.

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

SELECT FLOOR(23 / 6) AS `floor_result`;

النتيجة:

نتيجة الأرضية
3

ROUND – تقوم هذه الدالة بتقريب العدد إلى أقرب عدد صحيح. ولأن 23 ÷ 6 تساوي 3.8333، فإن دالة ROUND تُرجع 4 بينما تُرجع دالة FLOOR 3، لذا لا يمكن استخدامهما بالتبادل.

SELECT ROUND(23 / 6) AS `round_result`;

النتيجة:

نتيجة الجولة
4

RAND – تُولّد هذه الدالة رقمًا عشوائيًا. تتغير قيمته في كل مرة تُستدعى فيها الدالة. يوضح النص البرمجي أدناه كيفية استخدامها.

SELECT RAND() AS `random_result`;

وظائف التاريخ

تتعامل دوال التاريخ مع أنواع بيانات التاريخ والتاريخ والوقت. أما دالة DATE_FORMAT فهي التي تحل مشكلة "YYYY-MM-DD مقابل DD-MM-YYYY" الموضحة في المقدمة.

صيغة التاريخ يأخذ البرنامج النصي أدناه مُعاملين: قيمة التاريخ المراد تنسيقها، وسلسلة تنسيق مُنشأة من عناصر نائبة. يُعيد البرنامج النصي أدناه تاريخ كل إصدار بالتنسيق الذي طلبه المستخدمون: اليوم-الشهر-السنة.

SELECT `title`, DATE_FORMAT(`date_released`, '%d-%m-%Y') AS `formatted_date`
FROM `movies`;

فيما يلي قائمة بأكثر عناصر التنسيق استخداماً.

نائب معنى مثال على الناتج
%d يوم الشهر، رقمان 04
%m الشهر، رقمان 08
%Y السنة، أربعة أرقام 2012
%M اسم الشهر بالكامل أغسطس
٪له Hoursدقائق، ثوانٍ 14:35:09

تظهر ثلاث دوال أخرى للتاريخ باستمرار في العمل اليومي:

  • CURDATE() يُرجع التاريخ الحالي بصيغة YYYY-MM-DD.
  • الآن() إرجاع التاريخ الحالي و مرة.
  • DATEDIFF(d1, d2) يقوم بإرجاع عدد الأيام بين تاريخين - وهو أساس أي تقرير عن الإيجار المتأخر.

للاطلاع على القائمة الكاملة، انظر MySQL مرجع وظيفة التاريخ والوقت.

الوظائف المخزنة

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

تتصرف الدوال المخزنة تمامًا مثل الدوال المدمجة، باستثناء أنك تُعرّفها بنفسك. بمجرد إنشائها، يمكن استخدام الدالة المخزنة في عبارات SQL تمامًا مثل أي دالة أخرى. يظهر التركيب الأساسي أدناه.

CREATE FUNCTION sf_name ([parameter(s)])
RETURNS data_type
[DETERMINISTIC | NOT DETERMINISTIC]
BEGIN
    -- procedural statements
END

هنا

  • "إنشاء دالة sf_name ([المعلمات)])" إلزامي ويخبر بـ MySQL يقوم الخادم بإنشاء دالة باسم `sf_name` مع معلمات اختيارية محددة داخل الأقواس.
  • "إرجاع نوع البيانات" وهو إلزامي ويحدد نوع البيانات التي تُرجعها الدالة.
  • "حتمية" يُعلن أن الدالة تُرجع نفس القيمة كلما تم توفير نفس الوسائط. "غير حتمي" ويصرح بعكس ذلك.
  • "البداية ... النهاية" يغلف الكود الإجرائي الذي تنفذه الدالة.

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

DELIMITER |
CREATE FUNCTION sf_past_movie_return_date (return_date DATE)
RETURNS VARCHAR(3)
NOT DETERMINISTIC
BEGIN
    DECLARE sf_value VARCHAR(3);
    IF CURDATE() > return_date THEN
        SET sf_value = 'Yes';
    ELSEIF CURDATE() <= return_date THEN
        SET sf_value = 'No';
    END IF;
    RETURN sf_value;
END|
DELIMITER ;

⚠️ تحذير — لا تقم بتسمية هذه الدالة DETERMINISTIC. يستدعي جسم البرنامج الدالة CURDATE()، لذا قد تُرجع نفس الوسيطة القيمة "لا" اليوم والقيمة "نعم" غدًا. إن تعريف دالة تعتمد على الوقت باستخدام DETERMINISTIC يُضلل المُحسِّن ويُعدّ غير آمن للتكرار القائم على العبارات. استخدم غير حازم كلما استدعى الجسم CURDATE() أو NOW() أو RAND().

يؤدي تنفيذ البرنامج النصي أعلاه إلى إنشاء الدالة المخزنة `sf_past_movie_return_date`. لنختبرها الآن.

SELECT `movie_id`, `membership_number`, `return_date`, CURDATE(),
       sf_past_movie_return_date(`return_date`) AS `is_overdue`
FROM `movierentals`;

تنفيذ البرنامج النصي أعلاه في MySQL يعطينا برنامج Workbench النتائج التالية عند استخدامه مع قاعدة بيانات myflixdb.

movie_id رقم العضوية تاريخ العودة CURDATE() متأخر
1 1 اغية 04-08-2012 اغية
2 1 25-06-2012 04-08-2012 نعم
2 3 25-06-2012 04-08-2012 نعم
2 2 25-06-2012 04-08-2012 نعم
3 3 اغية 04-08-2012 اغية

لاحظ الصفين الفارغين. عندما تكون قيمة `return_date` فارغة، فإن كلا المقارنتين تُقيّمان إلى قيمة فارغة بدلاً من القيمة الصحيحة أو الخاطئة، لذلك لا يتم تنفيذ أي من فرعي الشرط، وتُرجع الدالة قيمة فارغة - وهي النتيجة المتوقعة، حيث لا يوجد تاريخ إرجاع للفيلم غير المُعاد للمقارنة به.

الوظائف المعرفة من قبل المستخدم

عندما لا تكون لغة SQL وحدها سريعة بما يكفي، MySQL يُتيح ذلك خيارًا ثالثًا. تُكتب الدوال المُعرَّفة من قِبل المستخدم (UDFs) بلغة مُجمَّعة مثل C or C++يتم دمجها في مكتبة مشتركة وتسجيلها لدى الخادم. وبمجرد إضافتها، يتم استدعاؤها تمامًا مثل أي دالة أخرى. ولأن دالة المستخدم المعرفة (UDF) تعمل كشفرة أصلية داخل عملية الخادم، فهي مناسبة للحسابات المعقدة، ولكن وجود خطأ فيها قد يؤدي إلى تعطل الخادم، لذا فإن استخدام دوال المستخدم المعرفة أقل بكثير من استخدام الدوال المخزنة.

الوظائف المدمجة مقابل الوظائف المخزنة مقابل الوظائف التي يحددها المستخدم: أيها يجب عليك استخدامه؟

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

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

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

الأسئلة الشائعة

يجب أن تُرجع الدالة قيمة واحدة فقط، ويمكن استخدامها داخل عبارة SELECT أو WHERE أو ORDER BY. أما الإجراء المخزن، فيُرجع صفرًا أو عدة مجموعات نتائج، ولا يمكن تضمينه في عبارة، ويتم استدعاؤه باستخدام عبارة CALL.

قم بتشغيل الأمر DROP FUNCTION IF EXISTS sf_name؛ ثم أعد إنشائه. MySQL لا تحتوي وظيفة CREATE OR REPLACE على وظيفة CREATE OR REPLACE، ووظيفة ALTER FUNCTION تغير فقط خصائص مثل التعليق أو نوع الأمان، وليس الجسم.

نعم، يمكنهم ذلك. تمنع الدالة المُغلّفة حول عمود مُفهرس في عبارة WHERE حدوث ذلك. MySQL تجنب استخدام هذا الفهرس، مما يجبر على إجراء مسح كامل. قم بالتصفية على العمود الخام وطبّق الدالة فقط في قائمة SELECT.

نعم. يمكن للمساعدين المدعومين بالذكاء الاصطناعي كتابة كود CREATE FUNCTION من قاعدة مكتوبة بلغة إنجليزية بسيطة. يُرجى دائمًا مراجعة الكود المُنشأ للتأكد من صحة خاصية DETERMINISTIC، ومعالجة القيم الفارغة (NULL)، وأنواع بيانات المعلمات قبل تشغيله على خادم الإنتاج.

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

تلخيص هذه التدوينة بـ: