Redgate Hub
wprowadzenie
istnieje kilka powodów, dla których może być konieczne porównanie tabel lub wyników.
- czasami wystarczy wiedzieć, czy tabele zawierają dane, które są takie same lub różne; brak szczegółów: po prostu tak lub nie. Jest to typowe w przypadku twierdzeń testowych, w których wystarczy wiedzieć, czy rutynowa lub partia daje wynik z odpowiednimi danymi. w przypadku dostarczenia określonych walców dla parametrów. Jest albo źle, albo dobrze
- czasami musisz wiedzieć, jakie wiersze się zmieniły, nie zwracając uwagi na to, które kolumny się zmieniły i jak.
- czasami masz dużą tabelę zarówno pod względem kolumn, jak i wierszy i potrzebujesz czegoś, co pokaże Ci kolumny, które zmieniły swoją wartość. Możesz również tego chcieć, gdy wyśledzisz błąd w rutynie, która w przeciwnym razie może wymagać marnowania czasu na skanowanie „na oko”.
zajmiemy się tymi trzema raczej różnymi zadaniami w SQL
Jeśli dwie tabele mają inną liczbę wierszy, nie mogą być oczywiście takie same. Są jednak chwile, kiedy musisz wiedzieć, czy Table_B zawiera wszystkie wiersze Table_A, bez różnic. Jeśli chcesz uzyskać więcej szczegółów, możesz nawet chcieć poznać wiersze w tabeli, które nie są wspólne, lub wiersze wspólne, jak wskazuje klucz podstawowy, które były różne. Po co porównywać tylko dwie tabele? Istnieją sposoby porównywania tyle, ile potrzebujesz. (na przykład podczas porównywania metadanych w kilku migawkach bazy danych). Tak, istnieje wiele odmian
masz narzędzia i funkcje, aby to zrobić, na pewno?
zawsze jest miejsce na narzędzia takie jak SQL Data Compare, TableDiff, tSQLt czy Change Data Capture. Wiele zależy od okoliczności i rodzaju zadania. Osobnym tematem jest problem przeprowadzania audytów zmian danych w systemie live, podobnie jak synchronizacja tabel i baz danych. Porównanie dokumentów XML jest również poza zakresem. Będziemy zajmować się wyłącznie rutynowym porównywaniem danych w tabelach
najprawdopodobniej użyję technik TSQL do porównywania tabel, gdy:
rozwijanie…
w trakcie tworzenia bazy danych porównuje się wiele tabel. To nie tylko wielkie rzeczy: każda funkcja wartościująca tabelę, na przykład, potrzebuje uprzęży testowej w skrypcie kompilacji, która upewnia się, że robi to, co uważasz, że powinna zrobić we wszystkich możliwych warunkach testowych, i obejmuje wszystkie paskudne przypadki, w których została złapana przez testerów w przeszłości. Każda procedura składowana wymaga testu, aby upewnić się, że proces, który wykonuje, robi dokładnie to, co jest zamierzone i nic więcej.
był czas, że budowa była raczej spokojna, ale kiedy masz nocny test budowania i integracji, najlepiej jest całkowicie zautomatyzować go i pozbyć się obowiązków.
ETL
Kiedy automatyzujesz ładowanie danych do systemu, często musisz przetestować różne warunki. Czy musisz aktualizować istniejące wersje wierszy, a także wstawiać nowe? Czy potrzebujesz pułapki, aby zapobiec duplikowaniu wpisów, a nawet usunąć istniejące wpisy?
Konfigurowanie danych testowych.
wszystkie skrypty w tym artykule używają tabeli z bazy danych czcigodnych pubów. Użyjemy tabeli autorów, ale zwiększymy liczbę wierszy nieco do 5000, aby uzyskać rozmiar, który jest nieco bardziej realistyczny. Podałem źródło tabeli z artykułem.
I then created a copy of the table …
1
2
3
4
5
6
|
SELECT * INTO authorsCopy
FROM authors
GO
ALTER TABLE dbo.authorsCopy dodaj ograniczenie PK_authorsCopy PRIMARY KEY CLUSTERED
(au_id) na PRIMARY
przejdź
|
, a następnie zmień niektóre wiersze.
1
2
3
4
5
|
update authorscopy set address=stuff(address,1,1,”)
gdzie au_id w (
wybierz top 10 au_id
z authorscopy f
Zamów przez telefon)
|
więc teraz dwie tabele powinny być zasadniczo takie same z kilkoma drobnymi zmianami w polu adresu
testowanie aby sprawdzić, czy tabele są różne.
czasami po prostu chcesz wiedzieć, czy tabele są takie same. Przykładem tego może być sprawdzenie, czy TVF działa poprawnie, porównując jego wynik z wynikiem z istniejącej tabeli z poprawnymi wynikami. Zwykle można to zrobić za pomocąCHECKSUM()
grupy funkcji w SQL serverze, ponieważ są one bardzo szybkie.
używając sum kontrolnych
możesz użyć funkcjiBINARY_CHECKSUM
, aby sprawdzić, czy tabele są takie same: cóż, mniej więcej takie same. Jest szybki, ale nie jest idealny, co zademonstruję za chwilę. Jeśli masz serię testów, na przykład jest to ogólnie wystarczające.
1
2
3
4
5
6
7
8
9
|
JEŚLI (
WYBIERZ KONTROLNY СУММУ_AGG(BINARNY SUMA KONTROLNA(*))
OD autorów)=(
WYBIERZ KONTROLNY СУММУ_AGG(BINARNY KWOTA(*))
Z authorscopy)
WYBIERZ „są prawdopodobnie takie same”
JESZCZE
WYBIERZ „są różne”
|
aby to działało, twoja tabela nie może mieć TEXT, NTEXT, IMAGE or CURSOR
(lub SQL_VARIANT
z żadnym z tych typów) jako typu podstawowego. W dzisiejszych czasach jest to coraz rzadsze, ale jeśli masz jakiekolwiek komplikacje, możesz zmusić dowolną kolumnę z jednym z nieobsługiwanych typów do obsługiwanego typu. W praktyce zazwyczaj używam procedury, która sprawdza metadane i robi to automatycznie, ale nie jest to ładne.
w wersji roboczej prawdopodobnie chcesz podać listę kolumn, zwłaszcza jeśli musisz wykonać jawny przymus typów danych lub jeśli sprawdzasz tylko niektóre kolumny,
ani BINARY_CHECKSUM()
, ani jej zwykły siostrzany CHECKSUM()
nie są całkowicie dokładne w informowaniu, czy coś się zmieniło w wierszu lub tabeli. Pokażemy to, patrząc na wspólne słowa języka angielskiego, zawarte w tabeli o nazwie CommonWords
.. Można by oczekiwać, że wszystkie będą miały inną sumę kontrolną, ale tak nie jest.
1
2
3
4
5
6
7
8
9
|
WYBIERZ wiersz BINARNY KWOTĘ (wiersz), JAKO „sumy Kontrolnej”
Z ogólnych słów
GDZIE BINARNY SUMA KONTROLNA(wiersz) W
(
WYBIERZ BINARNY SUMĘ KONTROLNĄ(wiersz)
Z ogólnych słów
GRUPUJ WEDŁUG BINARY SUMY KONTROLNEJ(wiersz)
O ILOŚĆ(*) > 2)
ORDER BY BINARY_CHECKSUM(string)
|
… dając wynik …
uzbrojeni w te informacje, możemy szybko wykazać, że różne ciągi mogą mieć takie same suma kontrolna
1
2
3
|
wybierz binary_checksum(’Reed the nerd’),
binary_checksum(’sued the nest’),
BINARY_CHECKSUM(’stud the oust’)
|
All these will; have the same checksum, as would …
1
2
3
|
SELECT
BINARY_CHECKSUM(’accosted guards’),
BINARY_CHECKSUM(’accorded feasts’)
|
….natomiast…
1
2
3
|
wybierz binary_checksum(’to wygląda bardzo podobnie do następnego’),
binary_checksum(’to wygląda bardzo podobnie do następnego’),
binary_checksum(’to wygląda bardzo podobnie do następnego’)
|
… daje różne sumy kontrolne w ten sposób…
1
2
|
———– ———– ———–
-447523377 -447522865 -447654449
|
The sister function CHECKSUM()
…
1
2
3
4
|
SELECT CHECKSUM(’This looks very much podobnie jak następne’),
suma kontrolna(’to wygląda bardzo podobnie do następnego’),
suma kontrolna(’to wygląda bardzo podobnie do następnego’)
|
… znajduje je wszystkie takie same, ponieważ używa bieżącego zestawienia i moje Zestawienie dla bazy danych jest niewrażliwe na wielkość liter. CHECKSUM()
ma na celu znalezienie równych łańcuchów w sumie kontrolnej, jeśli są one równe w porównaniu łańcuchów.
1
2
|
———– ———– ———–możesz więc powiedzieć, że istnieje duże prawdopodobieństwo, że tabele będą takie same, ale jeśli chcesz mieć absolutną pewność, użyj innego algorytmu.
Jeśli nie masz nic przeciwko różnicy liter w ciągach tekstowych, możesz użyć wielką wartością tej techniki jest to, że po obliczeniu sumy kontrolnej, której potrzebujesz, możesz zapisać ją jako wartość w kolumnie tabeli zamiast oryginalnej tabeli i dlatego możesz wykonać cały proces jeszcze szybciej i mniej czasu. Jeśli przechowujesz wartość sumy kontrolnej zwracaną przez Oto prosty przykład procedury „co się zmieniło”.
…which gives…
a potem po prostu posprzątamy.
oczywiście możesz użyć wyzwalacza, ale czasami możesz chcieć tylko dziennego lub tygodniowego raportu zmian bez ingerencji wyzwalacza w tabelę. Korzystanie z XMLjedną z ogólnych możliwości jest porównanie wersji XML obu tabel, ponieważ robi to tłumaczenie typu danych na ciągi znaków dla Ciebie. Jest wolniejszy niż suma kontrolna, ale bardziej niezawodny.
tutaj możesz określić typ porównania, określając zestawienie. lub możesz to zrobić, porównując dane w tabelach ..
… obliczając sumę kontrolną XML wersji tabeli. Pozwala to na przechowywanie sumy kontrolnej tabeli, z którą się porównujesz. znalezienie różnic w tabelinajprostszym zadaniem jest, gdy tabele mają identyczną liczbę wierszy i identyczną strukturę tabeli. Czasami chcesz wiedzieć, które wiersze są różne, a których brakuje. Musisz oczywiście określić, co masz na myśli przez „to samo”, szczególnie jeśli dwie tabele mają różne kolumny. Metoda, którą wybierzesz do porównania, jest zazwyczaj określana przez te szczegóły. the UNION ALL … GROUP BY techniqueklasycznym podejściem do porównywania tabel jest użycie
Jeśli jedna z tabel ma duplikat, to daje fałszywy wynik, jak tutaj, gdzie masz dwie tabele, które są bardzo różne, a wynik mówi ci, że są one takie same! Z tego powodu dobrym pomysłem jest dołączenie kolumn (kolumn), które stanowią klucz podstawowy, i dołączenie wierszy tylko raz!
… giving …
technika ta może być użyta do porównywania więcej niż dwóch tabel. Musisz tylko używając EXCEPTMożesz teraz użyć znacznie czystszego i nieco szybszego
pokazuje wszystkie wiersze autorów, których nie znaleziono w authorscopy. Jeśli są one takie same, nie odda wierszy
używam tylko select*, aby zachować prostotę artykułu. Zwykle wyszczególniasz wszystkie kolumny, które chcesz porównać. To będzie działać tylko dla tabel z taką samą liczbą wierszy, ponieważ, jeśli autorzy mieli dodatkowe wiersze, nadal mówiłoby, że były inne, ponieważ wiersze w autorach, których nie było w authorsCopy, zostaną zwrócone. Dzieje się tak, ponieważ to, mam nadzieję, że pokazuje, co mam na myśli
…yields …
..results in …
Ta funkcja możesz nie chcieć porównywać wszystkich kolumn. Należy zawsze określić te kolumny, które chcesz porównać, aby określić „identyczność”. Jeśli na przykład chcesz porównać adres, użyj …
technika łączenia zewnętrznegoistnieje również technika łączenia zewnętrznego. Jest to bardziej ogólna technika, która daje dodatkowe udogodnienia. Jeśli na przykład użyjesz pełnego połączenia zewnętrznego, możesz uzyskać niezrównane wiersze w każdej tabeli. Daje to Widok „przed” i ” po ” zmian w danych. Jest używany bardziej ogólnie w synchronizacji, aby powiedzieć, jakie wiersze należy usunąć, wstawić i zaktualizować. We’ll just use the technique to get the altered rows in authorsCopy
jak widać, istnieją trudności z kolumnami null w tym podejściu, ale jest tak szybki jak inne i daje raczej większą wszechstronność porównań. lokalizowanie różnic między tabelamimożesz potrzebować szybkiego sposobu sprawdzenia, która kolumna i wiersz uległy zmianie. Bardzo pomysłowy sposób na to został opublikowany niedawno. Używał XML. „Porównaj tabele i zgłoś różnice za pomocą Xml do obracania danych” (uwaga edytora: link przestarzały). Jest sprytny, ale zbyt wolny. To samo można zrobić wyłącznie w SQL. Zasadniczo porównuje się dane w kolumnie po kolumnie w oparciu o klucz podstawowy, używając pary klucz/wartość. Jeśli robisz całą tabelę na raz, jest to raczej powolne: najlepszą sztuczką jest zrobienie tego tylko w tych wierszach, w których wiesz, że istnieje różnica.
w naszym przykładzie da to:
ta technika obraca wiersze tabel, które mają różnice w tabeli Entity-attribute-value (EAV), dzięki czemu różnice w wierszu mogą być porównywane i wyświetlane. Wykonuje ten obrót przez wnioskinie ma jednej idealnej metody porównywania danych w tabelach lub wynikach. Jedna z wielu technik będzie najbardziej odpowiednia dla każdego konkretnego zadania. Wszystko zależy od odpowiedzi, których potrzebujesz i rodzaju zadania. Czy potrzebujesz szybkiego sprawdzenia, czy tabela się nie zmieniła, czy musisz dokładnie wiedzieć, jakie są zmiany? SQL jest oczywiście szybki w wykonywaniu tego zadania, a porównywanie tabel i wyników jest znanym zadaniem dla wielu programistów baz danych. Jeśli istnieje ogólna zasada, powiedziałbym, że praca eksploracyjna lub ad-hoc wymaga narzędzia takiego jak porównanie danych SQL, podczas gdy rutynowy proces w bazie danych wymaga ręcznie wyciętej techniki SQL.
|