SQL, bir tabloya veri güncellemeye veya eklemeye yönelik çeşitli yollar sağlar:
Ne zaman ve ne kullanılmalı:
INSERT kullanın.UPDATE kullanın.MERGE veya UPSERT kullanmak — bu karmaşıklığı azaltır ve SQL sorgusu sayısını düşürür.Örnek (PostgreSQL):
INSERT INTO employees(id, name, salary) VALUES (1, 'Ivan', 100000) ON CONFLICT (id) DO UPDATE SET salary = EXCLUDED.salary;
Performans ve bütünlük üzerindeki etkisi:
Eşsiz bir alan üzerinde UPSERT gerçekleştirmeye çalışırsanız, ancak aynı işlemde aynı satırı hem eklemeye hem de güncellemeye çalışırsanız ne olur?
Doğru cevap: Bir kilit hatası/çatışma olasılığı vardır, çünkü işlem aynı satırı iki kez değiştirmeye çalışır. İşlem tamamlanmayabilir veya veritabanına bağlı olarak deadlock hatası ile sonuçlanabilir.
Örnek:
BEGIN; INSERT INTO users(id, name) VALUES (1, 'Oleg') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name; UPDATE users SET name = 'Petr' WHERE id = 1; COMMIT;
Yanlış sıralama ve izolasyon düzeyinde değişiklik çatışması olasılığı vardır.
Hikaye №1
Bir veri göç mantığında SELECT kombinasyonunu kullanarak sonra INSERT veya UPDATE yapıldı, bu da bazen başka bir işlemin verileri önce ayarlamasına ve "duplicate key" hatasına neden oluyordu. Bu, gece veri ihracatında sık sık hatalara yol açtı ve mantığı UPSERT ile değiştirmek gerekti.
Hikaye №2
MySQL projesinde ON DUPLICATE KEY UPDATE uygun şekilde uygulanmadı ve bileşik benzersiz anahtarları hesaba katmadı. Sonuç olarak, bazı veriler güncellenmedi ve kopyalar ortaya çıktı. Sorun, yalnızca üretim ortamında tespit edilebildi.
Hikaye №3
Bir projede kullanıcı verilerini senkronize etmek için UPDATE kullanıldı, bağlanma hataları nedeniyle yeni kullanıcılar için güncelleme atlandı ve bazı verilerin kaybına neden oldu. Analizden sonra MERGE/UPSERT'i tamamen entegre ettik.