فرض سلامة البيانات باستخدام القيود
القيود وكائنات التسلسل هي خيارات تصميم تمنع مشاكل البيانات قبل حدوثها. وجود قيد مفتاح أجنبي مفقود يعني أن سجلات مفتية قد تكون موجودة بالفعل في قاعدة بياناتك. إضافة كائنات التسلسل لاحقا لاستبدال أعمدة الهوية يتطلب تغييرات عبر جميع التطبيقات. يمكن لكود التطبيق التحقق من صحة البيانات، لكن يمكن للمستخدمين تجاوزها من خلال الاستيراد الجماعي، أو الاستعلامات المباشرة، أو التطبيقات الجديدة التي تتجاوز التحقق.
قيود قاعدة البيانات تفرض القواعد على مستوى المحرك، لذا فهي دائما تنطبق. القرارات التي تتخذها أثناء التصميم، مثل القواعد التي يجب تطبيقها في قاعدة البيانات وما إذا كان يجب استخدام أعمدة أو تسلسلات هوية، تؤثر على جودة بياناتك طوال عمر تطبيقك.
فهم متى تستخدم القيود
مشاكل جودة البيانات مكلفة. تؤدي جودة البيانات الرديئة إلى قرارات تجارية خاطئة، وفشل في التكاملات، وانتهاكات الامتثال. على عكس التحقق على مستوى التطبيق الذي قد يكون غير متسق عبر تطبيقات مختلفة تصل إلى نفس قاعدة البيانات، تفرض القيود قواعد على مستوى محرك قاعدة البيانات حيث لا يمكن تجاوزها بواسطة كود التطبيق، أو الاستعلامات العشوائية، أو سكريبتات SQL المباشرة، أو الاستيراد الجماعي. يجب أن تحقق كل INSERTعملية ، UPDATE، و DELETE جميع القيود المحددة قبل أن يقوم محرك قاعدة البيانات بالتغيير.
تطبيق قيود قاعدة البيانات
القيود تمنع مشاكل جودة البيانات قبل أن تفسد قاعدة بياناتك. يوضح الجدول التالي كيف يعالج كل نوع من القيود قضايا سلامة البيانات المحددة:
| المشكلة | القيد | مثال |
|---|---|---|
| سجلات يتيمة | المفتاح الأجنبي | يمنع الطلبات بدون عملاء صالحين |
| البيانات المكررة | فريد | يوقف تسجيل البريد الإلكتروني المكرر |
| بيانات غير صحيحة | تم التحقق | يرفض الأسعار السلبية أو تواريخ الميلاد المستقبلية |
| البيانات الحرجة المفقودة | ليس بلا قيمة | يمنع السجلات غير المكتملة |
| التناقض المرجعي | المفتاح الأجنبي | يحافظ على سلامة البيانات عبر الجداول |
فكر في شركة تجزئة لم تحدد قيدا فريدا في عمود بريد العملاء الخاص بها. مع مرور الوقت، تم تسجيل نفس العملاء عدة مرات بعناوين بريد إلكتروني متطابقة. عندما كان التسويق يرسل حملات ترويجية، يتلقى بعض العملاء ثلاث نسخ من نفس البريد الإلكتروني، مما زاد التكاليف وأضر بثقة العملاء. إضافة UNIQUE (EmailAddress) إلى تعريف الجدول كانت ستمنع إدراج هذه النسخ المكررة.
تفرض القيود القواعد على مستوى محرك قاعدة البيانات، مما يضمن جودة البيانات بغض النظر عن كيفية دخول البيانات إلى النظام. يمكن تجاوز التحقق من التطبيق، ويختلف حسب التطبيق، ويصعب صيانته. قيود قواعد البيانات دائما مطبقة ومركزية وتوفر مصدرا واحدا للحقيقة.
تضمن القيود جودة البيانات واتساقها على مستوى قاعدة البيانات.
استخدم قيود المفتاح الأساسي
تضمن القيود الرئيسية للبيانات الفريدة وتفرض سلامة الكيان. عند تحديد قيد المفتاح الأساسي، يقوم محرك قاعدة البيانات تلقائيا بإنشاء فهرس فريد لأعمدة المفتاح الأساسي. يمكن أن يحتوي الجدول على قيد مفتاح رئيسي واحد فقط، ويجب تعريف جميع الأعمدة المعرفة داخل قيد المفتاح الأساسي ك NOT NULL.
يمكنك إنشاء مفتاح أساسي باستخدام القيد PRIMARY KEY . إليك مثال:
CREATE TABLE Customer (
CustomerID INT PRIMARY KEY IDENTITY(1,1),
EmailAddress NVARCHAR(100) NOT NULL
);
استخدم قيود المفاتيح الأجنبية
تفرض قيود المفاتيح الأجنبية سلامة المرجعية من خلال التحكم في البيانات التي يمكن تخزينها في جدول المفاتيح الأجنبية. قيد المفتاح الأجنبي يمنع التغييرات في البيانات في جدول المفتاح الأساسي إذا أبطلت هذه التغييرات الرابط إلى البيانات في جدول المفتاح الأجنبي.
يمكنك تعريف إجراءات مرجعية متتالية مثل CASCADE، SET NULLأو SET DEFAULT تحديد ما يحدث عندما يحاول المستخدم حذف أو تحديث مفتاح يشير إليه المفاتيح الأجنبية الموجودة. على الرغم من أن إنشاء فهرس يدويا لأعمدة المفاتيح الأجنبية ليس مطلوبا، إلا أنه غالبا ما يكون مفيدا لأن أعمدة المفاتيح الأجنبية تستخدم كثيرا في معايير الوصول.
يمكنك إنشاء مفتاح أجنبي باستخدام القيد FOREIGN KEY مع جملة REFERENCES . إليك مثال:
CREATE TABLE Order (
OrderID INT PRIMARY KEY IDENTITY,
CustomerID INT NOT NULL,
OrderDate DATETIME2,
FOREIGN KEY (CustomerID) REFERENCES Customer(CustomerID)
);
استخدم القيود الفريدة
تضمن القيود الفريدة عدم إدخال قيم مكررة في أعمدة محددة لا تشارك في مفتاح أساسي. على عكس PRIMARY KEY القيود، UNIQUE تسمح القيود بقيمة NULL. ومع ذلك، كما هو الحال مع أي قيمة تشارك في UNIQUE قيود، يسمح بقيمة صفرية واحدة فقط لكل عمود. يقوم محرك قاعدة البيانات تلقائيا بإنشاء فهرس فريد غير مجمع لتطبيق متطلب التفرد.
يمكنك إنشاء قيد فريد باستخدام الكلمة UNIQUE المفتاحية. إليك مثال:
CREATE TABLE Product (
ProductID INT PRIMARY KEY,
SKU NVARCHAR(50) UNIQUE,
ProductName NVARCHAR(100)
);
استخدم قيود التحقق
تفرض قيود التحقق سلامة المجال عن طريق تحديد القيم المقبولة بعمود أو أكثر. يمكنك إنشاء CHECK قيد بأي تعبير منطقي يعود TRUE أو FALSE يعتمد على العوامل المنطقية. يمكنك تطبيق قيود متعددة CHECK على عمود واحد أو فرض قيد واحد CHECK على عدة أعمدة.
نظرا لأن القيم الصفرية تقيم إلى UNKNOWN، فقد يتجاوز وجودها في التعبيرات قيدا. على سبيل المثال، لا يزال قيد MyColumn = 10 على عمود INT يسمح NULL بإدخاله لأنه NULL لا يقيم ل FALSE.
يمكنك إنشاء قيد CHECK باستخدام CHECK الكلمة المفتاحية مع تعبير منطقي. إليك مثال:
CREATE TABLE Employee (
EmployeeID INT PRIMARY KEY,
HireDate DATE,
Salary DECIMAL(10,2),
CHECK (Salary >= 20000),
CHECK (HireDate <= GETDATE())
);
استخدم القيود الافتراضية
توفر القيود الافتراضية قيما افتراضية عندما لا يتم تحديد أي قيمة أثناء INSERT العمليات. عند العمل مع مشاريع قواعد البيانات، ينصح بإنشاء قيود بأسماء صريحة بدلا من السماح بأسماء مولدة من قبل النظام، والتي تختلف بين البيئات.
يمكنك إنشاء قيد افتراضي باستخدام الكلمة DEFAULT المفتاحية. إليك مثال:
CREATE TABLE Activity (
ActivityID INT PRIMARY KEY IDENTITY,
Description NVARCHAR(200),
CreatedDate DATETIME2 CONSTRAINT DF_Activity_CreatedDate DEFAULT GETUTCDATE(),
IsActive BIT CONSTRAINT DF_Activity_IsActive DEFAULT 1
);
استخدم كائنات التسلسل
كائن التسلسل هو كائن محدد من قبل المستخدم مرتبط بالمخطط يولد تسلسلا من القيم الرقمية وفقا للمواصفات التي تم إنشاء التسلسل. على عكس أعمدة الهوية، لا ترتبط التسلسلات بجداول محددة. تشير التطبيقات إلى كائن تسلسل لاسترجاع قيمته التالية، وتتحكم التطبيق في العلاقة بين التسلسلات والجداول.
تعمل أعمدة الهوية بشكل جيد عندما تحتاج إلى ترقيم تلقائي لجدول واحد. ومع ذلك، فهي محدودة بتلك الطاولة فقط. لا يمكنك مشاركة الأرقام عبر جداول متعددة، أو الحصول على القيمة التالية قبل إدخال صف، أو إعادة تعيين العداد بسهولة. تحل الكائنات المتسلسلة هذه المشاكل عن طريق توليد أعداد مستقلة عن أي جدول.
فهم متى تستخدم التسلسلات
استخدم التسلسلات بدلا من أعمدة الهوية في السيناريوهات التالية:
- سلاسل الأرقام المشتركة - يتطلب التطبيق مشاركة سلسلة واحدة من الأرقام بين عدة جداول أو عدة أعمدة داخل الجدول.
- سلسلة الأرقام المتكررة - يجب على التطبيق إعادة تشغيل سلسلة الأرقام عند الوصول إلى رقم محدد. على سبيل المثال، بعد تعيين القيم من 1 إلى 10، يبدأ التطبيق في تعيين القيم من 1 إلى 10 مرة أخرى.
-
قيم التسلسل المرتبة - يتطلب التطبيق فرز قيم التسلسل حسب حقل آخر. يمكن للدالة
NEXT VALUE FORتطبيق الجملةOVER، التي تضمن أن القيم المرتجلة تولد بترتيب الجملةORDER BY. -
حجز عدة أرقام - يحتاج التطبيق إلى حجز عدة أرقام متسلسلة في نفس الوقت. طلب قيم الهوية قد يؤدي إلى فجوات إذا تم إصدار أرقام لعمليات أخرى في نفس الوقت. يستعيد الاتصال
sp_sequence_get_rangeعدة أرقام في التسلسل دفعة واحدة. - المواصفة القابلة للتغيير - تحتاج إلى تغيير مواصفات التسلسل، مثل قيمة التزايد، بعد الإنشاء.
يمكن لكائنات التسلسل أن توفر مرونة أكبر من أعمدة الهوية:
| الميزة | Sequence | الهوية |
|---|---|---|
| مرتبط بالطاولة | لا | نعم |
| مشتركة عبر الجداول أو الأعمدة | نعم | لا |
| احصل على القيمة التالية قبل عملية الإدراج | نعم | لا |
| قيم أدنى/قصوى مخصصة | نعم | Limited |
| استرجاع عدة أرقام في نفس الوقت | نعم | لا |
| دورة أو إعادة تشغيل عند الرقم المحدد | نعم | لا |
| ترتيب القيم حسب حقل آخر | نعم | لا |
| زيادة التغيير بعد الإنشاء | نعم | لا |
استخدم عمود الهوية عندما تحتاج إلى مفتاح أساسي بسيط يرفع تلقائيا لجدول واحد ولا تحتاج إلى مشاركة نفس سلسلة الأرقام عبر عدة جداول أو استرجاع القيمة التالية قبل إدخال الصف.
استخدم تسلسلا عندما يحتاج تطبيقك إلى رقم قبل إنشاء الإدراج، أو يحتاج إلى مشاركة سلسلة واحدة بين عدة جداول، أو يجب إعادة تشغيل سلسلة الأرقام عند الوصول إلى رقم محدد، أو يحتاج إلى حجز عدة أرقام متسلسلة في نفس الوقت.
فهم حدود التسلسل
على عكس أعمدة الهوية، لا يتم حماية القيم التسلسلية تلقائيا بعد إدخالها في الجدول. أيضا، التفرد لا يفرض تلقائيا على قيم التسلسل. إذا كان يجب أن تكون قيم التسلسل في الجدول فريدة، أنشئ قيدا فريدا على العمود.
يتم توليد أرقام التسلسل خارج نطاق المعاملة الحالية. يتم استهلاكها سواء تم تنفيذ المعاملة باستخدام رقم التسلسل أو تم التراجع عنها.
يمكنك إنشاء كائن تسلسل باستخدام CREATE SEQUENCE العبارة التي تحتوي على معلمات اختيارية للبداية، الزيادة، والمدى. إليك مثال:
-- Create sequence
CREATE SEQUENCE OrderNumber
START WITH 1000
INCREMENT BY 1
MINVALUE 1000
MAXVALUE 999999
NO CYCLE;
-- Use sequence in INSERT with NEXT VALUE FOR function
INSERT INTO Order (OrderID, CustomerID, OrderNumber, OrderDate)
VALUES (1, 100, NEXT VALUE FOR OrderNumber, GETDATE());
-- Get next value before INSERT
DECLARE @NextOrderNum INT = NEXT VALUE FOR OrderNumber;
SELECT @NextOrderNum;
-- Get multiple sequence numbers at once for batch processing
DECLARE @FirstSeq INT, @LastSeq INT;
EXEC sp_sequence_get_range
@sequence_name = N'OrderNumber',
@range_size = 100,
@range_first_value = @FirstSeq OUTPUT,
@range_last_value = @LastSeq OUTPUT;
-- Reset sequence
ALTER SEQUENCE OrderNumber RESTART WITH 1000;
هذا المثال ينشئ تسلسلا يسمى OrderNumber يبدأ من 1000، ويزداد بمقدار 1، ويتوقف عند 999999 دون العودة للخلف. تسترجع الدالة NEXT VALUE FOR الرقم المتاح التالي، إما داخل الخط أثناء العبارة INSERT أو تعيينه لمتغير قبل الإدراج عندما يحتاج التطبيق إلى الإشارة إلى القيمة أولا. بالنسبة للعمليات الدفعية التي تتطلب عدة أرقام متسلسلة في نفس الوقت، sp_sequence_get_range يحتفظ بكتلة من 100 رقم، ويعيد القيم الأولى والأخيرة في النطاق. تعيد العبارة ALTER SEQUENCE التسلسل إلى 1000 عند الحاجة.
القيود هي قرارات معمارية تمنع حدوث مشاكل قبل حدوثها. القيد المفقود CHECK يسمح للبيانات غير الصالحة بتلف قاعدة بياناتك بشكل صامت. اختيار أعمدة الهوية عندما تحتاج إلى ترقيم عبر الجداول يفرض على حلول بديلة على مستوى التطبيق. القيود المعرفة على مستوى قاعدة البيانات تحمي جودة البيانات بغض النظر عن التطبيق أو الأداة أو السكريبت الذي يصل إلى قاعدة بياناتك. تشكل هذه القرارات ضمانات سلامة بياناتك طوال عمر تطبيقك.