هل SQL مكان جيد لمنطق الأعمال؟
هل SQL مكان جيد لمنطق الأعمال؟
هل SQL مكان جيد لمنطق الأعمال؟
لا ، ليس كذلك. في حين أن SQL هي لغة Turing-Complete ويمكننا استخدامها لتشفير أي منطق أعمال نريده ، فإن وضع منطق الأعمال (المجال) في SQL يؤدي إلى حل أقل قابلية للصيانة مقارنةً بحل يستخدم لغة OO أو لغة وظيفية.
لهذا السبب ، أدعو إلى قصر استخدام SQL على استعلامات القراءة فقط (والتي يمكن أن تحتوي على منطق الأعمال ، هذا جيد) وعبارات CRUD البسيطة حيثما أمكن ذلك. </ TL؛ DR>
يحدث الخلاف بشأن ما إذا كان ينبغي للمرء أن يضع منطق الأعمال في SQL أم لا لأطول فترة ممكنة أتذكرها.
إنه أقل نشاطًا بكثير هذه الأيام ، لكنه لا يزال موجودًا ، لذا دعونا نوضح التفاصيل هنا.
ما هو الخطأ في وضع منطق الأعمال في SQL؟
في الأساس ، SQL نفسها.
لنأخذ مثالا.
لنفترض أن لدينا النموذج التالي في تطبيقنا:
بمعنى آخر ، هناك كيانان:
الطالب والمعلم ، اللذان يشتركان في بعض البيانات المشتركة (حقل الاسم) ولهما أيضًا بعض السمات الفريدة (متوسط العلامات والراتب).
الآن ، لنفترض أننا بحاجة إلى إنشاء طريقة تعرض وصفًا لشخص ما. فيما يلي جدول يمكننا إنشاؤه لتمثيل هذا النموذج:
CREATE TABLE dbo.Person
(
,PersonID int NOT NULL PRIMARY KEY
, Name nvarchar(200) NOT NULL
Type int NOT NULL, -- 1 for students, 2 for teachers
, AverageMark float NULL
Salary decimal(18, 2) NULL
)
وإليك كيفية تنفيذ هذه الطريقة في SQL:
CREATE PROCEDURE dbo.sp_GetPersonDescription
@PersonID int
AS
DECLARE @Name nvarchar(200)
DECLARE @Type int
DECLARE @AverageMark float
DECLARE @Salary decimal(18, 2)
SELECT @Name = Name,
@Type = [Type],
@AverageMark = AverageMark,
@Salary = Salary
FROM dbo.Person
WHERE PersonID = @PersonID
IF @Type = 1
SELECT 'Student ' + @Name + ' with average mark ' + CAST (@AverageMark as varchar(10))
ELSE
SELECT 'Teacher ' + @Name + ' with salary ' + CAST (@Salary as varchar(10))
-- Usages:
EXEC sp_GetPersonDescription 1 -- Returns: Student John with average mark 95
EXEC sp_GetPersonDescription 2 -- Returns: Teacher Jack with salary 60000.00
الآن ، قارنه بـ C #:
public abstract class Person
{
public string Name { get; set; }
public abstract string GetDescription();
}
public class Student : Person
{
public double AverageMark { get; set; }
public override string GetDescription() =>
"Student " + Name + " with average mark " + AverageMark;
}
public class Teacher : Person
{
public decimal Salary { get; set; }
public override string GetDescription() =>
"Teacher " + Name + " with salary " + Salary;
}
أيهما أسهل في الفهم؟ أراهن أن إجابتك ليست “الأولى” 🙂
وهذه مجرد طريقة بسيطة تعرض بعض الوصف ، لا أكثر.
تخيل مدى صعوبة ترميز قاعدة العمل هذه باستخدام SQL:
أنا لا أقول أنه مستحيل (بالتأكيد!) ، ولكن مستوى الجهد المطلوب للتنفيذ ، والأهم من ذلك ، دعم هذا الحل والحفاظ عليه أعلى بكثير من استخدام لغات OO (أو FP) العادية.
السبب في ذلك بسيط:
لم يتم تصميم SQL للعمل مع الصفوف الفردية. يصبح الأمر أكثر وضوحًا إذا أخذت في الحسبان حقيقة أن عبارة IF لم تكن حتى في المعيار في البداية.
تمت إضافته لاحقًا ، بدءًا من SQL-99.
OLTP مقابل OLAP
هناك طريقتان أساسيتان للعمل مع البيانات:
OLTP و OLAP. OLTP (معالجة المعاملات عبر الإنترنت) تعني معالجة المعاملات الفردية التي عادة ما تتضمن كمية قليلة من البيانات.
يهدف هذا النوع من المعالجة إلى إنتاجية عالية وزمن انتقال منخفض لكل عملية.
قد يكون أحد الأمثلة هنا تطبيق ويب نموذجي.
عند تنفيذ إجراء (على سبيل المثال ، أضف عنصرًا إلى عربة التسوق) ، يقوم النظام بمعالجة طلبك عن طريق إنشاء خط منتج جديد ، وربما تسجيل الإجراء بطريقة ما.
على العكس من ذلك ، تعد OLAP (المعالجة التحليلية عبر الإنترنت) طريقة لتشغيل مجموعات كبيرة نسبيًا من البيانات.
ومن الأمثلة الجيدة هنا وظيفة في الخلفية تنشئ تقارير تحليلية.
طريقة البحث التي تبحث عن البيانات في ظل معايير معينة هي طريقة أخرى (على الرغم من أنها ليست “عملية OLAP حقيقية” في حد ذاتها).
كما قد تتخيل ، فإن SQL تدور حول OLAP وليس OLTP.
SQL هي اللغة الأمثل لتشغيل مجموعات البيانات.
إنه ليس مرنًا بدرجة كافية ولا يمكننا الاعتماد عليه للتعبير عن أي نموذج نطاق أكثر أو أقل تعقيدًا لأنه يفتقر إلى القدرة على إنشاء تجريدات مناسبة.
وهذا هو السبب الوحيد الأكثر أهمية لعدم استخدامه كمكان لمنطق العمل.
لا يتعلق الأمر بنقص الأدوات أو دعم ممارسات التطوير الحديثة مثل التحكم في الإصدار واختبار الوحدة وما إلى ذلك.
هناك عدد غير قليل من المنتجات في السوق التي تتيح لنا القيام بذلك.
يتعلق الأمر كله بعدم القدرة على إنشاء نموذج نطاق بسيط ومعبر.
يمنحنا تصميم OO (وكذلك الوظيفي) فرصًا أكثر بكثير من التصميم الإجرائي الذي يتركه لنا SQL.
نمط تصميم سيناريو المعاملات هو كل ما لدينا مع SQL.
إنه يعمل عندما يكون التطبيق الذي تقوم بتطويره بسيطًا بدرجة كافية ، ولكنه ينفجر مباشرةً بعد أن يصل إلى بعض علامات التعقيد (منخفضة جدًا).
حالات الاستخدام المثالية للغة SQL
من الناحية المثالية ، يجب أن نقصر استخدام SQL على هذين السيناريوهين:
استعلامات التحديد / الإدراج / التحديث / الحذف البسيطة (CRUD) بدون منطق الأعمال فيها
استعلامات للقراءة فقط مع بعض منطق الأعمال
لذلك تعني عمليات CRUD البسيطة أنه يجب علينا التعامل مع قاعدة البيانات الخاصة بنا على أنها حقيبة تفريغ للبيانات واستخدام SQL فقط لجلب هذه البيانات إلى الذاكرة وحفظها مرة أخرى في قاعدة البيانات.
يجب أن تتم معالجة البيانات في المكان الأنسب – رمز التطبيق الخاص بنا:
حالة الاستخدام الأخرى لـ SQL هي استعلامات SELECT للقراءة فقط.
حتى مع ظهور موفري LINQ في C # وموفري النوع في F # ، يصعب أحيانًا كتابة استعلام عن أداء مشابه في كود التطبيق.
في مثل هذه المواقف ، علينا أن نتراجع ونستخدم لغة SQL القديمة البسيطة.
إنها ليست مشكلة عادة لأن الاستعلامات للقراءة فقط لا تغير البيانات في قاعدة البيانات وبالتالي تضيف القليل من الصيانة.
أيضا ، تتوافق هذه الممارسة تمامًا مع مبادئ CQRS.
كذلك هذا هو استخدام نماذج منفصلة للقراءة والكتابة لأسباب تتعلق بالأداء.
ليست حالات الاستخدام المثالية للغة SQL
حالة الاستخدام غير المثالية لـ SQL هي كتابة استعلامات تحتوي على بعض منطق الأعمال في الداخل.
كما ناقشنا سابقًا ، إنها ممارسة جيدة لتجنب مثل هذه الاستفسارات ولكن الحقيقة هي أنه ليس ممكنًا دائمًا.
على سبيل المثال ، قد يكون لدينا مطلب لتعطيل حسابات جميع عملائنا إذا اجتازوا استحقاق خطة الدفع الخاصة بهم.
كذلك في هذه الحالة ، سيكون من الأسهل بكثير تنفيذ عبارة UPDATE واحدة لجميع العملاء في وقت واحد ، دون تحميلهم في الذاكرة ومعالجتهم واحدًا تلو الآخر.
نصيحتي في مثل هذه الحالة هي:
استخدم مثل هذا البيان عند الاقتضاء ، ولكن حاول الحد من وجودهم وتبسيط قواعد العمل المشفرة فيها قدر الإمكان.
باختصار
دعونا نلخص:
- يعد SQL مكانًا سيئًا للحفاظ على منطق الأعمال فيه
- حاول الحد من استخدام SQL بطريقة:
- استعلامات SQL هي استعلامات CRUD بسيطة بدون منطق عمل فيها ، أو
- لا تغير استعلامات SQL البيانات في قاعدة البيانات
لمعرفة المزيد والمزيد عن اللغة SQL واحتراف اللغة واتقانها تواصل مع فريقنا المختص واطلب الخدمة الان