الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Auto Identity أم GUID كمفتاح أساسي؟

مغلقاستطلاع
بدأه وليد محمد الحسن في 28 يونيو 2006 · 14 رد · 4,313 مشاهدة · في قواعد بيانات Microsoft SQL Server
مشاركة: واتساب X فيسبوك تيليجرام

أيهما تفضل كمفتاح أساسي لجدولك؟

11 مشارك في التصويت

????? ???? ?????? ????? ???????

Auto Identity10 صوت · 91%
GUID1 صوت · 9%
?? ?????? ?? ????? ?????? ?????0 صوت · 0%
#1 صاحب الموضوع

كما هو واضح من العنوان، البعض يفضل استعمال حقل auto identity كمفتاح أساسي للجدول، بينما يفضل البعض عمل حقل من نوع GUID وهي عبارة عن قيمة حرفية بالنظام السادس عشري طولها 16 بايت لايمكن أن تتكرر على أي مستوى، بعكس حقل الauto identity الذي قد يؤدي لحدوث تضاربات في حالات دمج البيانات عبر الdisconnected mode، هذا غير حالات نفاذ مدى الأعداد في حال استعمال حقل نوعه smallint مثلا كحقل identity حقل مفتاحي، بينما استعمال حقل من نوع GUID يعقد عملية الفهرسة indexing لأن فهرسته تتم وكأنه حقل من نوع char أو varchar.

بعد هذا، أيهما تفضل كحقل مفتاحي: GUID أم auto identity؟ ولماذا؟

فكر بطريقة أخرى

#2

لأني تعاملت مع Identity

سلام

#3

يفضل استخدام ال GUID عندما نريد وجود مفتاح اساسى لا يمكن تكراره على مستوى قاعدة البيانات باكملها او عندما تود توليد قيمة Unique فى جدول على عكس ال Identity التى تعمل على مستوى الجدول

يوجد العديد من الاجراءات لتعامل مع ال Identity و قد سبق و ان ناقشناها فى اكثر من موضوع بالقسم اما توليد ال GUID فيستخدم من خلال الدالة NewID فقط بدون اجراءات اخرى مساعدة على حد علمى

Technical Lead Developer

My LinkedIn Profile

اللهم قنى شر الجهل و الجهلاء

( اقْتَرَبَ لِلنَّاسِ حِسَابُهُمْ وَهُمْ فِي غَفْلَةٍ مَّعْرِضُونَ ) {الأنبياء:1}

#4

انا لم اصوت لان السؤال لا يجب ان يكون تصويت

و انما لك من هذه الامور مكان لاستخدامها حسب المكان نقرر هل سنستخدم هذا النوع ام ذالك؟

سوف اوضح بعض النقاط في هذا الامر

السؤال هو: هل استخدم Auto Identity أم GUID كمفتاح أساسي؟

اولا بالنسبة لل Auto Identity:

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

و من اهم المشاكل او يعتبر مشكلة رئيسية في Identity ايضا هي gaps اي الفراغات:

اي عند حذف اي سجل من السجلات المضافة قديما يبقى الرقم ID الذي كان يُستخدم لهذا السجل بدون استخدام مما يؤدي الى تكبير الرقم في النهاية بوجود فراغات بين الارقام.

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

اقتباس
يفضل استخدام ال GUID عندما نريد وجود مفتاح اساسى لا يمكن تكراره على مستوى قاعدة البيانات باكملها او عندما تود توليد قيمة Unique فى جدول على عكس ال Identity التى تعمل على مستوى الجدول

هذا الكلام بعيد كثيرا عن الصحة اخي الكريم :) :) لا تزعل مني و لكن انتظر الى النهاية حتى اوضح الامر

اولا ما هو GUID: هو رقم لا يمكن تكراره على مستوى العالم بأسره اي لا يوجد رقمين GUID في العالم تم توليدهما بخوارزمية توليد ال GUID متشابهين.

ماذا تقصد بلا يمكن تكراره على مستوى قاعدة البيانات هذه المعلومة غير صحيحة نهائيا

ما هو ال GUID و اين يتم استخدامه:

اذا لم ترى ال GUID يكون ال GUID على الشكل التالي

{66103A23-A2B3-4844-B5A4-A844D7C3B664}

هذا ما يدعى GUID ب 16 بايت

كما سبق وقلت لا يمكن تكرار هذا الرقم نهائيا على مستوى العالم هل تصدق هذا ام لا؟؟؟

يعتمد توليد هذا الرقم على العديد من الخوارزميات المعقدة جدا لدرجة انه يمكنك قول انّ كل شيئ يدخل في خوارزمية توليده من(وقت , سيريالات, .......)

اين يتم استخدام ال GUID خارج قواعد البيانات:

يتم استخدامه عادة في برامج اعداد setup للبرامج حيث يتم اعطاء رقم GUID عند انشاء اي برنامج , هذا ال GUID يكون معرف لهذا التطبيق اي يلتصق

به طول حياته و لا يتم تغييره الا في حالات شاذة

تخيل معي التالي: لديك نسخة من برنامج ما على حسابك االان اذا اردت ان تنصبه مرة اخرى فلا يمكن ذلك بحال من الاحوال حيث يظهر لك على الاغلب قائمة تحتوي

على الخيارات(Modify, repair, remove) كيف عرف بوجود البرنامج لديك يا ترى هل هو نوع من السحر لا

فقد تم الاعتماد على GUID في معرفة وجود البرنامج ام لا

و هناك استخدامات اخرى لل GUID ....ليس الهدف ان نتحدث عنها

و انما الشيئ الهام و الذي يجب ان يتم توضيحه هو اين استخدم GUID في قاعدة البيانات؟

ليس الهدف من اختراع ال GUID هو ان يكون مفتاح اساسي للجدول و انما له وظائفه المفيدة التي سوف اوضحها

المفتاح الاساسي للجدول يمكن ان يكون اكثر من حقل و هنا يكون اسمه مفتاح اساسي مركب و لكن هل نستخدم GUID كمفتاح اساسي لجدول ام لا؟

يمكن ضمان ان يكون الحقل Unique بعمل رقم تسلسلي بغض النظر عن طريقة توليده و هذا يكفي في الكثير من الحالات او استخدام مجموعة من الحقول في جدول تضمن من خلالها عدم تكرار القيم

الى الان هذه مقدمات فقط لفهم اين يتم استخدام ال GUID في قاعدة البيانات:

في الحقيقة استخدام ال GUID نادرا ما يتم استخدامه لان حجمه كبير مقارنة مثلا ب int نسبيا و هذا ما يؤدي الى بطئ في التعامل معه

و لكن على الجانب المقابل هناك حالات يجب ان تستخدم فيها ال GUID لا محالة لذلك قام من صنع DBMS بانشاء نوع بيانات اسمه GUID في قواعد البيانات

ما هي الحالات التي يجب ان استخدم فيها GUID كحقل او مفتاح اساسي في جدولي و التي لا استطيع ان افعلها باستخدام رقم تسلسلي؟؟

لتوضيح الامر سوف ابين لك مشكلة اريد منك حل لها؟

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

رقم تسلسلي - اسم المادة - اسم الزبون - الكمية - السعر

بحيث يكون المفتاح الاساسي للجدول هو الرقم التسلسلي

هذه الشركة لديها العديد من الفروع في مناطق بعيدة عن بعضها البعض

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

في قاعدة بيانات مركزية بحيث تكون قاعدة البيانات المركزية حاوية على جميع بيانات الفروع الى الان ما في اي مشكلة

نظريا يمكن نقل البيانات باي صيغة كانت و عبر اي وسيلة اتصال بين الفروع لنفرض الان انّ البيانات قد وصلت الى المكان الذي توجد فيه قاعدة البيانات المركزية

الان نريد دمج هذه البيانات في الجدول السابق!! فكر قليل في الامر هل هناك مشكلة في الدمج

هاه هل هناك مشكلة في الدمج؟؟ الجواب نعم

المشكلة: كيف سوف اقوم بدمج البيانات و الارقام التسلسلية التي تشكل المفتاح الاساسي , ممكن ان تتكرر في كل فرع من فروع الشركة

يعني ممكن الرقم 100 ان يكون موجود في كل الفروع كيف سوف اقوم بدمج هذه البيانات و هناك تكرار في حقل المفتاح الاساسي

لا يمكن ذلك ؟؟!!! هل لديك حل؟؟ ممكن احدكم يفكر بطريقة غبية شوي (الطريقة غبية و ليس الشخص)ويقول ممكن ان اقوم باضافة هذه السجلات

مع اعطاءها ارقام تسلسلية من جديد!! ما رأيكم حل مقنع ام لا ؟؟؟

الجواب: الامر اعقد بكثير من ان تقوم بتوليد ارقام تسلسلية في حالتنا هذه و بسبب ضيق الوقت تم طرح المثال يحتوي على جدول واحد و لكن في الواقع هناك العديد

من الجداول الاخرى تعتمد على المفتاح الاساسي الذي هو الرقم التسلسلي السابق و في حال تغيير الرقم التسلسلي يتم الخطأ في كل الجداول الاخرى

هل ادركت ما المشكلة الحقيقية بالضبط ارجوا ان تكون الفكرة قد وضحت

الحل: هو استخدام GUID كمفتاح اساسي للجدول و بما انّ GUID لا يمكن ان يتكرر فبالتالي يمكن دمج البيانات فورا بدون اي مشكلة تذكر

هذه هي الفائدة الحقيقة من GUID وقس على ذلك من الافكار التي تكون على نفس الشاكلة.

ارجوا ان اكون قد اوضحت الامر

و السلام عليكم و رحمة الله و بركاته

تم تعديل هذه المشاركة بواسطة waeldalol في 6 يوليو 2006 في 20:14

▲ 1

رب اجعلني مقيم الصلاة ومن ذريتي ربنا وتقبل دعاء.

لا تنسى: "العقل مثل العضلة كلما استخدمته أكثر كلما ازدادت قوته"

#5

مرحبا بالأخ وائل ومرحبا بالجميع

شكرا على التعقيب.

اقتباس
لأنه لا توجد طريقة للتحكم به ولا يستطيع المبرمج زيادته أو حتى قراءة القيمة التالية له

التحكم به من أجل ماذا؟

إيقافه أو تصفيره وتغيير قيمة البدء وقيمة الزيادة؟

قراءة القيمة التالية له: ident_current('TableName')+1

اقتباس
و من اهم المشاكل او يعتبر مشكلة رئيسية في Identity ايضا هي gaps اي الفراغات:

اي عند حذف اي سجل من السجلات المضافة قديما يبقى الرقم ID الذي كان يُستخدم لهذا السجل بدون استخدام مما يؤدي الى تكبير الرقم في النهاية بوجود فراغات بين الارقام.

لن اخوض كثيرا في ال Identity و مشاكله

الغرض الأساسي من فتح هذا الموضوع هو للنقاش حول أفضلية identity أم GUID أم غيرهما كمفتاح أساسي.

بالنسبة للفراغات، الرابط الأول يوجد فيه طريقة حل لهذه المشكلة

طريقة أخرى تتمثل في إنشاء حقل إضافي لتطبيق خاصية أن القيمة المفتاحية لابد أن تكون مرتبة بدون أي فراغات، ومن ثم إنشاء delete trigger لمعالجة مسألة حذف حقل بترتيب قيم الحقل للسجلات التالية للسجل المحذوف

قمت بتطبيق هذه الطريقة وسأضعها بعد أن أرى المحاولات. :rolleyes:

اقتباس
ماذا تقصد بلا يمكن تكراره على مستوى قاعدة البيانات هذه المعلومة غير صحيحة نهائيا
اقتباس
هو رقم لا يمكن تكراره على مستوى العالم بأسره

مستوى قاعدة البيانات هو subset من مستوى العالم، أليس كذلك؟ :D

اقتباس
ويقول ممكن ان اقوم باضافة هذه السجلات

مع اعطاءها ارقام تسلسلية من جديد!! ما رأيكم حل مقنع ام لا ؟؟؟

الجواب: الامر اعقد بكثير من ان تقوم بتوليد ارقام تسلسلية في حالتنا هذه

توجد طريقة أخرى تتمثل في overriding Insert Command من الdata layer في التطبيق، وذلك باختيار جميع الحقول للدمج ماعدا حقل الidentity وتكوين الinsert command من هذه الحقول.

اقتباس
هو استخدام GUID كمفتاح اساسي للجدول و بما انّ GUID لا يمكن ان يتكرر فبالتالي يمكن دمج البيانات فورا

لاتنس أن استخدام GUID كحقل مفتاحي وبالتالي كclustered index سيبطيء عملية الإدخال بسبب قيامه بمراجعة وتعديل الفهرسة لكل السجلات الموجودة وفق السجل المُدخل الجديد، وذلك على حقل يشبه varchar بطول 32، وهذه هي المشكلة الرئيسية النوع GUID كحقل مفتاحي!!!

اقتباس
الجواب: الامر اعقد بكثير من ان تقوم بتوليد ارقام تسلسلية في حالتنا هذه و بسبب ضيق الوقت تم طرح المثال يحتوي على جدول واحد و لكن في الواقع هناك العديد من الجداول الاخرى تعتمد على المفتاح الاساسي

هل يمكنك ذكر هذه الحالات ومشاكلها لنتناقش حول كيفية حلها؟

فكر بطريقة أخرى

#6
اقتباس
الغرض الأساسي من فتح هذا الموضوع هو للنقاش حول أفضلية identity أم GUID أم غيرهما كمفتاح أساسي.

اذا سوف ادلي بكل ما اعرفه من مزايا وسيئات حتى نصل الى الافضل

اقتباس
بالنسبة للفراغات، الرابط الأول يوجد فيه طريقة حل لهذه المشكلة

طريقة أخرى تتمثل في إنشاء حقل إضافي لتطبيق خاصية أن القيمة المفتاحية لابد أن تكون مرتبة بدون أي فراغات، ومن ثم إنشاء delete trigger لمعالجة مسألة حذف حقل بترتيب قيم الحقل للسجلات التالية للسجل المحذوف

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

و لكن اليس هذه الطريقة مكلفة كثيرا من حيث الوقت تخيل انك تقوم بعمل حلقة على مجموعة كبيرة من السجلات لكي تعرف مكان الفراغ و من ثم لتقوم بترميمه

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

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

اقتباس
التحكم به من أجل ماذا؟

في SQL Server لا يمكن معرفة القيمة الجديدة لل Identity الى حين اكتمال تعليمة Insert و بعد اكتمال عملية Insert يمكنك معرفة قيمة Identity و هنا تكمن احيانا المشكلة

مثال لشرح الفكرة:

ليكن لديك جدول يحتوي على حقلين الاول حقل المفتاح الاساسي و هو رقمIdentity و الاخر هو حقل الاسم

بفرض نريد ان يكون حقل الاسم مجموع لحقل الرقم Identity+ مجموعة من الاحرف الاخرى اي اذا كان الرقم مثلا 11 يكون الاسم وائل11

اذا كان حقل الرقم Identity فهذا يعني انك لا تعرف ما القيمة التي سوف يتم وضعه في حقل الرقم و بالتالي كيف سوف تضيف الرقم الى الاسم؟؟

هل هناك طريقة لعمل هذا الشيئ بتعليمة واحدة ؟؟ باستخدام Identity؟؟

بينما اذا لم يكن حقل الرقم Identity فهنا انت تضع قيمة حقل الرقم القادم بيدك اي انت تتحكم بها و بالتالي تستطيع ان تضيف ما تريد الى حقل الاسم و من ثم

تقوم بعمل تعليمة Insert ليتم الادخال

قناعة جديدة مكتسبة:فائدة ال Identity في تأمين طريقة سريعة و فعالة في توليد حقل Unique ممتازة فعلاً و لكن هناك حالات لا تنفع استخدام Identity في الحقل كما في المثال السابق.

على فكرة انا لم اكن اعرف انه يوجد تلك المرونة في التعامل مع Identity و قد استفدت كثيرا من الرابط الاول حيث هذه المرونة قللت كثيرا من المشاكل التي كنت

سوف اطرحها في استخدام Identity.

اقتباس
مستوى قاعدة البيانات هو subset من مستوى العالم، أليس كذلك؟

نعم كلام صحيح و لكن لا يوجد اي شيئ يضمن تكرار ال GUID على مستوى قاعدة البيانات و انما ال GUID بطبيعته لا يمكن تكراره على مستوى العالم باسره

و هذه الميزة هي الفائدة الحقيقية من GUID فلا فائدة نهائيا من وجود رقم وحيد على مستوى قاعدة البيانات

اقتباس
توجد طريقة أخرى تتمثل في overriding Insert Command من الdata layer في التطبيق، وذلك باختيار جميع الحقول للدمج ماعدا حقل الidentity وتكوين الinsert command من هذه الحقول.

المشكلة تكمن في انه يوجد تكرار في ارقام المفتاح الاساسي الذي نود في دمجه و بالتالي يجب علينا تغيير قيمة المفتاح الاساسي

و لكن المفتاح الاساسي مرتبط بعدد كبير من الجداول المرتبطة بعدد اخر من الجداول كيف سوف تقوم بتعديل كل هذا

حتى ولو استطع ان تعيد صياغة كل شيئ من جديد فالوقت اللازلم لعمل ذلك كبير جدا في حال كانت البيانات المراد دمجها نسبيا

الان نأتي الى اين نستخدم ال GUID:

عند استخدام GUID كمفتاح اساسي لجدول فانه بلا شك سوف يكون هناك بطئ في توليد القيمة الجديدة له و في عملية الفهرسة و حتى في عمليات المقارنة

و لكن فائدة وجود GUID تستطيع ان تحجب هذه المساؤى ورائها.

يبدوا اننا الى الان لم ندرك ما هي فائدة ال GUID في قاعدة البيانات و متى يتم استخدامه؟

سوف اطرح مثال هذه المرة واضحا ابين من خلاله اهمية ال GUID:

بفرض اننا لدينا برنامج محاسبة يحتوي على حسابات مزودون و حسابات للزبائن و على المشتريات و المبيعات و يحتوي ايضا على المواد

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

اي كل فرع يجب ترحيل جميع البيانات المحاسبية في كل يوم الى المركز الرئيسي للشركة لكي يتم اعداد تقارير شاملة على مستوى الشركة

و بالتالي نقل لبيانات الحسابات الجديدة سواء كانت حسابات مزودين او حسابات زبائن التي تم فتحها و ايضا نقل المشتريات و المبيعات التي تمت على المواد

الان كيف سوف يتم نقل البيانات من الفروع الى المركز الرئيسي و ادخالها في قاعدة بياناته

اذا كان حقل المفتاح الاساسي لحسابات مثلا هو رقم تسلسلي سواء كان يتم التحكم به من البرنامح او من خلال Identity

فاكيد سوف يتم تكرار هذه الارقام بين الفروع لان الفروع منفصلة عن بعضها البعض ,لنفرض انه تم نقل البيانات بواسطة طريقة اتصال

الان نأتي لعملية دمج البيانات ضمن قاعدة بيانات المركز الرئيسي للشركة لا يمكن ذلك بسبب وجود ارقام مكررة لحقل المفتاح الاساسي و الذي من الضروري

جدا ان لا يكون هناك تكرار فيه.

هل سوف تقوم باعادة ترقيم كل من ارقام المفاتيح الاساسية من جديد لتعطيه ارقام تسلسلية جديدة تضمن فيها عدم تكرار قيمة المفتاح الاساسي؟

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

في عملية الدمج

بينما اذا استخدمت نمط GUID كمفتاح اساسي لن تصادف هذه المشكلة ابدا لانه حقل لا يمكن تكراره على مستوى العالم وبالتالي سوف يتم الدمج مباشرة و بسرعة كبيرة جدا

صحيح انه هناك بطئ ما في كل من عمليات DML و لكن الفائدة التي حصلنا عليها من استخدام ال GUID تعوض هذا البطئ.

فائدة اخرى لاستخدام ال GUID في قواعد البيانات:

هذه الفكرة اوضح من سابقتها

تخيل لدينا بنك له عدة فروع في بلد ما هذه البنك لديه زبائن كثر و ممكن لاي زبون ان يقوم بالاسفسار عن رصيده من اي فرع من الفروع

لاحظ هنا انه قاعدة البيانات الخاصة بالبنك قاعدة بيانات موزعة و ذلك لتخفيف الحمل على المركز الرئيسي

كيف سوف يتم في هذه الحالة الاستفسار عن الرصيد بناء على اي شيئ سوف يتم ذلك , اكيد على شيئ معرف وحيد لا يتكرر على مستوى زبائن البنك كلهم

و بما انه لا يوجد مركزية لقاعدة البيانات فبالتالي لا يمكن بحال من الاحوال ضمان عدم تكرار الرقم هنا يتم استخدام GUID للحصول على معرف وحيد

يتم الاستفسار من خلاله

ملاحظة:لقد وضعت شرح بسيط لقواعد البيانات الموزعة في نهاية الشرح.

هل اتضحت الفكرة ارجوا ان تكون كذلك :)

فائدة اخرى لاستخدام ال GUID في قواعد البيانات:

اذا كنت مثلا تريد تصميم برنامج لاتمتة جميع الطلاب التي في الجامعات و لكن الان لا يوجد ربط بين مراكز الجامعة و احتمال ان يتم دمج بيانات الطلاب مستقبلا

في مركز رئيسي و بالتالي في حال تم الدمج مستقبلا تكون ان جاهز لدمج مباشرة دون اي تغيير في ارقام الطلاب

هذه هي الفائدة الكبرى من ال GUID و قس على هذا الحالات المتشابهة

و غير ذلك يعتبر استخدام ال GUID كمفتاح اساسي للجدول غير مفيد نهائيا لانه لا حاجة لاستخدامه بوجود حقل من النوع int, bigint التي تستطيع من خلالها

ضمان فردية العامود انما تكون في هذه الحالة تستخدم GUID لابطاء كل شيئ دون جدوى

قواعد البيانات الموزعة:مجموعة من قواعد البيانات المترابطة منطقياً، والمخزنة على حواسب مختلفة مرتبطة مع بعضها البعض بشبكة.

عادة يتم إدارة قاعدة البيانات الموزعة وتأمين آليات الولوج access إلى البيانات بشكل شفاف transparent إلى المستخدمين و ذلك باستخدام نظام إدارة قواعد المعطيات الموزعة Distributed DBMS D-DBMS.

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

لقد سررت جدا بهذا النقاش مع شخص له وزنه في قواعدة البيانات املاً ان يتكرر في امور اخرى لكي استفيد اولا و افيد

و السلام عليكم و موضوع جميل فعلا

1

رب اجعلني مقيم الصلاة ومن ذريتي ربنا وتقبل دعاء.

لا تنسى: "العقل مثل العضلة كلما استخدمته أكثر كلما ازدادت قوته"

#7
اقتباس
هذا ما يدعى GUID ب 32 بايت

لقد اخطأت في هذا انا اسف خطأ مطبعي و انما حجمه هو 16 بايت كما ذكر الاخ welcom في بداية المشاركة

و قمت بتعديل المشاركة فوق ايضا

رب اجعلني مقيم الصلاة ومن ذريتي ربنا وتقبل دعاء.

لا تنسى: "العقل مثل العضلة كلما استخدمته أكثر كلما ازدادت قوته"

#8
اقتباس
بالنسبة للفراغات، الرابط الأول يوجد فيه طريقة حل لهذه المشكلة

طريقة أخرى تتمثل في إنشاء حقل إضافي لتطبيق خاصية أن القيمة المفتاحية لابد أن تكون مرتبة بدون أي فراغات، ومن ثم إنشاء delete trigger لمعالجة مسألة حذف حقل بترتيب قيم الحقل للسجلات التالية للسجل المحذوف

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

للرفع :rolleyes: :D

فكر بطريقة أخرى

#9
اقتباس
طريقة أخرى تتمثل في إنشاء حقل إضافي لتطبيق خاصية أن القيمة المفتاحية لابد أن تكون مرتبة بدون أي فراغات، ومن ثم إنشاء delete trigger لمعالجة مسألة حذف حقل بترتيب قيم الحقل للسجلات التالية للسجل المحذوف

سؤال:

لو فرضنا انّ حقل ID هو Identity حيث Seed(1,1)

الان قمنا باضافة مجموعة من السجلات و بعد ذلك قمنا بحذف بعضها حيث تم اضافة ابناء لهذه السجلات و الابناء لها ابناء .... وهكذا يعني توجد علاقات متعددة مع

عدة جداول تم ربطها مع حقل ID السابق

كيف سوف تقوم بإزاحة القيم و تزيل الفراغات؟ يعني السجلات المرتبطة مع ID ماذا سوف تفعل بها

هل لك ان توضح ما يدور في ذهنك!!! افصح اخي الكريم اكثر :blink:

رب اجعلني مقيم الصلاة ومن ذريتي ربنا وتقبل دعاء.

لا تنسى: "العقل مثل العضلة كلما استخدمته أكثر كلما ازدادت قوته"

#10

up

رب اجعلني مقيم الصلاة ومن ذريتي ربنا وتقبل دعاء.

لا تنسى: "العقل مثل العضلة كلما استخدمته أكثر كلما ازدادت قوته"

#11
اقتباس
الان قمنا باضافة مجموعة من السجلات و بعد ذلك قمنا بحذف بعضها حيث تم اضافة ابناء لهذه السجلات و الابناء لها ابناء .... وهكذا يعني توجد علاقات متعددة مع عدة جداول تم ربطها مع حقل ID السابق

يمكن تلافي هذه المشكلة بتطبيق شرط on delete cascade بين الجدول الذي يحوي خاصية auto identity والجداول الأبناء له،، وهذا يعتمد بالطبع على تحليل ما تريد تطبيقه.

الطريقة التي أريد شرحها طبقتها ضمن برنامج يتضمن إصدار فواتير، حيث أن جدول الفواتير كالآتي:

CREATE TABLE [dbo].[Invoices] (
	[invoice_id] [int] IDENTITY (1, 1) NOT NULL ,
	[invoice_cust_id] [int] NOT NULL ,
	[invoice_date] [datetime] NOT NULL ,
	[invoice_desc] [varchar] (800) COLLATE Arabic_CI_AS NULL ,
	[invoice_total] [money] NOT NULL ,
	[invoice_vat] [money] NOT NULL ,
	[invoice_grand_total] [money] NOT NULL, 
        primary key(invoice_id)
)

وكما هو واضح، الحقل invoice_id هو مفتاح هذا الجدول، وهو Auto Identity، وكنت أستعمل قيمة هذا الحقل كرقم متسلسل للفاتورة، ولكن طُلب مني أن تكون أرقام الفواتير متسلسلة ولا توجد أي أرقام محذوفة، حيث أن حذف أي فاتورة يحذف معه كل السجلات المرتبطة في جداول أخرى وذلك إما بdelete trigger أو on delete cascade أو جملة delete على السجلات المرتبطة تنفذ عقب حذف الفاتورة، وتكون داخل transaction مثلا.

بالنسبة للتحقق من تسلسل الIDs فقد قمت بإضافة حقل جدول الفواتير مخصص لتخزين الID مرتباً وهو الذي ستستخدم قيمته كرقم متسلسل للفاتورة، مثلا:

[invoice_report_id] [int] NULL

وقيمة هذا الحقل تكون max(invoice_report_id)+1 وتحسب قبل إضافة السجل الجديد ومن ثم تضاف في السجل الجديد.

CREATE  procedure InsertInvoice
@invoice_cust_id int, @invoice_date datetime, @invoice_desc varchar(800), 
@invoice_total money, @invoice_vat money, @invoice_grand_total money, 
@invoice_reporting_id int out
as select @invoice_reporting_id=max(invoice_report_id) from Invoices set @invoice_reporting_id=@invoice_reporting_id+1

insert into Invoices (invoice_cust_id, invoice_date, invoice_desc, invoice_total, 
invoice_vat, invoice_grand_total, invoice_maker_id, invoice_code, payed,  invoice_report_id)
values(@invoice_cust_id, @invoice_date, @invoice_desc, @invoice_total, @invoice_vat, 
@invoice_grand_total, @invoice_reporting_id)

أما بالنسبة للحذف فقمت بكتابة instead of delete trigger يقوم بعملية الحذف وإعادة ترتيب كل السجلات التي قيمة حقل invoice_reporting_id أكبر من قيمة الحقل للسجل المحذوف وذلك باستخدام الcursors وهذا هو:

CREATE TRIGGER InvoiceDeleted ON [dbo].[Invoices] 
instead of DELETE 
AS declare @invoice_id int

select @invoice_id=invoice_id from deleted /*
 This cursor is to re-numer the column invoice_report_id for the following records 
*/
DECLARE InvoicesCursor CURSOR FOR
SELECT * FROM Invoices WHERE Invoices.invoice_id >=@invoice_id


OPEN InvoicesCursor

FETCH NEXT FROM InvoicesCursor WHILE @@FETCH_STATUS = 0
BEGIN /*
to decrement the value of each record that is in the cursor
*/
	update Invoices
	set invoice_report_id=invoice_report_id-1
	where current of InvoicesCursor

    FETCH NEXT FROM InvoicesCursor END

CLOSE InvoicesCursor
DEALLOCATE InvoicesCursor

/*
 to delete record from other tables that has a foreign key 
 relationship with the deleted record
*/
declare @inv_items_count int
select @inv_items_count=count(*) from InvoiceItems where invoice_id=@invoice_id

if @inv_items_count>0
begin delete from InvoiceItems where invoice_id=@invoice_id
end

/* and now to delete the record it self
*/
delete from invoices where invoice_id=@invoice_id

توجد أيضا طريقة اخرى باستعمال الأمر SET IDENTITY INSERT OFF/ON أترك محاولتها لكم :)

فكر بطريقة أخرى

#12
waeldalol كتب:
و لكن اليس هذه الطريقة مكلفة كثيرا من حيث الوقت تخيل انك تقوم بعمل حلقة على مجموعة كبيرة من السجلات لكي تعرف مكان الفراغ و من ثم لتقوم بترميمه

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

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

في SQL Server لا يمكن معرفة القيمة الجديدة لل Identity الى حين اكتمال تعليمة Insert و بعد اكتمال عملية Insert يمكنك معرفة قيمة Identity و هنا تكمن احيانا المشكلة

و لكن إذا استخدت حلاً برمجياً فأنت لن تسلم من عملية الحلقة المكلفة جداً (و هي عنق الزجاجة في هذه المسألة في رأيي). بالإضافة لذلك فإنك ترمي مسؤولية إدارة إقفال قاعدة البيانات Lock Management على عاتق البرنامج المتصل بقاعدة البيانات و هو أمر ليس سهلاً أبداً بالذات في البرامج المتعددة الإتصالات مثل موافع الويب و ما إلى ذلك. كما أن هناك تكلفة overhead إضافية حيث أن إدارة الأقفال في الحل البرمجي لن تكون بكفاءة إدارة الأقفال في قاعدة البيانات نفسها.

و لكن أوافقك الرأي في مسألة الـGUID.

#13

همممم...

عجيب،، الضرائب ستختم على فواتير متسلسلة،،،

افرض مثلا أن الضرائب ختموا على القواتير من 100 إلى 200 .. وبعد أسبوع اضطر مدير المبيعات إلى حذف الفاتورة ذات الرقم 50،، ماذا سيحدث؟؟ الفواتير المختومة من الضرائب أصبحت غير مسجلة في النظام،، والعملاء لن يستطيوا استخراج البيانات من النظام لو أرادوا ذلك لأن الترقيم اختلف! فلو أراد العميل أن ينظر إلى الفاتورة رقم 100 فهو حقيقة سيرى معلومات الفاتورة رقم 101..!!

هل هذا واقع؟

#14

بكل صراحة استخدام GUID مفيد جدا و لا غنى عنه في

التطبيقات الحساسة و التي يمب أن يتم تميز العنصر عن أخر تميزا كبيرا

خوذ على سبيل المثال

قاعدة بيانات MemperShip ( Users ) في نظام

ASP.Net رقم السمتخدم هو GUID السبب إن لازم

يكون الرقم Unique

بتوقع منثل خدمة Microsoft PassPort

لو ما كانوا مستخدمين GUID كان في مشاكل للصبح

لو انت فكرت شوي Blogger.com عم يستخجم

GUID بدليل إنه لما المستخدم عم يسجل الدخول من خلال

برامج على نظام التشغيل أو ما يعرف بـ 3rd Party Programe

ما عم يعتمد على رقمين ( رقم المستخدم + رقم المدونة ) كـ رقم

و إنما كـ GUID

كذاك الحال في دفتر عناوين Microsoft Outlook

لما تعمل مزامنة بينه و بين أي هاتف

نفس القصة

GUID كبير الحجم بس يحل مشكلة جدا حدا كبيرة

سلام

#15

السلام عليكم

اقتباس
Auto Identity أم GUID كمفتاح أساسي؟, أيهما تفضل؟
عندي سؤال

بدي اكل فماذا أستخدم أأستخدم ملعقة او شوكة او استخدم يدي؟

سؤال عملي أكثر

اريد ان اعمل برنامج وسكون موبوط مع قاعدة بيانات

فايهما الأفضل Access او MSSQL او MySQL

-----------------

بالنسبة للTRIGGER الذي كتبة اخي walcom

نظرة سريعة فقط عليه وان شاء الله سأخذ وقتي للاطلاع على الكود الذي كتبته ولكن لماذا تستخدم ال cursor لما لا تستخدم التالي

declare @id int
	set @id=21
	delete from users where id=@id
	if @@rowcount >0
	   update  users  set id=id-1 where id >@id

فهو اسرع بكثير

واسف لم استطع قرائة الموضوع كاملا ولكن سوف افعل ان شاء الله

مع اني لا أعلم سبب اعادة ترتيب السجلات ولكن

تم تعديل هذه المشاركة بواسطة Mo7eb_Alrasool في 13 أكتوبر 2006 في 04:09

سبحانك اللهم وبحمدك أشهد ان لا اله الا أنت

أستغفرك وأتوب اليك

الهم صلي وسلم وبارك على سيدنا وحبيبنا محمد

هذا الموضوع مغلق.

مواضيع مشابهة