1. ما هو UPSERT؟
نظرة عامة
“UPSERT” يشير إلى عملية قاعدة بيانات تجمع بين INSERT و UPDATE. بمعنى آخر، إذا لم يكن البيان موجودًا بالفعل، سيتم إدراجه، وإذا كان موجودًا، سيتم تحديثه. تسمح هذه الميزة بعمليات فعالة مع الحفاظ على اتساق البيانات.
في MySQL، يوفر بناء الجملة INSERT ... ON DUPLICATE KEY UPDATE هذه الوظيفة. معها، يمكنك تجنب أخطاء المفاتيح المكررة وتحديث السجلات الموجودة حتى عند حدوث مواقف بيانات مكررة.
حالات الاستخدام
- أنظمة إدارة العملاء : إدراج بيانات عميل جديدة إذا لم تكن موجودة، أو تحديث معلومات العميل الموجودة عند تغييرها.
- إدارة المخزون : إضافة منتجات جديدة مع تحديث عدد المخزون للمنتجات الموجودة.
فوائد UPSERT في MySQL
- تجنب أخطاء المفاتيح المكررة
- تبسيط استعلامات SQL
- الحفاظ على سلامة البيانات
2. الاستخدام الأساسي لـ UPSERT في MySQL
في MySQL، تُنفذ عمليات UPSERT باستخدام بناء الجملة INSERT ... ON DUPLICATE KEY UPDATE. مع هذا، إذا تم العثور على مفتاح مكرر، يتم تحديث السجل الموجود بدلاً من إدراج واحد جديد.
البناء الأساسي
INSERT INTO table_name (column1, column2)
VALUES (value1, value2)
ON DUPLICATE KEY UPDATE
column1 = value1, column2 = value2;
الشرح:
INSERT INTOيحاول إدراج البيان في الجدول.- إذا كان البيان موجودًا بالفعل، ينفذ بند
ON DUPLICATE KEY UPDATEويحدث السجل الموجود.
مثال:
INSERT INTO users (user_id, name)
VALUES (1, 'Taro Tanaka')
ON DUPLICATE KEY UPDATE
name = 'Taro Tanaka';
في هذا المثال، إذا كان هناك مستخدم بـ user_id = 1 موجود بالفعل، سيتم تحديث name الخاص به إلى ‘Taro Tanaka’. وإلا، سيتم إدراج سجل جديد.

3. بناء SQL التفصيلي وأمثلة لـ UPSERT
تحديث أعمدة متعددة
عند استخدام UPSERT، يمكنك اختيار تحديث أعمدة معينة فقط. في مثل هذه الحالات، حدد فقط الأعمدة المستهدفة في بند ON DUPLICATE KEY UPDATE.
INSERT INTO products (product_id, name, price)
VALUES (100, 'Laptop', 50000)
ON DUPLICATE KEY UPDATE
price = VALUES(price);
هنا، إذا كان هناك منتج بـ product_id = 100 موجود بالفعل، سيتم تحديث عمود price فقط، مع ترك الأعمدة الأخرى مثل name دون تغيير.
4. الاختلافات مع قواعد البيانات الأخرى
توفر قواعد البيانات الأخرى أيضًا وظيفة مشابهة لـ UPSERT. على سبيل المثال، يستخدم PostgreSQL و SQLite INSERT ... ON CONFLICT أو MERGE كما يعادلان.
مثال PostgreSQL
INSERT INTO users (user_id, name)
VALUES (1, 'Taro Tanaka')
ON CONFLICT (user_id) DO UPDATE SET
name = 'Taro Tanaka';
في PostgreSQL و SQLite، يُستخدم بند ON CONFLICT للتحكم في السلوك عند حدوث أخطاء مفاتيح مكررة. في المقابل، يستخدم MySQL ON DUPLICATE KEY UPDATE.
تميز MySQL
- يستخدم MySQL
INSERT ... ON DUPLICATE KEY UPDATE، والذي يختلف عن قواعد البيانات الأخرى. يحتاج إلى انتباه خاص أثناء نقل قاعدة البيانات.
5. استخدام UPSERT المتقدم
UPSERT جماعي (سجلات متعددة دفعة واحدة)
يمكن تطبيق UPSERT أيضًا على سجلات متعددة في وقت واحد، مما يحسن الكفاءة بشكل كبير في عمليات قاعدة البيانات.
INSERT INTO products (product_id, name, price)
VALUES
(100, 'Laptop', 50000),
(101, 'Smartphone', 30000)
ON DUPLICATE KEY UPDATE
price = VALUES(price);
هنا، يتم إدراج منتجات متعددة دفعة واحدة، وإذا كان هناك مفتاح مكرر، يتم تحديث price فقط.
استخدام الإجراءات المخزنة لـ UPSERT
يمكنك أيضًا استخدام الإجراءات المخزنة لتبسيط عمليات UPSERT. هذا يجعل الكود قابلاً لإعادة الاستخدام، أكثر قابلية للقراءة، وأسهل في الصيانة.

6. المخاطر والاعتبارات لـ UPSERT
المعاملات والأقفال الميتة
عند استخدام UPSERT مع مجموعات بيانات كبيرة، قد تحدث أقفال ميتة. إذا كان مستوى عزل معاملة MySQL مضبوطًا على REPEATABLE READ، فإن أقفال الفجوات أكثر احتمالية.
تجنب أقفال الفجوات
- تغيير مستوى عزل المعاملات إلى
READ COMMITTEDيمكن أن يقلل من مخاطر التوقف المتبادل. - فكر في تقسيم عمليات UPSERT إلى استعلامات أصغر عند الضرورة.
7. الخاتمة
وظيفة UPSERT في MySQL هي أداة قوية لإدخال وتحديث البيانات بكفاءة مع تجنب أخطاء المفتاح المكرر. ومع ذلك، من الضروري النظر بعناية في إعدادات المعاملات والاحتمالات المحتملة للتوقف المتبادل. عند استخدامها بشكل صحيح، يمكن لـ UPSERT جعل عمليات قاعدة البيانات أبسط وأكثر فعالية.


