تحية!
في الفترة من 24 إلى 25 يونيو ، تم عقد مؤتمر Highload ++ Siberia 2019 في مدينة نوفوسيبيرسك ، وكان هناك أيضًا رجالنا
في تقرير "قواعد حاوية أوراكل (CDB / PDB) واستخدامهم العملي لتطوير البرمجيات" ، وسوف نقوم بنشر نسخة نصية في وقت لاحق قليلاً. لقد كان رائعًا ، شكرًا لـ
olegbunin على التنظيم ، وكذلك كل من
حضر .
في هذا المنشور ، نود أن نشارك معك المهام التي كانت في جناحنا بحيث يمكنك اختبار معرفتك في Oracle. تحت قص - 8 المهام ، خيارات الإجابة والشرح.
ما هي القيمة القصوى للتسلسل الذي سنراه نتيجة البرنامج النصي التالي؟
create sequence s start with 1; select s.currval, s.nextval, s.currval, s.nextval, s.currval from dual connect by level <= 5;
- 1
- 5
- 10
- 25
- لا ، سيكون هناك خطأ
الجوابوفقًا لوثائق Oracle (نقلت من 8.1.6):
ضمن عبارة SQL واحدة ، ستقوم Oracle بزيادة التسلسل مرة واحدة فقط في كل صف. إذا احتوى البيان على أكثر من مرجع واحد إلى NEXTVAL لتسلسل ، فإن Oracle يزيد التتابع مرة واحدة وتُرجع نفس القيمة لجميع تكرارات NEXTVAL. إذا احتوى البيان على مراجع إلى CURRVAL و NEXTVAL ، فإن Oracle تزيد التسلسل وتُرجع نفس القيمة لكل من CURRVAL و NEXTVAL بغض النظر عن ترتيبها داخل البيان.
وبالتالي ، فإن القيمة القصوى سوف تتوافق مع عدد الصفوف ، أي 5 .
كم عدد الصفوف ستكون في الجدول نتيجة البرنامج النصي التالي؟
create table t(i integer check (i < 5)); create procedure p(p_from integer, p_to integer) as begin for i in p_from .. p_to loop insert into t values (i); end loop; end; / exec p(1, 3); exec p(4, 6); exec p(7, 9);
الجوابوفقًا لوثائق Oracle (تم الاستشهاد بها من 11.2):
قبل تنفيذ أي عبارة SQL ، تقوم Oracle بتحديد نقطة حفظ ضمنية (غير متوفرة لك). ثم ، في حالة فشل العبارة ، تقوم Oracle بإعادة التشغيل تلقائيًا وإرجاع رمز الخطأ المطبق إلى SQLCODE في SQLCA. على سبيل المثال ، إذا تسببت عبارة INSERT في حدوث خطأ بمحاولة إدراج قيمة مكررة في فهرس فريد ، فسيتم استرجاع العبارة.
يتم أيضًا اعتبار مكالمة من العميل ومعالجتها كبيان واحد. وبالتالي ، يتم إكمال المكالمة الأولى إلى HP بنجاح عن طريق إدخال ثلاثة سجلات ؛ تنتهي المكالمة الثانية إلى HP بخطأ وتراجع السجل الرابع الذي تمكنت من إدراجه ؛ فشل المكالمة الثالثة ، وتظهر ثلاثة إدخالات في الجدول .
كم عدد الصفوف ستكون في الجدول نتيجة البرنامج النصي التالي؟
create table t(i integer, constraint i_ch check (i < 3)); begin insert into t values (1); insert into t values (null); insert into t values (2); insert into t values (null); insert into t values (3); insert into t values (null); insert into t values (4); insert into t values (null); insert into t values (5); exception when others then dbms_output.put_line('Oops!'); end; /
الجوابوفقًا لوثائق Oracle (تم الاستشهاد بها من 11.2):
يتيح لك قيد الاختيار تحديد شرط يجب أن يفي به كل صف في الجدول. لتلبية القيد ، يجب أن يجعل كل صف في الجدول الشرط إما TRUE أو غير معروف (بسبب وجود قيمة خالية). عندما يقوم Oracle بتقييم شرط قيد الاختيار لصف معين ، فإن أي أسماء أعمدة في الشرط تشير إلى قيم العمود في ذلك الصف.
وبالتالي ، ستنجح القيمة الخالية في الاختبار ، وسيتم تنفيذ الكتلة المجهولة بنجاح حتى محاولة إدراج القيمة 3. وبعد ذلك ، ستلقي كتلة معالجة الأخطاء استثناءً ، ولن يحدث الاستعادة وسيكون للجدول أربعة صفوف تحتوي على القيم 1 و null و 2 و null مرة أخرى.
ما أزواج القيم التي ستشغل نفس مقدار المساحة في الكتلة؟
create table t ( a char(1 char), b char(10 char), c char(100 char), i number(4), j number(14), k number(24), x varchar2(1 char), y varchar2(10 char), z varchar2(100 char)); insert into t (a, b, i, j, x, y) values ('Y', '', 10, 10, '', '');
- A و X
- ب و ص
- C و K
- C و Z
- ك و ض
- أنا و ي
- J و X
- جميع المدرجة
الجوابفيما يلي مقتطفات من الوثائق (12.1.0.2) لتخزين أنواع البيانات المختلفة في Oracle.
نوع بيانات Char
يحدد نوع بيانات CHAR سلسلة أحرف ذات طول ثابت في مجموعة أحرف قاعدة البيانات. يمكنك تحديد مجموعة أحرف قاعدة البيانات عند إنشاء قاعدة البيانات الخاصة بك. يضمن Oracle أن جميع القيم المخزنة في عمود CHAR لها الطول المحدد حسب الحجم في دلالات الطول المحددة. إذا قمت بإدخال قيمة أقصر من طول العمود ، فسوف تقوم Oracle بملء الفراغ بقيمة طول العمود.
VARCHAR2 نوع البيانات
يحدد نوع البيانات VARCHAR2 سلسلة أحرف متغيرة الطول في مجموعة أحرف قاعدة البيانات. يمكنك تحديد مجموعة أحرف قاعدة البيانات عند إنشاء قاعدة البيانات الخاصة بك. تقوم Oracle بتخزين قيمة حرف في عمود VARCHAR2 تمامًا كما تحددها ، دون أي حشوة فارغة ، بشرط ألا تتجاوز القيمة طول العمود.
رقم نوع البيانات
يخزن نوع البيانات NUMBER صفرًا وأرقامًا موجبة وسالبة ثابتة ذات قيم مطلقة من 1.0 × 10-130 إلى ولكن لا تشمل 1.0 × 10126. إذا حددت تعبير حسابي له قيمة مطلقة لها قيمة مطلقة أكبر من أو تساوي 1.0 × 10126 ، ثم Oracle بإرجاع خطأ. تتطلب كل قيمة NUMBER من 1 إلى 22 بايت. مع أخذ هذا في الاعتبار ، يمكن حساب حجم العمود بالبايت لقيمة بيانات رقمية معينة NUMBER (p) ، حيث p هي دقة قيمة معينة ، باستخدام الصيغة التالية: ROUND ((length (p) + s) / 2)) + 1 حيث تساوي s الصفر إذا كان الرقم موجبًا ، و s تساوي 1 إذا كان الرقم سالباً.
بالإضافة إلى ذلك ، نأخذ مقتطفات من الوثائق حول تخزين القيم الخالية.
القيمة الفارغة هي عدم وجود قيمة في العمود. تشير القيم الخالية إلى بيانات مفقودة أو غير معروفة أو غير قابلة للتطبيق. يتم تخزين القيم الخالية في قاعدة البيانات إذا كانت تقع بين الأعمدة ذات قيم البيانات. في هذه الحالات ، فإنها تتطلب 1 بايت لتخزين طول العمود (صفر). لا تتطلب أي فراغات زائدة في صف ما تخزينًا لأن رأس صف جديد يشير إلى أن الأعمدة المتبقية في الصف السابق خالية. على سبيل المثال ، إذا كانت الأعمدة الثلاثة الأخيرة من الجدول خالية ، فلن يتم تخزين أي بيانات لهذه الأعمدة.
بناءً على هذه البيانات ، نقوم ببناء المنطق. نعتقد أن قاعدة البيانات تستخدم الترميز AL32UTF8. في هذا الترميز ، سوف تشغل الحروف الروسية 2 بايت.
1) A و X ، قيمة الحقل a 'Y' هي 1 بايت ، قيمة الحقل x 'D' هي 2 بايت
2) B و Y ، سيتم إضافة "Vasya" بالقيمة b بمسافات تصل إلى 10 أحرف وستشغل 14 بايت ، و "Vasya" في d - سوف يستغرق 8 بايت.
3) C و K. كلا الحقلين فارغان ، وبعدهما توجد حقول مهمة ، لذلك يشغلونها بايت واحد.
4) C و Z. كلا الحقلين NULL ، لكن الحقل Z هو الأخير في الجدول ، لذلك لا يشغل مساحة (0 بايت). الحقل C يشغل 1 بايت.
5) K و Z. على غرار الحالة السابقة. القيمة في حقل K هي 1 بايت ، في Z - 0.
6) I و J. وفقًا للوثائق ، ستأخذ كلتا القيمتين 2 بايت لكل منهما. نعتبر الطول وفقًا للصيغة المأخوذة من الوثائق: round ((1 + 0) / 2) +1 = 1 + 1 = 2.
7) J و X. ستأخذ القيمة في الحقل J 2 بايت ، وستستغرق القيمة في حقل X 2 بايت.
في المجموع ، الخيارات الصحيحة هي: C و K و I و J و J و X.
ماذا سيكون عامل التجميع لمؤشر T_I تقريبًا؟
create table t (i integer); insert into t select rownum from dual connect by level <= 10000; create index t_i on t(i);
- حوالي العشرات
- حوالي المئات
- من أجل الآلاف
- من أجل عشرات الآلاف
الجوابوفقًا لوثائق Oracle (مقتبسة من 12.1):
بالنسبة إلى فهرس B-tree ، يقيس عامل تجميع الفهرس التجميع المادي للصفوف بالنسبة إلى قيمة الفهرس.
يساعد عامل تجميع الفهرس المُحسِّن في تحديد ما إذا كان فحص الفهرس أو مسح الجدول بالكامل أكثر فعالية لبعض الاستعلامات) يشير عامل التجميع المنخفض إلى مسح مؤشر فعال.
يشير عامل التجميع القريب من عدد الكتل في الجدول إلى أن الصفوف مرتبة فعليًا في كتل الجدول بواسطة مفتاح الفهرس. إذا أجرت قاعدة البيانات فحصًا كاملًا للجدول ، فإن قاعدة البيانات تميل إلى استرداد الصفوف حيث يتم تخزينها على القرص مرتبة حسب مفتاح الفهرس. يشير عامل التجميع القريب من عدد الصفوف إلى أن الصفوف مبعثرة بشكل عشوائي عبر كتل قاعدة البيانات فيما يتعلق بمفتاح الفهرس. إذا أجرت قاعدة البيانات فحصًا كاملًا للجدول ، فلن تقوم قاعدة البيانات باسترداد الصفوف بأي ترتيب تم الفرز حسب مفتاح الفهرس هذا.
في هذه الحالة ، يتم فرز البيانات بشكل مثالي ، وبالتالي فإن عامل التجميع سيكون مساوًا أو قريبًا لعدد الكتل المشغولة في الجدول. بالنسبة لحجم الكتلة القياسي البالغ 8 كيلو بايت ، يمكنك توقع أن حوالي ألف من قيم الأعداد الضيقة سيتم احتواؤها في كتلة واحدة ، وبالتالي فإن عدد الكتل ، ونتيجة لذلك سيكون عامل التجميع ، بترتيب عشرات .
في أي قيم من N سيتم تنفيذ البرنامج النصي التالي بنجاح في قاعدة بيانات منتظمة مع الإعدادات القياسية؟
create table t ( a varchar2(N char), b varchar2(N char), c varchar2(N char), d varchar2(N char)); create index t_i on t (a, b, c, d);
الجوابوفقًا لوثائق Oracle (تم الاستشهاد بها من 11.2):
حدود قاعدة البيانات المنطقية
وبالتالي ، يجب ألا يتجاوز الحجم الإجمالي للأعمدة المفهرسة 6 كيلو بايت. يعتمد كذلك على قاعدة الترميز المحددة. بالنسبة لترميز AL32UTF8 ، يمكن أن تشغل حرفًا واحدًا بحد أقصى 4 بايت ، لذلك في أسوأ الحالات ، ستناسب 6 كيلو بايت حوالي 1500 حرف. لذلك ، سوف يحظر Oracle إنشاء الفهرس عند N = 400 (عندما يكون طول المفتاح في أسوأ الأحوال هو 1600 حرفًا * 4 بايت + طول rowid) ، بينما
في إنشاء N = 200 (أو أقل) سيعمل إنشاء الفهرس دون مشاكل.
تم تصميم عبارة INSERT مع تلميح APPEND لتحميل البيانات في الوضع المباشر. ماذا يحدث إذا تم تطبيقه على الجدول الذي يعلق عليه المشغل؟
- سيتم تحميل البيانات في الوضع المباشر ، وسيعمل المشغل كما ينبغي
- سيتم تحميل البيانات في الوضع المباشر ، ولكن لن يتم تنفيذ المشغل
- سيتم تحميل البيانات في الوضع التقليدي ، وسيعمل المشغل كما ينبغي
- سيتم تحميل البيانات في الوضع التقليدي ، ولكن لن يتم تنفيذ المشغل
- لن يتم تحميل البيانات ، وسيتم إصلاح الخطأ
الجوابمن حيث المبدأ ، هذا هو أكثر مسألة المنطق. للعثور على الإجابة الصحيحة ، أقترح نموذج الاستدلال التالي:
- يتم إجراء الإدراج في الوضع المباشر من خلال التكوين المباشر لمجموعة البيانات ، عبر محرك SQL ، والذي يضمن السرعة العالية. وبالتالي ، فإن ضمان تنفيذ المشغل أمر صعب للغاية ، إن كان ذلك ممكنًا ، وليس هناك أي معنى في هذا ، لأنه سيؤدي إلى إبطاء عملية الإدراج بشكل كبير على أي حال.
- سيؤدي الفشل في التشغيل إلى حقيقة أن حالة قاعدة البيانات ككل (في الجداول الأخرى) تعتمد على الوضع الذي يتم إدخال البيانات فيه ، مع نفس البيانات في الجدول. هذا سوف يدمر بوضوح تكامل البيانات ولا يمكن تطبيقه كحل في الإنتاج.
- عدم القدرة على تنفيذ العملية المطلوبة ، بشكل عام ، يعامل كخطأ. ولكن هنا يجب أن نتذكر أن APPEND عبارة عن تلميح ، والمنطق العام للنصائح هو أنه يتم أخذها في الاعتبار إذا كان ذلك ممكنًا ، إن لم يكن ، يتم تنفيذ المشغل دون مراعاة التلميح.
وبالتالي ، فإن الجواب المتوقع هو أنه
سيتم تحميل البيانات في الوضع العادي (SQL) ، سيتم إطلاق المشغل.وفقًا لوثائق Oracle (مقتبسة من 8.04):
ستتسبب انتهاكات القيود في تنفيذ العبارة بشكل تسلسلي ، وذلك باستخدام مسار الإدراج التقليدي ، دون تحذيرات أو رسائل خطأ. الاستثناء هو التقييد على البيانات التي تصل إلى نفس الجدول أكثر من مرة في المعاملة ، والتي يمكن أن تسبب رسائل خطأ.
على سبيل المثال ، إذا كانت المشغلات أو التكامل المرجعي موجودة على الطاولة ، فسيتم تجاهل تلميح APPEND عند محاولة استخدام INSERT تحميل مباشر (مسلسل أو متوازي) ، وكذلك تلميح أو جملة PARALLEL ، إن وجدت.
ماذا يحدث عند تنفيذ البرنامج النصي التالي؟
create table t(i integer not null primary key, j integer references t); create trigger t_a_i after insert on t for each row declare pragma autonomous_transaction; begin insert into t values (:new.i + 1, :new.i); commit; end; / insert into t values (1, null);
- التنفيذ الناجح
- فشل بناء الجملة
- خطأ غير صالح في المعاملة بلا اتصال
- خطأ متعلق بتجاوز تداخل الحد الأقصى للمكالمات
- خطأ انتهاك المفتاح الخارجي
- خطأ قفل
الجوابيتم إنشاء الجدول والمشغل بشكل صحيح ويجب ألا تؤدي هذه العملية إلى مشاكل. يُسمح أيضًا بالمعاملات المستقلة في المشغل ، وإلا سيكون من المستحيل ، على سبيل المثال ، التسجيل.
بعد إدخال السطر الأول ، قد يؤدي المشغل الناجح إلى إدراج السطر الثاني ، فيما يتعلق بالعمل الذي سيعمل المشغل من جديد ، وأدخل السطر الثالث ، وما إلى ذلك حتى يسقط البيان بسبب تجاوز الحد الأقصى لتداخل المكالمات. ومع ذلك ، يتم تشغيل نقطة خفية أخرى. في وقت تنفيذ المشغل ، لم يتم تنفيذ الالتزام لأول سجل مدرج. لذلك ، يحاول المشغل الذي يعمل في معاملة مستقلة إدراج صف في الجدول يشير بواسطة مفتاح خارجي إلى سجل لم يتم الالتزام به بعد. يؤدي هذا إلى الانتظار (تنتظر المعاملة المستقلة الالتزام الرئيسي لفهم ما إذا كان من الممكن إدراج البيانات) وفي نفس الوقت تنتظر المعاملة الرئيسية الالتزام المستقل بمواصلة العمل بعد بدء التشغيل. تحدث حالة توقف تام ، ونتيجة لذلك ، يتم إعادة تشغيل معاملة مستقلة للسبب المرتبط بالأقفال .