SQL Diff: porównaj dwa pliki SQL online
Wklej, sformatuj i porównaj dwa zapytania SQL lub pliki schematu obok siebie. Działa dla PostgreSQL, MySQL, SQL Server, SQLite i Oracle.
Czym jest narzędzie SQL diff?
Darmowe narzędzie w przeglądarce do porównywania dwóch plików SQL. Wklej stary CREATE TABLE po lewej, nowy po prawej, a zmiany rozświetlą się znak po znaku. Ten sam przepływ dla dwóch wersji zapytania analitycznego, instrukcji wygenerowanej przez ORM lub wyjścia pg_dump. Nic nie opuszcza Twojej maszyny.
Diff działa na poziomie tekstu. Nie parsuje SQL do AST i nie rozumie równoważności semantycznej: SELECT a, b i SELECT b, a wyglądają dla diffa różnie, mimo że oba zwracają te same wiersze w innej kolejności. Dla 95% zadań code review (migracje schematu, refaktoryzacje zapytań, porównanie wyjścia ORM) tekstowy diff to dokładnie to, czego chcesz, ponieważ kolejność kolumn i klauzul jest częścią tego, jak zespół czyta zmianę.
Jeśli kiedykolwiek próbowałeś znaleźć jedną nową klauzulę WHERE w 400-liniowym zapytaniu analitycznym, które zaczęło zwracać inną liczbę wierszy, to jest narzędzie, które doprowadzi cię tam w sekundach. Dla prozy spoza SQL nasze narzędzie diff tekstu jest właściwym wyborem. Dla payloadów wyników ORM w JSON, JSON diff radzi sobie z przestawianiem obiektów czyściej. Dla starszych eksportów DDL pisanych jako metadane XML, XML diff pasuje lepiej.
Jak diff faktycznie działa
Pod maską diff działa na poziomie znaków, a potem przebieg semantyczny przesuwa podświetlenia, by trafiały na identyfikatory, słowa kluczowe i granice klauzul, a nie na losową interpunkcję. Wstawienia pojawiają się na zielono po prawej, usunięcia na czerwono po lewej. Każdy panel ma przycisk Format, który przepuszcza SQL z konsekwentnym wcięciem i jedną instrukcją na linię, co usuwa większość szumu formatowania jeszcze przed porównaniem.
SQL to rodzina dialektów, nie jeden język. Standard ISO/IEC 9075 definiuje gramatykę bazową, ale każda baza ją rozszerza: PostgreSQL ma stringi z dollar-quoting i RETURNING, MySQL ma identyfikatory w backtickach i ON DUPLICATE KEY UPDATE, SQL Server używa TOP i identyfikatorów w nawiasach kwadratowych, SQLite toleruje niemal wszystko, a Oracle ma ROWNUM i CONNECT BY. Diff między dialektami jest w porządku; narzędzie nie ostrzeże, że jakiś fragment jest nieprawidłowy w którymś z nich.
Druga rzecz do wiedzy: porównywanie tekstu zapytania to nie to samo, co porównywanie planów. Dwie instrukcje o identycznym tekście mogą produkować bardzo różne plany przy różnych statystykach, a dwie kosmetycznie różne instrukcje mogą produkować identyczny plan. Do porównania planów właściwymi narzędziami są EXPLAIN ANALYZE w psql lub odpowiednik w Twoim kliencie bazy (DataGrip, DBeaver, SSMS). Do recenzji refaktoryzacji tekstowej diff jest tym, czego chcesz. Lektura tła o samym języku na Wikipedii.
Jak porównać SQL w trzech krokach
Dwa panele tekstowe, jeden diff. Bez rejestracji, bez uploadu, bez round-tripa do serwera.
- 1
Wklej lub załaduj swój SQL
Wklej stary SQL po lewej, nowy po prawej. Lub kliknij Upload po dowolnej stronie, by wczytać bezpośrednio plik .sql, .ddl lub .psql. Przycisk Sample wypełnia oba panele małym przykładem schematu orders, jeśli chcesz najpierw zobaczyć narzędzie w akcji.
- 2
Sformatuj obie strony, by porównanie było uczciwe
Kliknij Format na każdym panelu, by przepuścić SQL z konsekwentnym wcięciem, jedną instrukcją na linię i słowami kluczowymi pisanymi wielkimi literami. To eliminuje szum z zapytania sformatowanego przez DataGrip po jednej stronie i pisanego ręcznie po drugiej, więc diff podświetla rzeczywiste zmiany schematu i klauzul, a nie różnice w spacjach i wielkości liter.
- 3
Czytaj diff
Usunięcia pojawiają się z czerwonym podświetleniem po lewej, wstawienia z zielonym po prawej. Przewijanie jednej strony pociąga za sobą drugą. Liczniki zmian w każdym nagłówku mówią, ile osobnych edycji diff znalazł w kolumnach, JOIN-ach, predykatach i elementach DDL.
Kiedy SQL diff to właściwe narzędzie
Recenzja migracji schematu przed zastosowaniem
PR migracyjny dodaje trzy kolumny i poprawia dwa indeksy. Wklej poprzedni CREATE TABLE przeciwko nowemu, a dodatki rzucają się w oczy: kolumna currency CHAR(3) NOT NULL została dodana bez DEFAULT, co padnie na każdym istniejącym wierszu. Wyłapanie tego, zanim migracja pójdzie na produkcję, zamiast po tym, jak alarm deploymentu odezwie się o 2 w nocy, to cały sens tego przepływu. Ta sama wartość dla instrukcji ALTER TABLE, gdzie typ kolumny zwęża się z VARCHAR(255) do VARCHAR(50).
Diff dwóch wersji zapytania analitycznego
Zapytanie raportowe, które wczoraj zwracało 12 400 wierszy, dziś zwraca 8 900. Zrób diff zapisanego zapytania z wczoraj przeciwko dzisiejszemu, a winowajca wypłynie: LEFT JOIN po cichu zmienił się w INNER JOIN, lub ktoś próbujący posprzątać dashboard dodał WHERE status <> 'cancelled'. Tekstowy diff doprowadzi cię do linii w sekundy, podczas gdy czytanie obu zapytań obok siebie na Slacku zajęłoby dziesięć minut.
Porównanie SQL generowanego przez ORM między wersjami aplikacji
Po upgrade Hibernate lub SQLAlchemy zapytania, które miały trzy JOIN-y, mają teraz cztery z dodatkowymi podzapytaniami, lub binding parametrów przeszedł z ? na placeholdery $1. Wyciągnij SQL z logu zapytań na każdej wersji aplikacji (psql log_statement = all, slow log MySQL lub narzędzie APM) i zrób diff. Nazwy aliasów będą hałaśliwe (t1, t2, generatedAlias0), ale rzeczywista zmiana strukturalna to zwykle jedyna rzecz, którą diff podświetla jako prawdziwą edycję.
Walidacja, że refaktoryzacja DDL zachowuje intencję
Zmieniłeś nazwę user_orders na orders i podzieliłeś kolumnę JSON blob na znormalizowane tabele. Wklej wyjście pg_dump --schema-only przed i po refaktoryzacji; diff czyni oczywistym, czy zachowałeś każdy constraint, indeks i default. Pułapka, na którą trzeba uważać, to NOT NULL, który po cichu zniknął podczas zmiany nazwy, lub constraint UNIQUE, który odpadł, bo nikt nie dodał go ponownie na nowej tabeli.
Sprawdzenie, czy schemat staging zgadza się z prod
Uruchom pg_dump --schema-only --no-owner przeciwko staging i prod, potem zrób diff obu. Różnice powinny być dokładnie migracjami w kolejce do najbliższego deploymentu. Cokolwiek innego, dodatkowy indeks, inny typ kolumny, zapomniana tabela testowa, to znak driftu schematu, który ugryzie podczas faktycznego deploymentu. To samo podejście z mysqldump --no-data dla MySQL i SCRIPT TO dla SQL Server, lub eksportem schematu z DataGrip dla dowolnej bazy.
Recenzja portowania między dialektami (Postgres do MySQL)
Portowanie zapytania z PostgreSQL na MySQL lub odwrotnie oznacza śledzenie, które funkcje, typy i klauzule muszą się zmienić: SERIAL kontra AUTO_INCREMENT, NOW() kontra CURRENT_TIMESTAMP, RETURNING kontra LAST_INSERT_ID(). Zrób diff oryginału przeciwko wersji portowanej, a wszystkie podstawienia dialektu wypłyną. Diff nie zwaliduje SQL na docelowym dialekcie, więc i tak przepuść go przez psql lub mysql, by potwierdzić, ale widok linia po linii powie ci, które decyzje sprawdzić podwójnie.
Szybka referencja SQL
Krótka ściąga skrajnych przypadków dialektu i parsowania, które ten diff najczęściej wydobywa na wierzch. Oparta na standardzie ISO SQL i dokumentacji głównych dostawców.
| Topic | What this tool does |
|---|
| Drift dialektu | PostgreSQL, MySQL, SQL Server, SQLite i Oracle, każdy rozszerza standard ISO SQL własną składnią. SERIAL, AUTO_INCREMENT, IDENTITY i GENERATED ALWAYS AS IDENTITY to cztery sposoby zapisu tej samej idei. |
|---|
| Zwijanie wielkości identyfikatorów | PostgreSQL zwija nieujęte w cudzysłów identyfikatory do małych liter, więc Users i users to ta sama tabela. MySQL zależy od lower_case_table_names i bazowego systemu plików. SQL Server jest domyślnie case-insensitive, ale szanuje collation. Otaczaj identyfikatory "Users" (standard), backtickami (MySQL) lub nawiasami kwadratowymi (SQL Server), by zachować wielkość liter. |
|---|
| Wielkość słów kluczowych | Słowa kluczowe SQL są case-insensitive wszędzie, więc SELECT i select są dla parsera identyczne. Konwencja to wielkie litery dla słów kluczowych i małe dla identyfikatorów; większość style guide'ów i specyfikacja ISO za nią idą. Mieszana wielkość jest poprawna i wykonuje się, ale narzędzia takie jak sqlfluff i sqlfmt ją normalizują. |
|---|
| Style komentarzy | Dwie formy: -- komentarz liniowy (kończy się na końcu linii) i /* komentarz blokowy */ (bez zagnieżdżania w standardowym SQL, choć niektóre dialekty na to pozwalają). MySQL wspiera też # dla komentarzy liniowych jako rozszerzenie. Diff traktuje komentarze jako tekst i pokazuje edycje komentarzy jak każdą inną zmianę. |
|---|
| Separatory instrukcji | Średnik (;) kończy instrukcję w standardowym SQL. Większość klientów wymaga go między instrukcjami w skrypcie. Niektórzy klienci (SSMS) używają zamiast tego GO jako separatora batcha, co nie jest częścią gramatyki SQL; to dyrektywa klienta. |
|---|
| Stringi z dollar-quoting (PostgreSQL) | PostgreSQL wspiera $tag$ ... $tag$ dla literałów stringowych, więc nie musisz escape'ować pojedynczych cudzysłowów wewnątrz, szczególnie przydatne w ciałach funkcji. $$ SELECT 'hello' $$ jest poprawne i powszechne w blokach CREATE FUNCTION. Inne dialekty nie parsują tej składni. |
|---|
| Placeholdery binding parametrów | Brak standardu. PostgreSQL i ORM-y go celujące używają $1, $2. JDBC, MySQL i ODBC używają ?. Nazwane placeholdery :name są powszechne w Oracle i w wielu szablonach stringów ORM. SQL generowany przez ORM między wersjami często różni się tylko stylem placeholderów; sformatuj obie strony przed diffem. |
|---|
| Kodowanie | UTF-8 to uniwersalny default dla plików SQL w 2026. Starsze skrypty pochodzenia Windows mogą wciąż być zapisane jako UTF-16 LE z BOM, co pokazuje się jako znak-widmo w linii 1 tekstowego diffa. Jeśli dwa pliki wyglądają identycznie, ale diff flaguje zmianę jednego znaku na początku, podejrzewaj BOM i zapisz ponownie z jawnym UTF-8. |
|---|
SQL diff: często zadawane pytania
Czym to się różni od uruchomienia EXPLAIN ANALYZE na obu zapytaniach?
Inna warstwa stosu. EXPLAIN ANALYZE pokazuje plan zapytania, to, co optymalizator zdecydował zrobić przy posiadanych statystykach. To narzędzie diffuje tekst zapytania, czyli to, co zmieniło się w twoim repo. Zwykle chcesz obu: tego diffa, by wychwycić refaktoryzację (zmienił się typ JOIN-a, predykat się przesunął), a potem EXPLAIN ANALYZE w psql lub twoim kliencie, by potwierdzić, że optymalizator naprawdę wybrał sensowny plan dla nowej formy. Oba są komplementarne, nie zamienniki.
Czy diff jest świadomy dialektu (PostgreSQL vs MySQL vs SQL Server)?
Nie. Diff traktuje wejście jako tekst, więc nie parsuje PostgreSQL, MySQL, SQL Server, SQLite ani Oracle różnie i nie flaguje składni niezgodnej z dialektem. To celowe: oznacza, że możesz robić diff między dialektami, czyli dokładnie tego, czego chcesz przy portowaniu zapytania. Jeśli potrzebujesz lintingu świadomego dialektu, przepuść SQL przez sqlfluff lub parser swojej bazy osobno. Dla przypadku użycia w recenzji ("co się zmieniło w tym zapytaniu") poziom tekstu to właściwa granulacja.
Czy narzędzie formatuje SQL za mnie?
Tak, przycisk Format na każdym panelu przepuszcza SQL z konsekwentnym wcięciem, słowami kluczowymi wielkimi literami i jedną instrukcją na linię. To podstawowy formatter, nie zamiennik dla sqlfmt czy sqlfluff: nie przepisuje JOIN-ów ukrytych na jawne i nie wymusza style guide konkretnego dialektu. Chodzi o eliminację szumu formatowania przed diffem, by zapytanie sformatowane przez DataGrip po jednej stronie i pisane ręcznie po drugiej porównały się czysto.
Czy normalizuje wielkość słów kluczowych (SELECT vs select)?
Przycisk Format zmienia słowa kluczowe na wielkie litery, co jest konwencją w większości style guide'ów i w standardzie ISO SQL. Jeśli nie klikniesz Format, mieszana wielkość pojawi się jako diff, ponieważ silnik pod spodem jest oparty na znakach. Słowa kluczowe SQL są case-insensitive w każdej bazie, więc select i SELECT wykonują się identycznie. Wielkość identyfikatorów to inna sprawa i różni się między bazami; zobacz szybką referencję poniżej, jak różnią się Postgres, MySQL i SQL Server.
Jak radzić sobie z aliasami generowanymi przez ORM jak t1, t2, generatedAlias0?
Wyjście ORM jest hałaśliwe z założenia: Hibernate generuje generatedAlias0, generatedAlias1, a SQLAlchemy używa anon_1, anon_2. Jeśli dwie wersje ORM przypisują te same aliasy w innej kolejności, tekstowy diff podświetli każdą zamianę aliasu jako zmianę, mimo że zapytanie jest strukturalnie identyczne. Praktyczne rozwiązanie to sformatować obie strony, zignorować różnice tylko-aliasowe (zwykle oczywiste jako sparowane czerwone i zielone bloki w tej samej linii) i skupić się na rzeczywistych edycjach strukturalnych: nowy JOIN, inna klauzula WHERE, usunięta kolumna.
Czy są limity rozmiaru SQL, który wklejam?
Limity miękkie, nie twarde. Diff działa w twojej przeglądarce, więc górną granicą jest pamięć przeglądarki i to, ile jesteś gotów czekać. Wyjście pg_dump z 5000 linii diffuje się w mocno poniżej sekundy na nowoczesnym laptopie. Dump z 200 000 linii może zająć kilka sekund i otrzeć się o limity pamięci na słabszych urządzeniach. Dla tak dużych dumpów bazy właściwy przepływ to najpierw zrobić diff samego schematu (pg_dump --schema-only), a potem zejść w konkretne tabele, jeśli potrzebujesz porównania na poziomie danych.
Prywatność i jak to działa
Twój SQL nigdy nie opuszcza przeglądarki. Formatter i diff działają oba na twojej maszynie, lokalnie. Brak analityki na twoim wejściu, brak logów, brak "pomocnego" round-tripa do chmury, co ma znaczenie, gdy SQL, który wklejasz, zawiera prawdziwe nazwy tabel, prawdziwe nazwy kolumn lub prawdziwe dane produkcyjne w przykładowym wierszu. Język jest udokumentowany w ISO/IEC 9075, a referencje dialektów to PostgreSQL, MySQL, SQL Server i SQLite.