Orijinal SQL
Değiştirilmiş SQL

SQL Diff: İki SQL Dosyasını Çevrimiçi Karşılaştırın

İki SQL sorgusunu veya şema dosyasını yapıştırın, biçimlendirin ve yan yana karşılaştırın. PostgreSQL, MySQL, SQL Server, SQLite ve Oracle ile çalışır.

SQL diff aracı nedir?

İki SQL dosyasını karşılaştırmak için tarayıcı içinde çalışan ücretsiz bir araç. Eski bir CREATE TABLE'ı sola, yenisini sağa yapıştırın; değişiklikler karakter karakter aydınlanır. Aynı akış, bir analiz sorgusunun iki sürümü, ORM'in ürettiği bir ifade veya bir pg_dump çıktısı için de geçerlidir. Hiçbir şey makinenizden çıkmaz.

Diff metin düzeyindedir. SQL'i AST'ye ayrıştırmaz ve anlamsal eşdeğerliği anlamaz: SELECT a, b ve SELECT b, a, ikisi de aynı satırları farklı sırada döndürse bile diff için farklı görünür. Kod inceleme görevlerinin %95'inde (şema göçleri, sorgu yeniden düzenlemeleri, ORM çıktısı karşılaştırması) gerçekten istediğiniz şey metin diff'idir, çünkü sütun ve cümle sırası ekibin değişikliği nasıl okuduğunun bir parçasıdır.

Daha önce farklı bir satır sayısı dönmeye başlayan 400 satırlık bir analiz sorgusunda tek bir yeni WHERE cümlesini bulmaya çalıştıysanız, sizi oraya saniyeler içinde götüren araç budur. SQL olmayan metin için metin diff aracımız doğru seçimdir. JSON'daki ORM sonuç payload'ları için, JSON diff nesnelerin yeniden sıralanmasını daha temiz işler. XML meta verisi olarak yazılmış eski DDL dışa aktarmaları için, XML diff daha uygun olur.

Diff aslında nasıl çalışır

Kapakların altında diff karakter düzeyinde çalışır, ardından bir anlamsal geçiş vurguları kaydırarak bunların rastgele noktalama yerine tanımlayıcılara, anahtar sözcüklere ve cümle sınırlarına oturmasını sağlar. Eklemeler sağda yeşil, silmeler solda kırmızı görünür. Her panelde, SQL'i tutarlı girinti ve satır başına bir ifadeyle yeniden akıtan bir Format düğmesi vardır; bu, karşılaştırmadan önce biçimlendirme gürültüsünün çoğunu yok eder.

SQL tek bir dil değil, lehçeler ailesidir. ISO/IEC 9075 standardı bir çekirdek dilbilgisi tanımlar, ancak her veritabanı bunu genişletir: PostgreSQL'de dolar tırnaklı stringler ve RETURNING vardır, MySQL'de backtick tanımlayıcılar ve ON DUPLICATE KEY UPDATE vardır, SQL Server TOP ve köşeli parantezli tanımlayıcılar kullanır, SQLite neredeyse her şeye katlanır ve Oracle'da ROWNUM ve CONNECT BY bulunur. Lehçeler arası diff sorun değildir; araç bir parçanın bunlardan birinde geçersiz olduğunu uyarmaz.

Bilinmesi gereken diğer şey: bir sorgunun metnini karşılaştırmak, sorgu planlarını karşılaştırmakla aynı şey değildir. Metni aynı olan iki ifade, farklı istatistiklerle çok farklı planlar üretebilir ve kozmetik olarak farklı iki ifade aynı planı üretebilir. Plan karşılaştırması için doğru araçlar psql'deki EXPLAIN ANALYZE veya veritabanı istemcinizdeki (DataGrip, DBeaver, SSMS) eşdeğeridir. Metin yeniden düzenleme incelemesi için diff istediğiniz şeydir. Dilin kendisine ilişkin arka plan okuması Wikipedia'da.

Üç adımda SQL nasıl karşılaştırılır

İki metin paneli, tek diff. Kayıt yok, yükleme yok, sunucu gidiş-dönüşü yok.

  1. 1

    SQL'inizi yapıştırın veya yükleyin

    Eski SQL'i sola, yeni SQL'i sağa yapıştırın. Veya bir .sql, .ddl veya .psql dosyasını doğrudan yüklemek için her iki tarafta da Yükle'ye tıklayın. Sample düğmesi, aracı önce çalışırken görmek isterseniz her iki paneli de küçük bir orders şema örneğiyle doldurur.

  2. 2

    Adil bir karşılaştırma için her iki tarafı da biçimlendirin

    SQL'i tutarlı girinti, satır başına bir ifade ve büyük harf anahtar sözcüklerle yeniden akıtmak için her panelde Format'a tıklayın. Bu, bir tarafta DataGrip ile biçimlendirilmiş bir sorgu, diğer tarafta elle yazılmış bir sorgu olduğunda gürültüyü yok eder; böylece diff boşluk ve büyük/küçük harf farkları yerine gerçek şema ve cümle değişikliklerini vurgular.

  3. 3

    Diff'i okuyun

    Silmeler solda kırmızı vurgulamayla, eklemeler sağda yeşil vurgulamayla görünür. Bir tarafı kaydırın, diğeri takip eder. Her başlıktaki değişiklik sayaçları, diff'in sütunlar, JOIN'ler, predikatlar ve DDL öğeleri arasında kaç farklı düzenleme bulduğunu söyler.

SQL diff doğru araç olduğunda

Şema göçünü uygulamadan önce inceleme

Bir göç PR'si üç sütun ekler ve iki indeksi düzenler. Önceki CREATE TABLE'ı yenisine karşı yapıştırın; eklemeler göze çarpar: currency CHAR(3) NOT NULL sütunu DEFAULT olmadan eklendi, bu mevcut herhangi bir satırda başarısız olacak. Bunu, göç prod'a karşı çalışmadan önce yakalamak, sabah 2'de deploy alarmı çaldıktan sonra değil, bu akışın tüm anlamıdır. Bir sütun türünün VARCHAR(255)'ten VARCHAR(50)'ye daraldığı ALTER TABLE ifadeleri için de aynı değer.

Bir analiz sorgusunun iki sürümünün diff'i

Dün 12.400 satır döndüren bir raporlama sorgusu bugün 8.900 döndürüyor. Dün kaydedilen sorguyu bugünküyle diff'leyin; suçlu değişiklik yüzeye çıkar: bir LEFT JOIN sessizce INNER JOIN'a dönüşmüş veya panoyu temizlemeye çalışan biri tarafından bir WHERE status <> 'cancelled' eklenmiş olabilir. Metin diff'i sizi saniyeler içinde satıra götürür; iki sorguyu Slack'te yan yana okumak ise on dakika sürerdi.

Uygulama sürümleri arasında ORM tarafından üretilen SQL'i karşılaştırma

Bir Hibernate veya SQLAlchemy yükseltmesinden sonra, üç JOIN'lik sorgular ekstra alt sorgularla dört JOIN'e dönüşür ya da parametre bağlama ?'den $1 yer tutuculara geçer. Her uygulama sürümünden sorgu logundan SQL'i yakalayın (psql log_statement = all, MySQL slow log veya APM aracınız) ve diff'leyin. Takma ad isimleri gürültülü olacak (t1, t2, generatedAlias0), ama gerçek yapısal değişiklik genellikle diff'in gerçek bir düzenleme olarak vurguladığı tek şeydir.

Bir DDL yeniden düzenlemesinin niyeti koruduğunu doğrulama

user_ordersorders'a yeniden adlandırdınız ve bir JSON blob sütununu normalize edilmiş tablolara böldünüz. Yeniden düzenlemeden önce ve sonra pg_dump --schema-only çıktısını yapıştırın; diff her kısıtlamayı, indeksi ve varsayılanı koruyup korumadığınızı bariz hale getirir. Dikkat edilmesi gereken tuzak, yeniden adlandırma sırasında sessizce kaybolan bir NOT NULL veya kimsenin yeni tabloya geri eklemediği için düşen bir UNIQUE kısıtlamasıdır.

Staging şemasının prod ile eşleştiğini kontrol etme

Staging ve prod'a karşı pg_dump --schema-only --no-owner çalıştırın, ardından ikisini diff'leyin. Farklar tam olarak bir sonraki deploy için kuyrukta bekleyen göçler olmalıdır. Başka herhangi bir şey, fazladan bir indeks, farklı bir sütun türü, başıboş bir test tablosu, gerçek deploy sırasında ısıracak bir şema kayması işaretidir. MySQL için mysqldump --no-data ve SQL Server için SCRIPT TO ile aynı yaklaşım, ya da herhangi bir veritabanında DataGrip'in şema dışa aktarımı.

Lehçe taşımayı inceleme (Postgres'ten MySQL'e)

Bir sorguyu PostgreSQL'den MySQL'e veya tersine taşımak, hangi fonksiyonların, türlerin ve cümlelerin değişmesi gerektiğini izlemek demektir: SERIAL'a karşı AUTO_INCREMENT, NOW()'a karşı CURRENT_TIMESTAMP, RETURNING'e karşı LAST_INSERT_ID(). Orijinali taşınan sürümle diff'leyin; tüm lehçe ikameleri yüzeye çıkar. Diff, hedef lehçede SQL'i doğrulamaz, bu yüzden onaylamak için yine de psql veya mysql'den geçirin, ancak satır satır görünüm hangi kararları çift kontrol etmeniz gerektiğini söyler.

SQL hızlı referans

Bu diff'in en sık yüzeye çıkardığı lehçe ve ayrıştırma sınır durumları için kısa bir kopya kağıdı. ISO SQL standardına ve büyük üretici belgelerine dayanır.

TopicWhat this tool does
Lehçe kaymasıPostgreSQL, MySQL, SQL Server, SQLite ve Oracle'ın her biri ISO SQL standardını kendi sözdizimleriyle genişletir. SERIAL, AUTO_INCREMENT, IDENTITY ve GENERATED ALWAYS AS IDENTITY aynı fikrin dört yazım biçimidir.
Tanımlayıcı büyük/küçük harf katlamaPostgreSQL tırnaksız tanımlayıcıları küçük harfe katlar, dolayısıyla Users ve users aynı tablodur. MySQL lower_case_table_names ve alttaki dosya sistemine bağlıdır. SQL Server varsayılan olarak büyük/küçük harf duyarsızdır ancak collation'a saygı duyar. Büyük/küçük harfi korumak için tanımlayıcıları "Users" (standart), backtick (MySQL) veya köşeli parantez (SQL Server) ile tırnaklayın.
Anahtar sözcük büyük/küçük harfiSQL anahtar sözcükleri her yerde büyük/küçük harf duyarsızdır, bu nedenle SELECT ve select ayrıştırıcı için aynıdır. Uzlaşı anahtar sözcükler için büyük harf, tanımlayıcılar için küçük harftir; çoğu stil kılavuzu ve ISO spec'i bunu izler. Karışık büyük/küçük harf geçerlidir ve çalışır, ancak sqlfluff ve sqlfmt gibi araçlar bunu normalleştirir.
Yorum stilleriİki biçim: -- satır yorumu (satır sonunda biter) ve /* blok yorumu */ (standart SQL'de iç içe geçiremez, bazı lehçeler izin verse de). MySQL ayrıca uzantı olarak #'i satır yorumları için destekler. Diff yorumları metin olarak ele alır ve yorum düzenlemelerini diğer değişiklikler gibi gösterir.
İfade ayırıcılarNoktalı virgül (;) standart SQL'de bir ifadeyi sonlandırır. Çoğu istemci bir betikteki ifadeler arasında bunu gerektirir. Bazı istemciler (SSMS) bunun yerine GO'yu toplu ayırıcı olarak kullanır; bu SQL dilbilgisinin parçası değildir; bir istemci yönergesidir.
Dolar tırnaklı stringler (PostgreSQL)PostgreSQL string sabitleri için $tag$ ... $tag$'i destekler, böylece içindeki tek tırnakları kaçırmanıza gerek kalmaz, özellikle fonksiyon gövdeleri için kullanışlıdır. $$ SELECT 'hello' $$ geçerlidir ve CREATE FUNCTION bloklarında yaygındır. Diğer lehçeler bu sözdizimini ayrıştırmaz.
Parametre bağlama yer tutucularıStandart yok. PostgreSQL ve onu hedefleyen ORM'ler $1, $2 kullanır. JDBC, MySQL ve ODBC ? kullanır. Adlandırılmış yer tutucular :name Oracle'da ve birçok ORM string şablonunda yaygındır. ORM tarafından üretilen SQL sürümler arasında genellikle yalnızca yer tutucu stilinde farklılaşır; diff'ten önce her iki tarafı da biçimlendirin.
Kodlama2026'da SQL dosyaları için evrensel varsayılan UTF-8'dir. Windows kökenli eski betikler hâlâ BOM'lu UTF-16 LE olarak kaydedilmiş olabilir; bu, metin diff'inin 1. satırında hayalet bir karakter olarak görünür. İki dosya aynı görünüyor ama diff başta tek karakterlik bir değişikliği işaretliyorsa, BOM'dan şüphelenin ve açık UTF-8 ile yeniden kaydedin.

SQL diff: sıkça sorulan sorular

Bunun her iki sorguda EXPLAIN ANALYZE çalıştırmaktan farkı nedir?

Yığının farklı bir katmanı. EXPLAIN ANALYZE size sorgunun planını, optimizatörün elindeki istatistikler ışığında ne yapmaya karar verdiğini gösterir. Bu araç sorgunun metnini diff'ler, yani repo'nuzda değişen şeyi. Genellikle her ikisini de istersiniz: yeniden düzenlemeyi tespit etmek için bu diff'i (bir JOIN türü değişti, bir predikat hareket etti), sonra optimizatörün yeni şekil için gerçekten makul bir plan seçtiğini doğrulamak için psql veya istemcinizdeki EXPLAIN ANALYZE'ı. İkisi tamamlayıcıdır, birbirinin yerine geçmez.

Diff, lehçenin farkında mıdır (PostgreSQL vs MySQL vs SQL Server)?

Hayır. Diff girdiyi metin olarak ele alır, dolayısıyla PostgreSQL, MySQL, SQL Server, SQLite veya Oracle'ı farklı şekilde ayrıştırmaz ve lehçeler arası uyumsuz sözdizimini işaretlemez. Bu kasıtlıdır: lehçeler arası diff yapabileceğiniz anlamına gelir, ki bir sorguyu taşırken tam olarak istediğiniz şey budur. Lehçe farkındalıklı linting'e ihtiyacınız varsa, SQL'i ayrı olarak sqlfluff'tan veya veritabanınızın ayrıştırıcısından geçirin. İnceleme kullanım durumu için ("bu sorguda ne değişti"), metin düzeyi doğru ayrıntı düzeyidir.

Araç benim için SQL'i biçimlendirir mi?

Evet, her paneldeki Format düğmesi SQL'i tutarlı girinti, büyük harf anahtar sözcükler ve satır başına bir ifade ile yeniden biçimlendirir. Temel bir biçimlendiricidir, sqlfmt veya sqlfluff yerine geçmez: örtük JOIN'leri açık olanlara dönüştürmez ve belirli bir lehçenin stil kılavuzunu zorlamaz. Amaç, diff'ten önce biçimlendirme gürültüsünü yok etmektir; böylece bir tarafta DataGrip ile biçimlendirilmiş bir sorgu, diğer tarafta elle yazılmış bir sorgu temiz şekilde karşılaştırılır.

Anahtar sözcük büyük/küçük harfini (SELECT vs select) normalleştirir mi?

Format düğmesi anahtar sözcükleri büyük harfe çevirir; bu çoğu stil kılavuzunda ve ISO SQL standardında uzlaşıdır. Format'a tıklamazsanız karışık büyük/küçük harf bir diff olarak görünür çünkü altta yatan motor karakter tabanlıdır. SQL anahtar sözcükleri her veritabanında büyük/küçük harf duyarsızdır, bu nedenle select ve SELECT aynı şekilde çalışır. Tanımlayıcı büyük/küçük harfi farklı bir konudur ve veritabanına göre değişir; Postgres, MySQL ve SQL Server'ın nasıl farklılaştığı için aşağıdaki hızlı referansa bakın.

ORM'in ürettiği t1, t2, generatedAlias0 gibi takma adlarla nasıl başa çıkarım?

ORM çıktısı tasarım gereği gürültülüdür: Hibernate generatedAlias0, generatedAlias1 üretir, SQLAlchemy ise anon_1, anon_2 kullanır. İki ORM sürümü aynı takma adları farklı sırada atarsa, sorgu yapısal olarak aynı olsa bile metin diff'i her takma ad değişikliğini değişiklik olarak vurgular. Pratik çözüm her iki tarafı da biçimlendirmek, yalnızca takma ad farklılıklarını yok saymak (genellikle aynı satırda eşleşmiş kırmızı ve yeşil bloklar olarak bariz) ve gerçek yapısal düzenlemelere odaklanmaktır: yeni bir JOIN, farklı bir WHERE cümlesi, kaldırılmış bir sütun.

Yapıştırdığım SQL'de boyut sınırı var mı?

Yumuşak sınırlar var, sert değil. Diff tarayıcınızda çalışır, dolayısıyla üst sınır tarayıcınızın belleği ve ne kadar beklemeye razı olduğunuzdur. 5.000 satırlık bir pg_dump çıktısı modern bir dizüstünde bir saniyenin oldukça altında diff'lenir. 200.000 satırlık bir döküm birkaç saniye sürebilir ve düşük donanımlı cihazlarda bellek sınırlarına yaklaşabilir. Bu kadar büyük veritabanı dökümleri için doğru akış, önce yalnızca şemayı diff'lemek (pg_dump --schema-only), ardından veri düzeyinde karşılaştırma gerekirse belirli tablolara inmektir.

Gizlilik ve nasıl çalıştığı

SQL'iniz tarayıcınızdan asla çıkmaz. Biçimlendirici ve diff her ikisi de makinenizde, yerelde çalışır. Girişiniz üzerinde analitik yok, log yok, "yardımcı" bulut gidiş-dönüşü yok; bu, yapıştırdığınız SQL gerçek tablo adları, gerçek sütun adları veya örnek bir satırda gerçek üretim verisi içerdiğinde önem kazanır. Dil ISO/IEC 9075'te belgelenmiştir ve lehçe referansları PostgreSQL, MySQL, SQL Server ve SQLite'dır.