في آخر مرة تحدثنا فيها عن تناسق البيانات ، درسنا الفرق بين مستويات مختلفة من عزل المعاملة من خلال أعين المستخدم ، وتوصلنا إلى معرفة أهمية معرفة ذلك. بدأنا الآن في معرفة كيفية تطبيق PostgreSQL للعزلة القائمة على الصور وآلية الإصدارات المتعددة.
في هذه المقالة ، سننظر في كيفية وجود البيانات فعليًا في الملفات والصفحات. هذا يقودنا بعيدًا عن موضوع العزلة ، لكن مثل هذا الانحدار ضروري لفهم المزيد من المواد. نحن بحاجة إلى فهم كيفية عمل تخزين البيانات منخفض المستوى.
العلاقة (العلاقات)
إذا نظرت داخل الجداول والفهارس ، اتضح أنها مرتبة بطريقة مماثلة. كل من ذلك وكائنات أخرى تحتوي على بعض البيانات التي تتكون من خطوط.
حقيقة أن الجدول يتكون من الصفوف لا شك فيه ؛ بالنسبة للمؤشر ، هذا أقل وضوحًا. ومع ذلك ، تخيل شجرة B: تتكون من العقد التي تحتوي على قيم مفهرسة وروابط لعقد أخرى أو إلى صفوف الجدول. يمكن اعتبار هذه العقد خطوط فهرس - في الواقع ، كما هي.
في الواقع ، لا يزال هناك عدد من الكائنات مرتبة بطريقة مماثلة: التسلسلات (جداول ذات صف أحادي بشكل أساسي) ، طرق عرض ملموسة (بشكل أساسي جداول تتذكر الاستعلام). ثم هناك طرق العرض المعتادة ، والتي في حد ذاتها لا تخزن البيانات ، ولكن من جميع النواحي الأخرى تشبه الجداول.
تسمى كل هذه الكائنات في PostgreSQL
علاقة الكلمات الشائعة. الكلمة مؤسفة للغاية لأنها مصطلح من نظرية العلائقية. يمكنك رسم موازٍ بين العلاقة والجدول (العرض) ، ولكن بالتأكيد ليس بين العلاقة والفهرس. ولكن حدث ذلك: جذور PostgreSQL الأكاديمية تجعل نفسها تشعر. أعتقد أنه في البداية كان يسمى الجداول والآراء ، والباقي نما مع مرور الوقت.
علاوة على ذلك ، من أجل البساطة ، سوف نتحدث فقط عن الجداول والفهارس ، ولكن بقية
العلاقات مهيكلة تمامًا.
الطبقات (الشوك) والملفات
عادة ، كل علاقة لها عدة
طبقات (شوكات). تكون الطبقات من عدة أنواع وكل منها يحتوي على نوع معين من البيانات.
إذا كانت هناك طبقة ، فسيتم تمثيلها في البداية
بملف واحد. يتكون اسم الملف من معرف رقمي يمكن إضافة النهاية المطابقة لاسم الطبقة إليه.
ينمو الملف تدريجياً وعندما يصل حجمه إلى 1 غيغابايت ، يتم إنشاء الملف التالي من نفس الطبقة (تسمى هذه الملفات أحيانًا
شرائح ). يتم إلحاق رقم القطعة بنهاية اسم الملف.
نشأت قيود حجم ملف 1 جيجابايت تاريخيا لدعم أنظمة الملفات المختلفة ، وبعضها لا يمكن أن يعمل مع الملفات الكبيرة. يمكن تغيير القيد عند إنشاء PostgreSQL (
./configure --with-segsize
).
وبالتالي ، يمكن أن تتوافق عدة ملفات مع علاقة واحدة على القرص. على سبيل المثال ، بالنسبة لطاولة صغيرة سيكون هناك 3 منهم.
سيتم وضع جميع ملفات الكائنات التي تنتمي إلى مساحة جدول واحدة وقاعدة بيانات واحدة في دليل واحد. يجب أن يؤخذ ذلك في الاعتبار لأن أنظمة الملفات عادة لا تعمل بشكل جيد مع عدد كبير من الملفات في الدليل.
لاحظ فقط أن الملفات ، بدورها ، تنقسم إلى
صفحات (أو
كتل ) ، عادةً 8 كيلو بايت. سنتحدث عن الهيكل الداخلي للصفحات أدناه.

الآن دعونا نلقي نظرة على أنواع الطبقات.
الطبقة الرئيسية هي البيانات نفسها: نفس الجدول أو صفوف الفهرس. توجد الطبقة الرئيسية لأي علاقة (باستثناء التمثيلات التي لا تحتوي على بيانات).
تتكون أسماء الملفات في الطبقة الرئيسية من معرف رقمي فقط. فيما يلي مثال على مسار ملف الجدول الذي أنشأناه في المرة الأخيرة:
=> SELECT pg_relation_filepath('accounts');
pg_relation_filepath ---------------------- base/41493/41496 (1 row)
من أين تأتي هذه المعرفات؟ يتوافق الدليل الأساسي مع مساحة الجداول pg_default ، والدليل الفرعي التالي يتوافق مع قاعدة البيانات ، والملف الذي يهمنا فيه موجود بالفعل:
=> SELECT oid FROM pg_database WHERE datname = 'test';
oid ------- 41493 (1 row)
=> SELECT relfilenode FROM pg_class WHERE relname = 'accounts';
relfilenode ------------- 41496 (1 row)
المسار نسبي ، يتم حسابه من دليل البيانات (PGDATA). علاوة على ذلك ، يتم حساب جميع المسارات تقريبًا في PostgreSQL من PGDATA. بفضل هذا ، يمكنك نقل PGDATA بأمان إلى مكان آخر - لا يحتفظ بأي شيء (إلا إذا كنت قد تحتاج إلى تكوين المسار إلى المكتبات في LD_LIBRARY_PATH).
نحن ننظر إلى أبعد من ذلك في نظام الملفات:
postgres$ ls -l --time-style=+ /var/lib/postgresql/11/main/base/41493/41496
-rw------- 1 postgres postgres 8192 /var/lib/postgresql/11/main/base/41493/41496
توجد
طبقة تهيئة فقط للجداول غير اليومية (التي تم إنشاؤها باستخدام UNLOGGED) وفهارسها. هذه الأشياء لا تختلف عن الأشياء العادية ، إلا أنه لا يتم تسجيل الإجراءات معها في سجل السجل المسبق. وبسبب هذا ، يكون العمل معهم أسرع ، ولكن في حالة حدوث عطل ، يكون من المستحيل استعادة البيانات في حالة متسقة. لذلك ، عند الاسترداد ، يقوم PostgreSQL ببساطة بحذف جميع طبقات هذه الكائنات ويكتب طبقة التهيئة إلى مكان الطبقة الرئيسية. والنتيجة هي "دمية". سنتحدث عن اليومية بالتفصيل ، ولكن في دورة مختلفة.
تتم كتابة جدول الحسابات ، لذا لا توجد طبقة تهيئة له. ولكن بالنسبة للتجربة ، يمكنك تعطيل التسجيل:
=> ALTER TABLE accounts SET UNLOGGED; => SELECT pg_relation_filepath('accounts');
pg_relation_filepath ---------------------- base/41493/41507 (1 row)
تتضمن القدرة على تمكين وتعطيل عمل اليومية أثناء التنقل ، كما يتبين من المثال ، الكتابة فوق البيانات في ملفات بأسماء مختلفة.
طبقة التهيئة لها نفس اسم الطبقة الرئيسية ، ولكن مع اللاحقة "_init":
postgres$ ls -l --time-style=+ /var/lib/postgresql/11/main/base/41493/41507_init
-rw------- 1 postgres postgres 0 /var/lib/postgresql/11/main/base/41493/41507_init
خريطة المساحة الحرة (خريطة المساحة الحرة) - طبقة فيها مساحة فارغة داخل الصفحات. يتغير هذا المكان باستمرار: عند إضافة إصدارات جديدة من الأوتار ، فإنها تتناقص ، بينما يزيد التنظيف - يزداد. يتم استخدام خريطة المساحة الحرة عند إدراج إصدارات جديدة من الصفوف للعثور بسرعة على صفحة مناسبة تناسب البيانات المراد إضافتها.
تحتوي خريطة المساحة الحرة على اللاحقة "_fsm". لكن الملف لا يظهر على الفور ، ولكن فقط إذا لزم الأمر. أسهل طريقة لتحقيق ذلك هي تنظيف الطاولة (لماذا - دعنا نتحدث في الوقت المناسب):
=> VACUUM accounts;
postgres$ ls -l --time-style=+ /var/lib/postgresql/11/main/base/41493/41507_fsm
-rw------- 1 postgres postgres 24576 /var/lib/postgresql/11/main/base/41493/41507_fsm
خريطة الرؤية هي طبقة يتم فيها تمييز الصفحات التي تحتوي على الإصدارات الحالية فقط من السلاسل ببت واحد. بمعنى تقريبي ، يعني هذا أنه عندما تحاول معاملة قراءة سطر من هذه الصفحة ، يمكن عرض الخط دون التحقق من ظهوره. سنبحث بالتفصيل كيف يحدث هذا في المقالات التالية.
postgres$ ls -l --time-style=+ /var/lib/postgresql/11/main/base/41493/41507_vm
-rw------- 1 postgres postgres 8192 /var/lib/postgresql/11/main/base/41493/41507_vm
صفحة
كما قلنا بالفعل ، يتم تقسيم الملفات بشكل منطقي إلى صفحات.
عادةً ما يكون حجم الصفحة 8 كيلو بايت. يمكنك تغيير الحجم داخل حدود معينة (16 كيلو بايت أو 32 كيلوبايت) ، ولكن فقط أثناء التجميع (
./configure --with-blocksize
). يمكن أن تعمل النسخة المجمعة والعاملة مع صفحات بحجم واحد فقط.
بغض النظر عن الطبقة التي تنتمي إليها الملفات ، يتم استخدامها بواسطة الخادم بنفس الطريقة تقريبًا. تتم قراءة الصفحات أولاً في ذاكرة التخزين المؤقت ، حيث يمكن للعمليات قراءتها وتعديلها ؛ ثم ، إذا لزم الأمر ، يتم دفع الصفحات مرة أخرى إلى القرص.
تحتوي كل صفحة على ترميز داخلي وتحتوي عمومًا على الأقسام التالية:
0 + ----------------------------------- +
| العنوان |
24 + ----------------------------------- +
| مجموعة من المؤشرات إلى سلاسل الإصدار |
أقل + ----------------------------------- +
| مساحة حرة |
العلوي + ----------------------------------- +
| إصدارات الصف |
خاص + ----------------------------------- +
| منطقة خاصة |
pageize + ----------------------------------- +
يسهل اكتشاف حجم هذه الأقسام من خلال ملحق البحث "pageinspect":
=> CREATE EXTENSION pageinspect; => SELECT lower, upper, special, pagesize FROM page_header(get_raw_page('accounts',0));
lower | upper | special | pagesize -------+-------+---------+---------- 40 | 8016 | 8192 | 8192 (1 row)
هنا ننظر إلى
عنوان الصفحة الأولى (صفر) من الجدول. بالإضافة إلى حجم المناطق المتبقية ، يحتوي الرأس على معلومات أخرى حول الصفحة ، لكنها لا تهمنا حتى الآن.
يوجد أسفل الصفحة
منطقة خاصة ، في حالتنا ، فارغة. يتم استخدامه فقط للفهارس ، ثم ليس للجميع. "القاع" هنا يتوافق مع الصورة ؛ ربما سيكون من الأصح قول "في العناوين العليا".
بعد المنطقة الخاصة توجد
إصدارات الصف - البيانات ذاتها التي نخزنها في الجدول ، بالإضافة إلى بعض المعلومات العامة.
في أعلى الصفحة ، مباشرة بعد العنوان ، يوجد جدول المحتويات:
مجموعة من المؤشرات لإصدار الأسطر المتوفرة في الصفحة.
بين إصدارات الخطوط والمؤشرات قد تكون هناك
مساحة حرة (والتي تم وضع علامة عليها في خريطة المساحة الحرة). لاحظ أنه لا يوجد تجزئة داخل الصفحة ، حيث يتم تمثيل كل المساحة الحرة دائمًا بجزء واحد.
مؤشرات
لماذا تعد مؤشرات سلسلة الإصدارات ضرورية؟ الحقيقة هي أن صفوف الفهرس يجب أن تشير بطريقة ما إلى إصدار الصفوف في الجدول. من الواضح أن الرابط يجب أن يحتوي على رقم الملف ورقم الصفحة في الملف وبعض المؤشرات على إصدار السطر. يمكن استخدام إزاحة من بداية الصفحة كإشارة ، لكن هذا غير مريح. لن نتمكن من نقل إصدار السطر داخل الصفحة لأنه سيؤدي إلى قطع الروابط الحالية. وهذا من شأنه أن يؤدي إلى تجزئة المساحة داخل الصفحات وغيرها من العواقب غير السارة. لذلك ، يشير الفهرس إلى رقم الفهرس ، ويشير المؤشر إلى الموضع الحالي لإصدار الصف في الصفحة. اتضح عنونة غير مباشرة.
يشغل كل مؤشر 4 بايت بالضبط ويحتوي على:
- تصل إلى إصدار السلسلة ؛
- طول هذا الإصدار من السلسلة ؛
- العديد من وحدات البت التي تحدد حالة إصدار السلسلة.
تنسيق البيانات
يتزامن تنسيق البيانات على القرص تمامًا مع تمثيل البيانات في ذاكرة الوصول العشوائي. تتم قراءة الصفحة في ذاكرة التخزين المؤقت "كما هي" ، دون أي تحويلات. لذلك ، ملفات البيانات من نظام أساسي واحد غير متوافقة مع الأنظمة الأساسية الأخرى.
على سبيل المثال ، في x86 architecture ، يتم اعتماد ترتيب البايت من الأقل أهمية إلى الأعلى (end-little-endian) ، z / Architecture يستخدم الترتيب العكسي (end-bigian) ، وفي ARM ترتيب التبديل.
توفر العديد من البنى محاذاة البيانات عبر حدود الكلمات الجهاز. على سبيل المثال ، على نظام x86 32 بت ، سيتم محاذاة أعداد صحيحة (نوع عدد صحيح ، تشغل 4 بايت) على حدود الكلمات ذات 4 بايت ، وكذلك أرقام الفاصلة العائمة المزدوجة الدقة (نوع الدقة المزدوجة ، 8 بايت). وعلى نظام 64 بت ، ستتم محاذاة القيم المزدوجة على حدود الكلمات ذات 8 بايت. هذا سبب آخر لعدم التوافق.
بسبب المحاذاة ، يعتمد حجم صف الجدول على ترتيب الحقول. عادة لا يكون هذا التأثير ملحوظًا للغاية ، ولكن في بعض الحالات قد يؤدي إلى زيادة كبيرة في الحجم. على سبيل المثال ، إذا قمت بوضع الحرف (1) وحقول الأعداد الصحيحة مختلطة ، فعادةً ما يتم إهدار 3 بايت بينهما. يمكنك معرفة المزيد حول هذا الموضوع في عرض نيكولاي شابلوف "
What Inside It ".
سلسلة التوست والإصدارات
حول كيفية ترتيب إصدارات السلاسل من الداخل ، سنتحدث بالتفصيل في المرة القادمة. حتى الآن ، الشيء الوحيد المهم بالنسبة لنا هو أن كل إصدار يجب أن يتلاءم تمامًا مع صفحة واحدة: PostgreSQL لا يوفر طريقة "لمواصلة" السطر في الصفحة التالية. بدلاً من ذلك ، يتم استخدام تقنية تسمى TOAST (تقنية تخزين السمات كبيرة الحجم). يشير الاسم نفسه إلى أن السلسلة يمكن قصها في الخبز المحمص.
على محمل الجد ، TOAST ينطوي على العديد من الاستراتيجيات. يمكن إرسال قيم السمات "الطويلة" إلى جدول خدمة منفصل ، مقطوع مسبقًا إلى قطع صغيرة من الخبز المحمص. هناك خيار آخر وهو ضغط القيمة بحيث لا يزال إصدار الصف مناسبًا في صفحة جدول عادية. ومن الممكن أن كلاهما والآخر: في البداية للضغط ، وعندها فقط لخفض وإرسال.
لكل جدول رئيسي ، إذا لزم الأمر ، يتم إنشاء جدول منفصل ، ولكن لكل السمات ، يتم إنشاء جدول TOAST (وفهرس خاص له). يتم تحديد الضرورة من خلال وجود سمات طويلة محتملة في الجدول. على سبيل المثال ، إذا كان الجدول يحتوي على عمود من النوع الرقمي أو النص ، فسيتم إنشاء جدول TOAST على الفور ، حتى إذا لم يتم استخدام القيم الطويلة.
نظرًا لأن جدول TOAST عبارة عن جدول منتظم ، فإنه لا يزال يحتوي على نفس مجموعة الطبقات. وهذا يضاعف عدد الملفات التي "تخدم" الجدول.
في البداية ، يتم تحديد الاستراتيجيات حسب أنواع بيانات الأعمدة. يمكنك مشاهدتها باستخدام الأمر
\d+
في psql ، ولكن نظرًا لأنه يعرض أيضًا الكثير من المعلومات الأخرى ، فسنستخدم الطلب في دليل النظام:
=> SELECT attname, atttypid::regtype, CASE attstorage WHEN 'p' THEN 'plain' WHEN 'e' THEN 'external' WHEN 'm' THEN 'main' WHEN 'x' THEN 'extended' END AS storage FROM pg_attribute WHERE attrelid = 'accounts'::regclass AND attnum > 0;
attname | atttypid | storage ---------+----------+---------- id | integer | plain number | text | extended client | text | extended amount | numeric | main (4 rows)
أسماء الاستراتيجيات لها المعاني التالية:
- عادي - لا يستخدم TOAST (يستخدم لأنواع البيانات "القصيرة" بوضوح ، مثل عدد صحيح) ؛
- ممتد - كل من الضغط والتخزين في جدول TOAST منفصل مسموح به ؛
- يتم تخزين القيم الخارجية الطويلة في جدول TOAST غير مضغوط ؛
- الرئيسية - يتم ضغط القيم الطويلة أولاً وفقط في جدول TOAST إذا لم يساعد الضغط.
بعبارات عامة ، الخوارزمية هي كما يلي. يريد PostgreSQL احتواء 4 أسطر على الأقل على الصفحة. لذلك ، إذا تجاوز حجم الخط الجزء الرابع من الصفحة ، مع الأخذ في الاعتبار العنوان (مع صفحة 8 كيلو بايت العادية 2040 بايت) ، يجب تطبيق TOAST على جزء من القيم. نحن نتصرف بالترتيب الموضح أدناه ونتوقف بمجرد توقف السطر عن العتبة:
- أولاً ، نقوم بالفرز بين السمات ذات الاستراتيجيات الخارجية والممتدة ، وننتقل من الأطول إلى الأقصر. يتم ضغط السمات الموسعة (إذا كان هذا له تأثير) ، وإذا تجاوزت القيمة نفسها ربع الصفحة ، يتم إرسالها على الفور إلى جدول TOAST. يتم التعامل مع السمات الخارجية بنفس الطريقة ، ولكنها غير مضغوطة.
- إذا كان إصدار الصف لا يزال غير صالح بعد مرور أول الأمر ، فنحن نرسل السمات المتبقية مع الاستراتيجيات الخارجية والممتدة إلى جدول TOAST.
- إذا لم يساعد ذلك أيضًا ، فحاول ضغط السمات مع الاستراتيجية الرئيسية ، مع تركها في صفحة الجدول.
- وفقط إذا كان الصف لا يزال غير كافٍ ، فسيتم إرسال السمات الرئيسية إلى جدول TOAST.
قد يكون من المفيد في بعض الأحيان تغيير الإستراتيجية لبعض الأعمدة. على سبيل المثال ، إذا كان من المعروف مسبقًا أن البيانات الموجودة في العمود غير مضغوطة ، يمكنك تعيين استراتيجية خارجية لها - سيوفر ذلك على محاولات الضغط غير المجدية. ويتم ذلك على النحو التالي:
=> ALTER TABLE accounts ALTER COLUMN number SET STORAGE external;
تكرار الطلب ، نحصل على:
attname | atttypid | storage ---------+----------+---------- id | integer | plain number | text | external client | text | extended amount | numeric | main
توجد جداول وفهارس TOAST في مخطط pg_toast منفصل وبالتالي لا تكون مرئية عادةً. بالنسبة للجداول المؤقتة ، يتم استخدام مخطط pg_toast_temp_
N ، على غرار مخطط pg_temp_
N. المعتاد
بالطبع ، إذا رغبت في ذلك ، لا أحد يزعج أن ينظر إلى الميكانيكا الداخلية للعملية. لنفترض أن هناك ثلاث سمات طويلة في جدول الحسابات ، لذلك يجب أن يكون جدول TOAST. ومن هنا:
=> SELECT relnamespace::regnamespace, relname FROM pg_class WHERE oid = ( SELECT reltoastrelid FROM pg_class WHERE relname = 'accounts' );
relnamespace | relname --------------+---------------- pg_toast | pg_toast_33953 (1 row)
=> \d+ pg_toast.pg_toast_33953
TOAST table "pg_toast.pg_toast_33953" Column | Type | Storage ------------+---------+--------- chunk_id | oid | plain chunk_seq | integer | plain chunk_data | bytea | plain
ومن المنطقي أنه بالنسبة لـ "الخبز المحمص" الذي يتم فيه تقطيع الخط إلى شرائح ، يتم تطبيق الإستراتيجية البسيطة: TOAST من المستوى الثاني غير موجود.
يخفي مؤشر PostgreSQL بعناية أكبر ، ولكن من السهل أيضًا العثور على:
=> SELECT indexrelid::regclass FROM pg_index WHERE indrelid = ( SELECT oid FROM pg_class WHERE relname = 'pg_toast_33953' );
indexrelid ------------------------------- pg_toast.pg_toast_33953_index (1 row)
=> \d pg_toast.pg_toast_33953_index
Unlogged index "pg_toast.pg_toast_33953_index" Column | Type | Key? | Definition -----------+---------+------+------------ chunk_id | oid | yes | chunk_id chunk_seq | integer | yes | chunk_seq primary key, btree, for table "pg_toast.pg_toast_33953"
يستخدم عمود العميل الإستراتيجية الموسعة: سيتم ضغط القيم الموجودة به. تحقق:
=> UPDATE accounts SET client = repeat('A',3000) WHERE id = 1; => SELECT * FROM pg_toast.pg_toast_33953;
chunk_id | chunk_seq | chunk_data ----------+-----------+------------ (0 rows)
لا يوجد شيء في جدول TOAST: يتم ضغط الأحرف المكررة تمامًا وبعد ذلك يتم احتواء القيمة في صفحة جدول عادية.
اسمح الآن أن يتكون اسم العميل من أحرف عشوائية:
=> UPDATE accounts SET client = ( SELECT string_agg( chr(trunc(65+random()*26)::integer), '') FROM generate_series(1,3000) ) WHERE id = 1 RETURNING left(client,10) || '...' || right(client,10);
?column? ------------------------- TCKGKZZSLI...RHQIOLWRRX (1 row)
لا يمكن ضغط هذا التسلسل ، ويقع في جدول TOAST:
=> SELECT chunk_id, chunk_seq, length(chunk_data), left(encode(chunk_data,'escape')::text, 10) || '...' || right(encode(chunk_data,'escape')::text, 10) FROM pg_toast.pg_toast_33953;
chunk_id | chunk_seq | length | ?column? ----------+-----------+--------+------------------------- 34000 | 0 | 2000 | TCKGKZZSLI...ZIPFLOXDIW 34000 | 1 | 1000 | DDXNNBQQYH...RHQIOLWRRX (2 rows)
كما ترون ، يتم قطع البيانات إلى أجزاء من 2000 بايت.
عند الوصول إلى قيمة "طويلة" ، يقوم PostgreSQL تلقائيًا وشفافًا بالتطبيق ، باستعادة القيمة الأصلية وإعادتها إلى العميل.
بالطبع ، يتم إنفاق الكثير من الموارد على ضغط شرائح والاسترداد اللاحقة. لذلك ، فإن تخزين البيانات الضخمة في PostgreSQL ليس فكرة جيدة ، خاصة إذا تم استخدامها بنشاط ولم يكن منطق المعاملات مطلوبًا لها (على سبيل المثال: المستندات الأصلية الممسوحة ضوئيًا للمستندات المحاسبية). قد يكون البديل الأكثر ربحية هو تخزين هذه البيانات على نظام الملفات ، وفي قواعد البيانات ، أسماء الملفات المقابلة.
يتم استخدام جدول TOAST فقط عند الإشارة إلى قيمة "طويلة". بالإضافة إلى ذلك ، يحتوي جدول التوست على إصدار خاص به: إذا لم يؤثر تحديث البيانات على القيمة "الطويلة" ، فسيشير الإصدار الجديد من الصف إلى نفس القيمة في جدول TOAST - وهذا يوفر المساحة.
لاحظ أن TOAST يعمل فقط للجداول ، ولكن ليس للفهارس. هذا يفرض حدًا على حجم المفاتيح المفهرسة.
يمكنك قراءة المزيد حول تنظيم البيانات الداخلية في الوثائق .
أن تستمر .