Oracle إلى SQL Server و SQL Server إلى Oracle Migration Guide - Pt. 2
نشرت: 2022-03-11ناقش الجزء الأول من هذه السلسلة الاختلافات بين Oracle Database و Microsoft SQL Server في تنفيذها للمعاملات ، مع التركيز على المخاطر التي قد يواجهها المرء أثناء عمليات ترحيل Oracle إلى SQL Server والعكس بالعكس. ستغطي هذه الدفعة التالية عددًا من عناصر بناء جملة SQL شائعة الاستخدام والتي ليس لها تطابق أو لها معنى أو استخدام مختلف تمامًا عبر قسم Oracle – SQL Server.
التسلسلات في أعمدة Oracle و Identity في SQL Server
هناك فجوة طويلة الأمد في مجتمع قاعدة البيانات بين معسكرين: الوطنيون للمفاتيح الطبيعية وأنصار المفاتيح الاصطناعية (أو "البديلة").
أنا نفسي أدافع عن المفاتيح الطبيعية ولكني أجد نفسي في كثير من الأحيان أصنع بدائل لسبب أو لآخر. ولكن إذا تركنا جوهر هذا النقاش جانبًا ، فلنلقِ نظرة على الآليات القياسية لإنشاء مفاتيح اصطناعية: تسلسلات Oracle وأعمدة هوية SQL Server.
تسلسل أوراكل هو كائن من الدرجة الأولى على مستوى قاعدة البيانات. في المقابل ، عمود هوية SQL Server هو نوع عمود ، وليس كائنًا.
عند استخدام تسلسل أوراكل لإنشاء مفتاح جدول - عادةً ما يكون مفتاحًا أساسيًا - يكون مضمونًا للزيادة ، وبالتالي يكون فريدًا. لكن ليس من المضمون أن تكون متتالية. في الواقع ، حتى في عمليات التنفيذ جيدة التصميم ، فمن المرجح أن يكون بها بعض الثغرات. لذلك لا ينبغي أن يعتمد تطبيق Oracle على القيم المولدة بالتسلسل حتى تكون متتالية.
أيضًا ، تتم إدارة التسلسل من خلال قاموس بيانات قاعدة بيانات أوراكل ، لذلك سيكون الأمر مستهلكًا للموارد (ومرهقًا) لإنشاء تسلسل مخصص لدعم كل مفتاح بديل. يمكن أن يدعم كائن التسلسل الفردي عدة مفاتيح أو حتى جميع المفاتيح البديلة.
من ناحية أخرى ، عندما تحتاج عمليات متعددة إلى الوصول إلى NEXTVAL
(القيمة المتزايدة التالية) من تسلسل ، سيصبح التسلسل موردًا حاسمًا يمكن الوصول إليه مرة واحدة. ستجعل جميع العمليات التي تصل إليها متسلسلة بشكل صارم بشكل فعال ، وتحول أي تنفيذ متعدد الخيوط (فردي أو متعدد الخوادم) إلى عملية ذات خيوط واحدة ، مع أوقات انتظار طويلة وذاكرة عالية / استخدام منخفض لوحدة المعالجة المركزية.
مثل هذه التطبيقات تحدث بالفعل. يتمثل الحل لهذه المشكلة في تحديد كائن التسلسل المعني بقيمة ذاكرة تخزين مؤقت معقولة - بمعنى أنه يتم تحديد نطاق محدد من القيم (سواء كان 100 أو 100 ألف) في ذاكرة تخزين مؤقت لعملية استدعاء ، مسجلة في قاموس البيانات كما هو مستخدم ، وتصبح متاحة لهذه العملية بالذات دون الحاجة إلى الوصول إلى قاموس البيانات في كل مرة يتم استدعاء NEXTVAL
.
ولكن هذا هو بالضبط سبب إنشاء الفجوات حيث من غير المحتمل استخدام جميع القيم المخزنة مؤقتًا. وهذا يعني أيضًا أنه عبر عمليات متعددة في جلسات متوازية ، يمكن عكس بعض قيم التسلسل المسجل ترتيبًا زمنيًا. لا يمكن أن يحدث هذا الانقلاب في عملية واحدة ما لم تتم إعادة تعيين قيمة التسلسل أو تغييرها إلى الخلف. لكن هذا السيناريو الأخير يرقى إلى البحث عن مشكلة: يجب أن يكون غير ضروري ، وإذا تم تنفيذه بشكل غير صحيح ، فقد يؤدي إلى إنشاء قيم مكررة.
لذلك ، فإن الطريقة الصحيحة الوحيدة لاستخدام تسلسلات Oracle هي إنشاء مفاتيح بديلة: مفاتيح فريدة ولكن لا يُفترض أنها تحتوي على أي معلومات أخرى قابلة للاستخدام بشكل موثوق.
أعمدة الهوية في SQL Server
ماذا عن SQL Server؟ بينما تم تقديم التسلسلات ذات الوظائف والتنفيذ المتشابهين جدًا مع نظيرتها من Oracle في SQL Server 2012 ، إلا أنها ليست تقنية من الدرجة الأولى. مثل إضافات الميزات الأخرى ، فهي منطقية للتحويل من Oracle ، ولكن عند تنفيذ مفاتيح بديلة من البداية على SQL Server ، يعد IDENTITY
خيارًا أفضل بكثير.
IDENTITY
هي كائن "فرعي" للجدول. لا يصل إلى أي موارد خارج الجدول ويضمن أن يكون تسلسليًا ما لم يتم التلاعب به عن عمد. وهو مصمم خصيصًا لهذه المهمة بالذات ، بدلاً من التوافق الدلالي مع Oracle.
مع تطبيق Oracle لوظيفة IDENTITY
في الإصدار 12.1 ، من الطبيعي أن نتساءل كيف فعلت بدونها من قبل ، ولماذا نفذتها الآن ، ولماذا احتاج SQL Server إليها منذ البداية (من أصول Sybase SQL Server).
والسبب هو أن Oracle كانت تتمتع دائمًا بميزة مفتاح هوية: ROWID
pseudocolumn ، الذي يحتوي على نوع بيانات ROWID
أو UROWID
. هذه القيمة غير رقمية ( ROWID
و UROWID
هما نوعان من أنواع بيانات Oracle مملوكين) ويحددان سجل البيانات بشكل فريد.
على عكس ROWID
IDENTITY
بـ Oracle بسهولة (يمكن الاستعلام عنه ، ولكن لا يمكن إدراجه أو تعديله) ، ويتم إنشاؤه في الخلفية لكل صف في كل جدول Oracle. أيضًا ، الطريقة الأكثر فاعلية للوصول إلى أي صف بيانات في قاعدة بيانات Oracle هي من خلال ROWID
، لذلك يتم استخدامه كأسلوب لتحسين الأداء. أخيرًا ، يحدد ترتيب فرز مخرجات الاستعلام الافتراضي ، لأنه يقوم بشكل فعال بفهرسة التخزين منخفض المستوى لبيانات الصف.
إذا كان ROWID
من Oracle مهمًا جدًا ، فكيف نجا SQL Server كل تلك السنوات والإصدارات بدونه؟ باستخدام أعمدة IDENTITY
كمفاتيح أساسية (بديلة).
من المهم ملاحظة الاختلاف في تنفيذ بنية الفهرس بين Oracle و SQL Server.
في SQL Server ، يكون الفهرس الأول - المفتاح الأساسي ، في أغلب الأحيان - متفاوتًا ؛ هذا يعني أنه الأكثر شيوعًا ، يتم ترتيب البيانات الموجودة في ملف البيانات الأساسي بواسطة هذا المفتاح. على جانب أوراكل ، ما يعادل الفهرس العنقودي هو جدول منظم بفهرس. هذا بناء اختياري في Oracle يتم استخدامه بشكل متقطع ، فقط حسب الحاجة - لجداول البحث للقراءة فقط ، على سبيل المثال.
يجب تنفيذ جميع أنماط التصميم في Oracle التي تستند إلى استخدام ROWID
(مثل إلغاء البيانات المكررة) استنادًا إلى أعمدة IDENTITY
عند الترحيل إلى SQL Server.
أثناء الترحيل من استخدام IDENTITY
على SQL Server إلى استخدام IDENTITY
على Oracle ، يمكن أن ينتج رمزًا صحيحًا وظيفيًا ، ولكنه ليس مثاليًا ، لأنه من جانب Oracle ، فإن ROWID
سيعمل بشكل أكثر كفاءة.
وينطبق الشيء نفسه عند إجراء تحويل بسيط لبناء جملة SQL لنقل تسلسلات Oracle إلى SQL Server: سيتم تشغيل الكود ، ولكن استخدام IDENTITY
هو الخيار المفضل كثيرًا من حيث بساطة الكود والأداء.
الفهارس المصفاة في Microsoft SQL Server
منذ سنوات ، قدم Microsoft SQL Server 2008 عددًا من الميزات المهمة التي حولته إلى قاعدة بيانات مؤسسية من الدرجة الأولى حقًا. واحد الذي أنقذ يومي أكثر من مرة تمت تصفيته الفهارس.

الفهرس الذي تمت تصفيته هو فهرس غير متفاوت العنقودي (أي واحد موجود كملف بيانات خاص به) يحتوي على WHERE
. هذا يعني أن ملف الفهرس يحتوي فقط على سجلات البيانات ذات الصلة بالفقرة. للاستفادة الكاملة من الفهارس التي تمت تصفيتها ، يجب أن تحتوي أيضًا على عبارة INCLUDE
التي تسرد جميع الأعمدة المطلوبة عند إرجاع مجموعة بيانات. عندما يتم تحسين استعلامك لاستخدام فهرس تمت تصفيته محددًا يتضمن جميع نقاط البيانات المطلوبة ، يحتاج محرك قاعدة البيانات فقط إلى الوصول إلى ملف فهرس (صغير) دون النظر حتى إلى ملف بيانات الجدول الأساسي.
كان هذا ذا قيمة خاصة بالنسبة لي منذ بضع سنوات عند العمل مع طاولة بحجم تيرابايت. احتاج العميل المعني بشكل متكرر للوصول إلى جزء بسيط فقط من نسبة مئوية من السجلات النشطة في أي وقت. لم يكن التنفيذ الأولي لهذا الوصول (الذي تم تشغيله بواسطة إجراءات واجهة المستخدم للمستخدم النهائي) بطيئًا بشكل مؤلم فحسب - لقد كان مجرد غير قابل للاستخدام. عندما أضفت فهرسًا تمت تصفيته باستخدام INCLUDE
s المطلوب ، أصبح بحثًا أقل من مللي ثانية. كان الوقت الذي أمضيته في مهمة التحسين هذه ساعة واحدة فقط.
من المؤكد أن الفهارس التي تمت تصفيتها لها بعض القيود. لا يمكن أن تتضمن أعمدة LOB ، وهناك قيود على الشروط التي يمكن أن تتضمنها جمل WHERE
التي يمكن أن تتضمنها الفهارس نفسها ، وتضيف إلى مساحة تخزين قاعدة البيانات. ولكن بشرط أن تتناسب حالة الاستخدام مع هذه المعلمات ، فإن مقايضات التخزين عادةً ما تكون ثانوية جدًا مقارنةً بتعزيز الأداء الكبير الذي يمكن أن توفره الفهارس التي تمت تصفيتها.
ماذا عن الفهارس المصفاة في Oracle Database؟
وجدت نفسي لاحقًا ضمن فريق كبير في شركة Fortune 500 بصفتي مطورًا / DBA في مشروع ترحيل SQL Server إلى Oracle. تم تنفيذ التعليمات البرمجية المحيطة بقاعدة البيانات المصدر - SQL Server 2008 - بشكل سيئ ، مع الأداء الضئيل الذي جعل التحويل أمرًا ضروريًا: كانت مهمة المزامنة الخلفية اليومية تعمل لمدة أطول من 23 ساعة. لم يكن يحتوي على فهارس تمت تصفيتها ، ولكن في نظام Oracle 11g الجديد ، رأيت حالات متعددة حيث تكون الفهارس التي تمت تصفيتها مفيدة للغاية. لكن Oracle 11g لا تحتوي على فهارس تمت تصفيتها!
ولا يتم تنفيذ الفهارس التي تمت تصفيتها في أحدث Oracle 18c.
لكن مهمتنا كمحترفين تقنيين هي تحقيق أقصى استفادة مما لدينا. لذلك قمت بتطبيق ما يعادل الفهارس المفلترة في نظام Oracle 11g (ونفس التقنية التي استخدمتها لاحقًا في 12c). تعتمد الفكرة على كيفية معالجة Oracle للقيم NULL
، ويمكن استخدامها في أي إصدار من Oracle.
لا تتعامل Oracle مع القيمة NULL
بنفس الطريقة التي تتعامل بها البيانات العادية. NULL
في Oracle ليست شيئًا - فهي غير موجودة. نتيجة لذلك ، إذا قمت بتعريف العمود المفهرس على أنه NULLABLE
وكنت تبحث بقيم غير NULL
، فلن يحتوي ملف بيانات الفهرس إلا على سجلات الاهتمام. نظرًا لأن تعريف Oracle index لا يحتوي على عبارة INCLUDE
، فستحتاج إلى إنشاء فهرس مركب بجميع الأعمدة التي تحتاج إلى تضمينها في مجموعة النتائج. (تحتوي هذه التقنية على بعض النفقات العامة مقارنة بعبارة INCLUDE
الخاصة بـ SQL Server ، ولكنها غير ذات أهمية إلى حد معقول.)
يؤدي تطبيق الحل البديل هذا إلى إضافة قيود: يجب أن يسمح عمود الفهرس البادئ NULL
، وبالتالي لا يمكن أن يكون المفتاح الأساسي للجدول. ومع ذلك ، يمكن أن يكون عمودًا مشتقًا أو محسوبًا تم إنشاؤه خصيصًا لدعم طريقة تحسين الأداء هذه. بمعنى ما ، يكون العمود الأول للفهرس ثنائي منطقيًا: قيم غير NULL
للبيانات المضمنة في البحث ، و NULL
لأي بيانات يجب أن تكون "غير مرئية".
الخيار الآخر المحتمل في ترحيل منطق الفهرس المصفى من SQL Server إلى Oracle هو تنفيذ فهرس (أو الجدول بالكامل) على أنه مقسم. في هذه الحالة ، سيتم الوصول إلى قسم الفهرس ذي الصلة فقط بواسطة محرك قاعدة البيانات - يتم تنفيذ الاستعلامات المقدمة بشكل صحيح باستخدام شرط التقسيم الدقيق في عبارات WHERE
الخاصة بهم.
سيعمل هذا بشكل جيد ، حتى على نطاق واسع ، على بيانات ثابتة نسبيًا ، ولكن يمكن أن يضع عبء صيانة كبير على فريق DBA إذا تم تطبيقه على البيانات المتغيرة بشكل متكرر. على سبيل المثال ، عند تحسين الوصول إلى بيانات اليوم في تطبيق يركز على الوقت: سيحتاج فريق DBA إلى إعادة تعريف الأقسام على أساس يومي. في حين أن إعادة التعريف هذه يمكن كتابتها في مهمة صيانة ليلية ، فإنها تجعل نظامك أكثر تعقيدًا وتقدم نقاط فشل نظامية محتملة جديدة.
لذلك ، يحتاج المرء إلى أن يكون محددًا وحذرًا للغاية كلما احتاج منطق فهرس SQL Server الذي تمت تصفيته إلى Oracle.
كيفية التعامل مع التحويلات
باستخدام ترحيل Oracle إلى SQL Server ، ابحث عن فرص التحسين باستخدام الفهارس التي تمت تصفيتها. لن ترى فهارس تمت تصفيتها في Oracle ، ولكن قد ترى فهارس تتضمن قيمًا NULL
. لا تنسخها كما هي: قد يكون هذا هو أفضل مكان يمكنك فيه تعزيز الأداء وتحسين التصميم في التحويل الخاص بك.
بالنسبة لعمليات الترحيل من SQL Server إلى Oracle ، إذا رأيت فهارس تمت تصفيتها ، فابحث عن كيفية تجنب حدوث اختناق في الأداء في تعليمات Oracle البرمجية المقابلة. انظر كيف يمكنك إعادة تصميم تدفق البيانات للتعويض عن تعزيز الأداء المفقود الذي قدمته الفهارس التي تمت تصفيتها في تطبيق المصدر.
تمت إزالة الغموض عن تحديات ترحيل SQL Server إلى Oracle / Oracle إلى SQL Server
بالنسبة لمشاريع الترحيل بين Oracle و SQL Server في أي من الاتجاهين ، من المهم أن يكون لديك فهم أعمق للميكانيكا المستخدمة. عندما تحتوي الإصدارات الحالية من قواعد البيانات المعنية (Oracle 18c و Microsoft SQL Server 2017 *) على معادلات معجمية لوظائف بعضها البعض - على سبيل المثال ، في التسلسل والهوية - فقد يبدو الأمر وكأنه فوز سهل. لكن نسخ تصميم جيد على أحد أنظمة RDBMS مباشرة إلى الآخر يمكن أن ينتج عنه رمز معقد بلا داع وضعيف الأداء.
في الجزء التالي والأخير من هذه السلسلة ، أغطي اتساق القراءة واستخدام أدوات الترحيل. ابقوا متابعين!
* لم يخرج SQL Server 2019 (أو "15.x") لفترة كافية لتبني المؤسسة على نطاق واسع.