تحديث مخطط جدول Delta Lake

يتيح لك Delta Lake تحديث مخطط جدول. يتم دعم الأنواع التالية من التغييرات:

  • إضافة أعمدة جديدة (في مواضع عشوائية)
  • إعادة ترتيب الأعمدة الموجودة
  • إعادة تسمية الأعمدة الموجودة

يمكنك إجراء هذه التغييرات بشكل صريح باستخدام DDL أو ضمنيا باستخدام DML.

هام

تحديث مخطط جدول Delta هو عملية تتعارض مع جميع عمليات كتابة دلتا المتزامنة.

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

تحديث المخطط بشكل صريح لإضافة أعمدة

ALTER TABLE table_name ADD COLUMNS (col_name data_type [COMMENT col_comment] [FIRST|AFTER colA_name], ...)

بشكل افتراضي، قابلية القيم الخالية هي true.

لإضافة عمود إلى حقل متداخل، استخدم:

ALTER TABLE table_name ADD COLUMNS (col_name.nested_col_name data_type [COMMENT col_comment] [FIRST|AFTER colA_name], ...)

على سبيل المثال، إذا كان المخطط قبل التشغيل ALTER TABLE boxes ADD COLUMNS (colB.nested STRING AFTER field1) هو:

- root
| - colA
| - colB
| +-field1
| +-field2

المخطط بعد هو:

- root
| - colA
| - colB
| +-field1
| +-nested
| +-field2

إشعار

إضافة أعمدة متداخلة معتمدة فقط للبنى. الصفائف والخرائط غير معتمدة.

تحديث المخطط بشكل صريح لتغيير تعليق العمود أو ترتيبه

ALTER TABLE table_name ALTER [COLUMN] col_name (COMMENT col_comment | FIRST | AFTER colA_name)

لتغيير عمود في حقل متداخل، استخدم:

ALTER TABLE table_name ALTER [COLUMN] col_name.nested_col_name (COMMENT col_comment | FIRST | AFTER colA_name)

على سبيل المثال، إذا كان المخطط قبل التشغيل ALTER TABLE boxes ALTER COLUMN colB.field2 FIRST هو:

- root
| - colA
| - colB
| +-field1
| +-field2

المخطط بعد هو:

- root
| - colA
| - colB
| +-field2
| +-field1

تحديث المخطط بشكل صريح لاستبدال الأعمدة

ALTER TABLE table_name REPLACE COLUMNS (col_name1 col_type1 [COMMENT col_comment1], ...)

على سبيل المثال، عند تشغيل DDL التالي:

ALTER TABLE boxes REPLACE COLUMNS (colC STRING, colB STRUCT<field2:STRING, nested:STRING, field1:STRING>, colA STRING)

إذا كان المخطط من قبل هو:

- root
| - colA
| - colB
| +-field1
| +-field2

المخطط بعد هو:

- root
| - colC
| - colB
| +-field2
| +-nested
| +-field1
| - colA

تحديث المخطط بشكل صريح لإعادة تسمية الأعمدة

هام

هذه الميزة في المعاينة العامة.

إشعار

تتوفر هذه الميزة في Databricks Runtime 10.4 LTS وما فوق.

لإعادة تسمية الأعمدة دون إعادة كتابة أي من البيانات الموجودة في الأعمدة، يجب تمكين تعيين العمود للجدول. راجع إعادة تسمية الأعمدة وإفلاتها باستخدام تعيين عمود Delta Lake.

لإعادة تسمية عمود:

ALTER TABLE table_name RENAME COLUMN old_col_name TO new_col_name

لإعادة تسمية حقل متداخل:

ALTER TABLE table_name RENAME COLUMN col_name.old_nested_field TO new_nested_field

على سبيل المثال، عند تشغيل الأمر التالي:

ALTER TABLE boxes RENAME COLUMN colB.field1 TO field001

إذا كان المخطط من قبل هو:

- root
| - colA
| - colB
| +-field1
| +-field2

ثم المخطط بعد هو:

- root
| - colA
| - colB
| +-field001
| +-field2

راجع إعادة تسمية الأعمدة وإفلاتها باستخدام تعيين عمود Delta Lake.

تحديث المخطط بشكل صريح لإسقاط الأعمدة

هام

هذه الميزة في المعاينة العامة.

إشعار

تتوفر هذه الميزة في Databricks Runtime 11.3 LTS وما فوق.

لإسقاط الأعمدة كلعملية بيانات تعريف فقط دون إعادة كتابة أي ملفات بيانات، يجب تمكين تعيين العمود للجدول. راجع إعادة تسمية الأعمدة وإفلاتها باستخدام تعيين عمود Delta Lake.

هام

لا يؤدي إسقاط عمود من بيانات التعريف إلى حذف البيانات الأساسية للعمود في الملفات. لإزالة بيانات العمود الذي تم إسقاطه، يمكنك استخدام REORG TABLE لإعادة كتابة الملفات. يمكنك بعد ذلك استخدام فراغ لحذف الملفات التي تحتوي على بيانات العمود التي تم إسقاطها فعليا.

لإسقاط عمود:

ALTER TABLE table_name DROP COLUMN col_name

لإفلات أعمدة متعددة:

ALTER TABLE table_name DROP COLUMNS (col_name_1, col_name_2)

تحديث المخطط بشكل صريح لتغيير نوع العمود أو الاسم

يمكنك تغيير نوع العمود أو اسمه أو إسقاط عمود عن طريق إعادة كتابة الجدول. للقيام بذلك، استخدم overwriteSchema الخيار .

يوضح المثال التالي تغيير نوع عمود:

(spark.read.table(...)
  .withColumn("birthDate", col("birthDate").cast("date"))
  .write
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .saveAsTable(...)
)

يوضح المثال التالي تغيير اسم عمود:

(spark.read.table(...)
  .withColumnRenamed("dateOfBirth", "birthDate")
  .write
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .saveAsTable(...)
)

إضافة أعمدة مع تحديث المخطط التلقائي

تتم إضافة الأعمدة الموجودة في DataFrame ولكنها مفقودة من الجدول تلقائيا كجزء من معاملة الكتابة عندما:

  • write أو writeStream لديك .option("mergeSchema", "true")
  • spark.databricks.delta.schema.autoMerge.enabled هو true

عند تحديد كلا الخيارين، يكون للخيار من DataFrameWriter الأسبقية. يتم إلحاق الأعمدة المضافة بنهاية البنية الموجودة فيها. يتم الاحتفاظ بالحالة عند إلحاق عمود جديد.

إشعار

  • mergeSchema لا يمكن استخدامها مع INSERT INTO أو .write.insertInto().

تطور المخطط التلقائي لدمج Delta Lake

يسمح تطور المخطط للمستخدمين بحل عدم تطابق المخطط بين الجدول الهدف والجدول المصدر في الدمج. وهو يعالج الحالتين التاليتين:

  1. عمود في الجدول المصدر غير موجود في الجدول الهدف. تتم إضافة العمود الجديد إلى المخطط الهدف، ويتم إدراج قيمه أو تحديثها باستخدام قيم المصدر.
  2. عمود في الجدول الهدف غير موجود في الجدول المصدر. لم يطرأ أي تغيير على المخطط الهدف؛ يتم إما ترك القيم في العمود الهدف الإضافي دون تغيير (ل UPDATE) أو تعيينها إلى NULLINSERT).

هام

لاستخدام تطور المخطط، يجب تعيين تكوين spark.databricks.delta.schema.autoMerge.enabled جلسة Spark إلى true قبل تشغيل merge الأمر.

إشعار

  • في Databricks Runtime 12.2 LTS وما فوق، يمكن تحديد الأعمدة الموجودة في الجدول المصدر بالاسم في إجراءات الإدراج أو التحديث. في Databricks Runtime 11.3 LTS والإصدارات أدناه، يمكن استخدام الإجراءات أو UPDATE SET * فقط INSERT * لتطور المخطط مع الدمج.

فيما يلي بعض الأمثلة على تأثيرات merge التشغيل مع تطور المخطط وبدونه.

الأعمدة الاستعلام (في SQL) السلوك دون تطور المخطط (افتراضي) السلوك مع تطور المخطط
الأعمدة الهدف: key, value

أعمدة المصدر: key, value, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN MATCHED
THEN UPDATE SET *
WHEN NOT MATCHED
THEN INSERT *
يظل مخطط الجدول دون تغيير؛ يتم تحديث/إدراج الأعمدة keyvalue فقط. يتم تغيير مخطط الجدول إلى (key, value, new_value). يتم تحديث السجلات الموجودة ذات التطابقات مع value و new_value في المصدر. يتم إدراج صفوف جديدة مع المخطط (key, value, new_value).
الأعمدة الهدف: key, old_value

أعمدة المصدر: key, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN MATCHED
THEN UPDATE SET *
WHEN NOT MATCHED
THEN INSERT *
UPDATE وتطرح INSERT الإجراءات خطأ لأن العمود old_value الهدف ليس في المصدر. يتم تغيير مخطط الجدول إلى (key, old_value, new_value). يتم تحديث السجلات الموجودة ذات التطابقات مع new_value ترك في المصدر old_value دون تغيير. يتم إدراج سجلات جديدة مع keyالمحدد و new_valueو NULL ل old_value.
الأعمدة الهدف: key, old_value

أعمدة المصدر: key, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN MATCHED
THEN UPDATE SET new_value = s.new_value
UPDATE يطرح خطأ لأن العمود new_value غير موجود في الجدول الهدف. يتم تغيير مخطط الجدول إلى (key, old_value, new_value). يتم تحديث السجلات الموجودة ذات التطابقات مع new_value ترك في المصدر old_value دون تغيير، وقد NULL تم إدخال السجلات غير المتطابقة ل new_value. راجع الملاحظة (1).
الأعمدة الهدف: key, old_value

أعمدة المصدر: key, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN NOT MATCHED
THEN INSERT (key, new_value) VALUES (s.key, s.new_value)
INSERT يطرح خطأ لأن العمود new_value غير موجود في الجدول الهدف. يتم تغيير مخطط الجدول إلى (key, old_value, new_value). يتم إدراج سجلات جديدة مع keyالمحدد و new_valueو NULL ل old_value. تم NULL إدخال السجلات الموجودة لتركها old_valuenew_value دون تغيير. راجع الملاحظة (1).

(1) يتوفر هذا السلوك في Databricks Runtime 12.2 LTS وما فوق؛ Databricks Runtime 11.3 LTS وتحت الخطأ في هذا الشرط.

استبعاد الأعمدة باستخدام دمج Delta Lake

في Databricks Runtime 12.2 LTS وما فوق، يمكنك استخدام EXCEPT العبارات في شروط الدمج لاستبعاد الأعمدة بشكل صريح. يختلف سلوك EXCEPT الكلمة الأساسية اعتمادا على ما إذا كان قد تم تمكين تطور المخطط أم لا.

مع تعطيل تطور المخطط، EXCEPT تنطبق الكلمة الأساسية على قائمة الأعمدة في الجدول الهدف وتسمح باستبعاد الأعمدة من UPDATE أو INSERT الإجراءات. يتم تعيين الأعمدة المستبعدة إلى null.

مع تمكين تطور المخطط، EXCEPT تنطبق الكلمة الأساسية على قائمة الأعمدة في الجدول المصدر وتسمح باستبعاد الأعمدة من تطور المخطط. لا تتم إضافة عمود جديد في المصدر غير موجود في الهدف إلى المخطط الهدف إذا كان مدرجا في العبارة EXCEPT . يتم تعيين الأعمدة المستبعدة الموجودة بالفعل في الهدف إلى null.

توضح الأمثلة التالية بناء الجملة هذا:

الأعمدة الاستعلام (في SQL) السلوك دون تطور المخطط (افتراضي) السلوك مع تطور المخطط
الأعمدة الهدف: id, title, last_updated

أعمدة المصدر: id, title, review, last_updated
MERGE INTO target t
USING source s
ON t.id = s.id
WHEN MATCHED
THEN UPDATE SET last_updated = current_date()
WHEN NOT MATCHED
THEN INSERT * EXCEPT (last_updated)
يتم تحديث الصفوف المتطابقة عن طريق تعيين last_updated الحقل إلى التاريخ الحالي. يتم إدراج صفوف جديدة باستخدام قيم و idtitle. يتم تعيين الحقل last_updated المستبعد إلى null. يتم تجاهل الحقل review لأنه ليس في الهدف. يتم تحديث الصفوف المتطابقة عن طريق تعيين last_updated الحقل إلى التاريخ الحالي. تم تطوير المخطط لإضافة الحقل review. يتم إدراج صفوف جديدة باستخدام كافة الحقول المصدر باستثناء last_updated التي تم تعيينها إلى null.
الأعمدة الهدف: id, title, last_updated

أعمدة المصدر: id, title, review, internal_count
MERGE INTO target t
USING source s
ON t.id = s.id
WHEN MATCHED
THEN UPDATE SET last_updated = current_date()
WHEN NOT MATCHED
THEN INSERT * EXCEPT (last_updated, internal_count)
INSERT يطرح خطأ لأن العمود internal_count غير موجود في الجدول الهدف. يتم تحديث الصفوف المتطابقة عن طريق تعيين last_updated الحقل إلى التاريخ الحالي. review تتم إضافة الحقل إلى الجدول الهدف، ولكن internal_count يتم تجاهل الحقل. تم last_updated تعيين الصفوف الجديدة المدرجة إلى null.

تطور المخطط التلقائي لصفائف البنيات

تدعم Delta MERGE INTO حل حقول البنية حسب الاسم والمخططات المتطورة لصفائف البنيات. مع تمكين تطور المخطط، ستتطور مخططات الجدول الهدف لصفائف البنيات، والتي تعمل أيضا مع أي بنيات متداخلة داخل الصفائف.

إشعار

في Databricks Runtime 12.2 LTS وما فوق، يمكن تحديد حقول البنية الموجودة في الجدول المصدر بالاسم في أوامر الإدراج أو التحديث. في Databricks Runtime 11.3 LTS والإصدارات أدناه، يمكن استخدام الأوامر أو UPDATE SET * فقط INSERT * لتطور المخطط مع الدمج.

فيما يلي بعض الأمثلة على تأثيرات عمليات الدمج مع تطور المخطط وبدونه لصفائف البنيات.

مخطط المصدر مخطط الهدف السلوك دون تطور المخطط (افتراضي) السلوك مع تطور المخطط
بنية<الصفيف<b: سلسلة، أ: سلسلة>> بنية<الصفيف<a: int، b: int>> يظل مخطط الجدول دون تغيير. سيتم حل الأعمدة بالاسم وتحديثها أو إدراجها. يظل مخطط الجدول دون تغيير. سيتم حل الأعمدة بالاسم وتحديثها أو إدراجها.
بنية<الصفيف<a: int, c: string, d: string>> بنية<الصفيف<أ: سلسلة، ب: سلسلة>> update وطرح insert الأخطاء لأن c و d غير موجودين في الجدول الهدف. يتم تغيير مخطط الجدول إلى بنية الصفيف<أ: سلسلة، ب: سلسلة، ج: سلسلة، د: سلسلة>>.< c ويتم إدراج و d كما NULL للإدخالات الموجودة في الجدول الهدف. update واملأ insert الإدخالات في الجدول المصدر مع a تحويلها إلى سلسلة و b ك NULL.
بنية<الصفيف<أ: سلسلة، ب: بنية<ج: سلسلة، د: سلسلة>>> بنية<الصفيف<أ: سلسلة، ب: بنية<ج: سلسلة>>> update وطرح insert الأخطاء لأنه d غير موجود في الجدول الهدف. يتم تغيير مخطط الجدول الهدف إلى بنية الصفيف<أ: سلسلة، ب: بنية<ج: سلسلة، د: سلسلة>>>.< d يتم إدراج كإدخالات NULL موجودة في الجدول الهدف.

التعامل مع NullType الأعمدة في تحديثات المخطط

نظرا لأن Parquet لا يدعم NullType، NullType يتم إسقاط الأعمدة من DataFrame عند الكتابة في جداول Delta، ولكن لا تزال مخزنة في المخطط. عند تلقي نوع بيانات مختلف لهذا العمود، يدمج Delta Lake المخطط بنوع البيانات الجديد. إذا تلقى NullType Delta Lake لعمود موجود، يتم الاحتفاظ بالمخطط القديم ويتم إسقاط العمود الجديد أثناء الكتابة.

NullType في البث غير مدعوم. نظرا لأنه يجب عليك تعيين المخططات عند استخدام دفق هذا يجب أن يكون نادرا جدا. NullType غير مقبول أيضا لأنواع معقدة مثل ArrayType و MapType.

استبدال مخطط الجدول

بشكل افتراضي، لا يؤدي الكتابة فوق البيانات في جدول إلى الكتابة فوق المخطط. عند الكتابة فوق جدول باستخدام mode("overwrite") بدون replaceWhere، قد لا تزال ترغب في الكتابة فوق مخطط البيانات التي تتم كتابتها. يمكنك استبدال مخطط الجدول وتقسيمه عن طريق تعيين overwriteSchema الخيار إلى true:

df.write.option("overwriteSchema", "true")

هام

لا يمكنك تحديد overwriteSchema عند true استخدام الكتابة فوق القسم الديناميكي.