Jak mogę monitorować bazę danych SQL Server pod kątem zmian w tabeli bez używania wyzwalaczy lub modyfikowania w jakikolwiek sposób struktury bazy danych? Moje preferowane środowisko programistyczne to .NET i C #.
Chciałbym móc obsługiwać dowolny SQL Server 2000 SP4 lub nowszy. Moja aplikacja to skręcana wizualizacja danych dla produktu innej firmy. Nasza baza klientów jest w tysiącach, więc nie chcę nakładać wymagań, aby modyfikować tabelę zewnętrznego dostawcy przy każdej instalacji.
Przez „zmiany w tabeli” rozumiem zmiany danych tabeli, a nie zmiany struktury tabeli.
Ostatecznie chciałbym, aby zmiana wyzwalała zdarzenie w mojej aplikacji, zamiast sprawdzać zmiany w odstępach czasu.
Wydaje się, że najlepszym sposobem działania, biorąc pod uwagę moje wymagania (brak wyzwalaczy lub modyfikacji schematu, SQL Server 2000 i 2005), jest użycie BINARY_CHECKSUM
funkcji w T-SQL . Sposób, w jaki planuję wdrożyć, jest następujący:
Co X sekund uruchamiaj następujące zapytanie:
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);
I porównaj to z wartością przechowywaną. Jeśli wartość uległa zmianie, przejdź przez tabelę wiersz po wierszu, używając zapytania:
SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);
I porównaj zwrócone sumy kontrolne z zapisanymi wartościami.
źródło
Odpowiedzi:
Spójrz na polecenie SUMA KONTROLNA:
To zwróci tę samą liczbę za każdym razem, gdy zostanie uruchomiona, o ile zawartość tabeli nie ulegnie zmianie. Zobacz mój post na ten temat, aby uzyskać więcej informacji:
SUMA KONTROLNA
Oto jak go użyłem do odbudowania zależności pamięci podręcznej po zmianie tabel:
Zależność pamięci podręcznej bazy danych ASP.NET 1.1 (bez wyzwalaczy)
źródło
Niestety SUMA KONTROLNA nie zawsze działa poprawnie w celu wykrycia zmian .
Jest to tylko prymitywna suma kontrolna i brak obliczeń cyklicznej kontroli nadmiarowej (CRC).
Dlatego nie można go używać do wykrywania wszystkich zmian, np. Zmiany symetryczne skutkują tą samą SUMĄ KONTROLNĄ!
E. g. rozwiązanie z
CHECKSUM_AGG(BINARY_CHECKSUM(*))
zawsze zapewni 0 dla wszystkich 3 tabel o różnej zawartości:źródło
Dlaczego nie chcesz używać wyzwalaczy? Są dobrą rzeczą, jeśli używasz ich poprawnie. Jeśli używasz ich jako sposobu na wymuszenie integralności referencyjnej, wtedy zmieniają się z dobrych w złe. Ale jeśli używasz ich do monitorowania, nie są tak naprawdę uważane za tabu.
źródło
Jak często musisz sprawdzać zmiany i jak duże (pod względem wielkości wierszy) są tabele w bazie danych? Jeśli użyjesz
CHECKSUM_AGG(BINARY_CHECKSUM(*))
metody sugerowanej przez Johna, przeskanuje każdy wiersz określonej tabeli.NOLOCK
Wskazówka pomoże, ale na dużej bazie danych, nadal uderzania każdy wiersz. Będziesz także musiał zapisać sumę kontrolną dla każdego wiersza, aby powiedzieć, że jeden się zmienił.Czy zastanawiałeś się nad tym z innej perspektywy? Jeśli nie chcesz modyfikować schematu w celu dodania wyzwalaczy (co ma sens, to nie twoja baza danych), czy rozważałeś współpracę z dostawcą aplikacji, który tworzy bazę danych?
Mogliby zaimplementować interfejs API zapewniający mechanizm powiadamiania dodatkowych aplikacji o zmianie danych. Może to być tak proste, jak zapisanie do tabeli powiadomień, która zawiera listę tabeli i wiersza, który został zmodyfikowany. Można to zaimplementować za pomocą wyzwalaczy lub kodu aplikacji. Z Twojej strony nie ma to znaczenia, jedynym zmartwieniem byłoby okresowe skanowanie tabeli powiadomień. Wydajność bazy danych byłaby znacznie mniejsza niż skanowanie każdego wiersza w poszukiwaniu zmian.
Najtrudniejsze byłoby przekonanie dostawcy aplikacji do wdrożenia tej funkcji. Ponieważ można to obsługiwać całkowicie za pomocą języka SQL za pośrednictwem wyzwalaczy, większość pracy można wykonać, pisząc i testując wyzwalacze, a następnie przekazując kod do dostawcy aplikacji. Jeśli dostawca obsługuje wyzwalacze, zapobiega to sytuacji, w której dodanie wyzwalacza nieumyślnie zastępuje wyzwalacz dostarczony przez dostawcę.
źródło
Niestety nie wydaje mi się, aby można to zrobić w sposób czysty w SQL2000. Jeśli ograniczysz swoje wymagania do SQL Server 2005 (i nowszych), jesteś w biznesie. Możesz użyć
SQLDependency
klasy wSystem.Data.SqlClient
. Zobacz powiadomienia o zapytaniach w programie SQL Server (ADO.NET) .źródło
Mieć zadanie DTS (lub zadanie uruchamiane przez usługę systemu Windows) działające w określonych odstępach czasu. Za każdym razem, gdy jest uruchamiany, pobiera informacje o danej tabeli przy użyciu systemowych tabel INFORMATION_SCHEMA i zapisuje te dane w repozytorium danych. Porównaj zwrócone dane dotyczące struktury tabeli z danymi zwróconymi poprzednim razem. Jeśli jest inny, wiesz, że struktura uległa zmianie.
Przykładowe zapytanie zwracające informacje dotyczące wszystkich kolumn w tabeli ABC (najlepiej wyszczególniając tylko kolumny z tabeli INFORMATION_SCHEMA, które chcesz, zamiast używać * select **, tak jak tutaj):
Należy monitorować różne kolumny i widoki INFORMACJE_SCHEMA w zależności od tego, jak dokładnie zdefiniujesz „zmiany w tabeli”.
źródło
Zgadnij tutaj: jeśli nie chcesz modyfikować tabel strony trzeciej, czy możesz utworzyć widok, a następnie ustawić wyzwalacz w tym widoku?
źródło
Sprawdź datę ostatniego zatwierdzenia. W każdej bazie danych znajduje się historia każdego zatwierdzenia. Uważam, że jest to standard zgodności z ACID.
źródło