الرئيسية > برمجة قواعد البيانات ADO.NET, تقنية net. > حقول الهوية : بين الفئات البرمجية وحقول SQL Server :

حقول الهوية : بين الفئات البرمجية وحقول SQL Server :

يوجد الكثير من الطرق التي لعمل حقول هوية مميزة Identity fields او ما يعرف بالمفتاح الأساسي Primary Key Filed ، من اشهرها على الاطلاق حقل الـ Autoincrement او الترقيم التلقائي ، والتي يتم فيها توليد رقم تلقائي يزيد عن اخر رقم في العداد الخاص بقيمة تكون في اغلب الاحيان 1 ، تتميز بالخفة والنحافه ، وبالتالي فنحن نتوقع منها الاداء المتميز كونها تحمل قيمة رقمية صغيرة تبدأ من 1 وتصل للآلاف لكنها قد تصل الملايين كلما كبر حجم البرنامج وزاد استخدامه ، وان يكن ، فهي لاتزال ارقام صحيحه integers قد تكون مثلا 99999999999953424 وماذا يعني ذلك ؟ فلا يوجد مشاكل حتى اللحظه فما احلاها !

ولكن ما يعيب هذا الاسلوب هو افتقادها إلى شيء مهم للغاية ، حيث اننا في التطبيقات الكبيرة نوعا ما ، يكون اغلب اعتمادنا على الوضع المنفصل فقد نستخدم Dataset,LINQtoSQL,Entity Framework,…etc ونضيف سجلات Records وقد يتم تعديلها حتى قبل ان ترسل إلى قاعدة البيانات database ، والمشكلة التي ستحدث هنا ، ان كائنات البيانات التي بحوزتنا لن تستطيع اسناد قيمة لحقل المفتاح الأساسي ، حيث ان اصدارها يتم حكرا على قاعدة البيانات فقط ، ولن نستطيع معرفة قيمتها الا بإضافة السجلات إلى قاعدة البيانات وهنا تمكن المشكلة ، ففي التطبيقات التجارية والتطبيقات التي تعتمد على تعدد الطبقات n-tier applications ، يتم اضافة العديد من السجلات وحزمها كلها في حزمة واحده لإرسالها دفعة واحدة إلى قاعدة البيانات ، كما يتم قبل ذلك كله تبادل البيانات بين طبقتي العرض والاعمال ، ناهيك عما يدور خلف الكواليس من عمليات تحقق وسين وجيم !

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

ان حاولنا ان نقوم بإنشاء فئة خاصة بنا فذلك جيد ، لكننا قد نتعب كثيرا فيها في سبيل ضمان عدم تكرر القيمة المنشأة مع أي نسخه اخرى من الكائن من نفس الفئة في الذاكرة ، او نسخه اخرى من التطبيق ككل في جهاز آخر ، قد نحتاج إلى دالة توليد الارقام العشوائيه وندخل لها معادلة محترمة في فترة interval رقمية كبيرة جدا قد تتراوح بين 1 و 5 ملايين مثلا ،ونسندها إلى حقل المفتاح الأساسي ، لكن في برنامج يتوقع ان تكون سجلاته بأعداد كبيرة فإن احتمالية تكرار الرقم الواحد ستكون اكبر وستزداد بزيادة عدد نسخ البرنامج العاملة في الشبكة !

قد يقترح احدهم ان نكبر المجال ليكون إلى 20 مليون مثلا وبالتالي نضع انفسنا في امان اكثر ونكون على يقين بأن نسبه تكرار الرقم صغيرة جدا – اقسم 1 على 20 مليون ! – ومن هنا سنحتاج إلى ان يكون حقل المفتاح الاساسي من نوع خاص ، فالنوع الرقمي – اما في .net او في SQL Server – لن يحتويه في اغلب الاحيان فنحن نتحدث من منظور التطبيقات المتوسطة والكبيرة والملايين ، مما قد يدفعنا إلى استخدام حقل نصي في قاعدة البيانات ، ونوع نصي كـ String مثلا في برنامجنا ، لكن هذا النوع يعاب عليه البطء في مثل هذه العمليات ، فهذا الحقل هو المفتاح الاساسي وتعتمد عليه كل العمليات الأخرى مما يعني ان ينخفض مستوى الأداء بشكل كبير جدا جدا ويصبح العمل بطيئا للغاية .

نفس المشكلة سنواجهها ان فكرنا في توليد بيانات عشوائية مختلطة بالنصوص والارقام ليكون لدينا قيمة مثل s334dfgr54 ولكنها ايضا ستكون نصيه بالرغم من اننا نعرف ان نسبه التكرار ستكون ضئيلة للغاية ايضا في هذه الحالة .

طيب والحل ؟

ينفرد SQL Server وكذلك .Net Framework بالنوعين UniquIdentifier و GUID – الاول في الاول والثاني للثاني طبعا ! – فهذا النوع يقوم بتوليد سلسلة نصية طويلة مثل التالية:

dc63e853-804b-4eac-b2e8-270bf1095a63

21c5d16d-d455-49e1-ab4a-7ff39753c4f9

5690757b-544f-49d8-b412-d45433f55202

1c7c7409-a9cf-48cd-a051-6a3a145b90c3

1be8fd38-785c-4628-b5f8-efab7b4d7e40

fc9270f6-fc6b-426e-b7d8-d4b43ec73f6a

4f400213-dcdc-4c91-9ec0-5ce916332be4

74211c09-0bb7-4eea-8944-94581545e3a3

cbb03156-990e-4e15-891e-96788861b8f7

c3b60d21-94a0-4764-866b-582b04fa9701

d0921672-bfff-41c1-9c17-56a76d459d66

3434c358-2371-4352-b16e-c72c4c138525

21afb37d-5981-4c7f-b6f5-0c15a8b7cda5

c1675a25-c365-4015-8151-16d1b2ff7271

ceabf72d-3076-4784-80d8-879a53e21e0c

55760bd0-b7bc-4b14-8b4e-b808e9cb35fe

فنسبه تكرار الرقم ضئيلة للغاية وقد تصل إلى – بحسب حساباتي المتواضعة – 15.78E-51 تخيل 51 خانة عشرية كلها اصفار ! اذا نسبة ضئيلة جدا جدا من التكرار ، فمن هذه الناحية نضمن عدم التكرار ، ومن ناحية نوع البيانات فهو مدعوم في اطار العمل .net وفي قاعدة البيانات SQL Server ايضا ، طيب ماذا عن السرعة ؟

من ناحية السرعة فلا تقلق ، فبما اننا بعدنا عن النوع String فنحن في جهة آمنة من البطء ، خصوصا ان النوع مدعوم في كلا المكانين SQL Server و .Net Framework

وماذا بعد ؟

تتوفر الفئة GUID مباشرة في فضاء الاسماء System ، والميزة التي تتمتع بها انها Shared خصوصا الدالة NewGUID التي تعود بقيمة GUID هكذا : Guid.NewGuid() ، وبالنسبة لإنشاء كائن جديد فذلك عادي جدا :

 

        Dim x As Guid
       
x = Guid.NewGuid
       
Console.WriteLine(x)

        Console.Read()

ولكن تذكر دائما وجوب استدعاء الدالة NewGUID في حالة رغبتك بإنشاء مميز جديد ، حيث ان الكود التالي :

 

        x = Guid.NewGuid
       
Console.WriteLine(x)
       
Console.WriteLine(x)
       
Console.WriteLine(x)

        Console.Read()

 

سيعطينا نفس الناتج تماما مرتين ! والحل يكمن في استدعاء الطريقة المشتركة Guid.NewGuid في كل مرة :

 

Dim x As Guid
       
x = Guid.NewGuid
       
Console.WriteLine(x)
       
x = Guid.NewGuid
       
Console.WriteLine(x)
       
x = Guid.NewGuid
       
Console.WriteLine(x)

        Console.Read()

بهذا نكون قد انتهينا من هذا الموضوع .

تحياتي

  1. أغسطس 24, 2009 الساعة 4:23 م

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

  2. غازي
    نوفمبر 13, 2009 الساعة 8:36 م

    الأخ rarek siala
    قال كاتب المقال
    حيث اننا في التطبيقات الكبيرة نوعا ما ، يكون اغلب اعتمادنا على الوضع المنفصل ..

  3. نوفمبر 15, 2009 الساعة 12:55 ص

    @غازي
    شكراً لتنبيهك لي🙂

  1. No trackbacks yet.

أضف تعليقاً

إملأ الحقول أدناه بالمعلومات المناسبة أو إضغط على إحدى الأيقونات لتسجيل الدخول:

WordPress.com Logo

أنت تعلق بإستخدام حساب WordPress.com. تسجيل خروج   / تغيير )

صورة تويتر

أنت تعلق بإستخدام حساب Twitter. تسجيل خروج   / تغيير )

Facebook photo

أنت تعلق بإستخدام حساب Facebook. تسجيل خروج   / تغيير )

Google+ photo

أنت تعلق بإستخدام حساب Google+. تسجيل خروج   / تغيير )

Connecting to %s

%d مدونون معجبون بهذه: