porównanie dwóch zbiorów danych w celu synchronizacji

0

Mam do porównania dwa zbiory danych. Jeden z nich trzymany jest w bazie MsSQL i jest to tabela 1000 wierszy z 50 kolumnami (docelowo danych ma być naście i dziesiąt tysięcy). Dane dostaję prostym selectem "select * from tabela"
Drugi zbiór danych to aplikacja klienta, w której te dane także są trzymane i mam do nich dostęp przez API. Po wyciągnięciu ich przez API także dostaję dostęp do każdej kolumny i każdego wiersza (lista (wiersze) zawierająca w sobie podlistę (kolumny) czyli mam np. lista[999].podlista[49] dla ostatniego elementu i ostatniej kolumny).

Dane w aplikacji klienta mają się synchronizować z tymi z bazy MsSQL, tzn. jeśli coś się pojawiło w tabeli MsSQL (dodano element 1001) to ma też się pojawiać u klienta w aplikacji, jeśli coś się zmieniło w tabeli MsSQL to zmiana ta ma nadpisać dane w aplikacji klienta. Założenia są takie, że kilka kolumn w bazie jest unikalnych (także nie ma powtórek danych), ale nowe dane mogą pojawiać się pomiędzy istniejącymi wierszami, a nie zawsze na końcu, czyli:
Przed:
A
B
C

Po:<code>
A
AA
B
C

stąd, mówiąc obrazowo MsSQL[500] != API[500], nie mogę w pętli porównać jeden do jednego, czy zaszła jakaś zmiana.
Mam pytanie, w jaki sposób najwydajniej będzie te dane porównywać, jaki typ danych zastosować, żeby najszybciej wyłapać różnice i dalej pracować tylko na tych różnicach? A różnice chcę wpychać do aplikacji klienta już przez jego API.

Pozdrawiam.

0
  1. Piszesz o kliku unikalnych kolumnach dla każdego rekordu - czy stanowią one klucz główny?
  2. Czy jest albo jest możliwość przechowywania w obu bazach daty ostatniej edycji rekordu?

Jeśli odpowiedź to 2 x tak, to sprawa jest banalna. Jeśli nie, to trzeba będzie kombinować.

nowe dane mogą pojawiać się pomiędzy istniejącymi wierszami, a nie zawsze na końcu

To akurat jest oczywiste, bo sam serwer bazy danych nie określa kolejności zapisu rekordów, możesz ją jedynie wymusić przy odczycie.

0

Nie wiem czy dobrze zrozumiałem jest to synchronizacja w dwie strony? Więc skąd wiesz przy pierwszym odpaleniu który dane są nowsze? Zgaduje że posiadasz jakieś czasy modyfikacji/dodania. Więc przy pierwszym uruchomieniu i tak musisz przemielić całość. Więc ja bym oprał całość na prostym TimeStampie wybierasz tylko te rekordy które były zmodyfikowane po ostatnim sprawdzeniu.

0

synchronizacja tylko w jedną stronę MsSQL -> aplikacja, ale jeśli w aplikacji istnieje już jakiś obiekt, to mogę go tylko modyfikować, nie mogę go usunąć i dodać od nowa.

Nie mam możliwości dodania info daty ostatniej modyfikacji. Baza danych codziennie jest usuwana i tworzona od nowa (w zasadzie jest to widok danych z jeszcze innego systemu)

0
porównywacz napisał(a):

synchronizacja tylko w jedną stronę MsSQL -> aplikacja, ale jeśli w aplikacji istnieje już jakiś obiekt, to mogę go tylko modyfikować, nie mogę go usunąć i dodać od nowa.

Co ma się stać, jeśli z bazy MSSQL obiekt/rekord zostanie usunięty, a Ty nie możesz go usuwać w aplikacji?

0

nie przetwarzam go w żaden sposób, ostatnia istniejąca wersja obiektu pozostaje w aplikacji
aczkolwiek w sumie założenia są takie, że on nigdy z bazy nie zniknie

0

Czy lista kolumn jest stała?

0

To jedyny sposób jaki mi przychodzi do głowy to trzymanie wszystkiego co zwrócił poprzedni SELECT i porównywanie go z aktualnym. Zmiany które zaszły aktualizować w aplikacji klienckiej. Samo sprawdzanie czy to w samej bazie przy użyciu jakiejś tabeli tymczasowej czy to w aplikacji to kwestia wyboru, zapewne szybciej by było robić wszystko na samej bazie.

0

tak, ilość kolumn jest stała i nigdy się nie zmieni

0

To skoro kilka kolumn jest unikalnych i nie ma powtórzeń, to na tej podstawie możesz stwierdzić czy doszedł nowy wiersz czy nie. I sprawdzać to sekwencyjnie w pętli: bo KOL1+KOL2+KOL3 będzie zawsze wartością unikalną.

0

No tak, tyle że w ramach jednego wiersza, dalsze kolumny mogą się różnić i te zmiany muszę nanieść w aplikacji.
Mój problem polega na tym, że nie chce przelatywać przez każdą wartość, czyli ustaiwać się na lista[0] i jej 50 kolumn porównywać ze wszystkimi danymi w aplikacji, bo dla 10 000 wartości mam do przelecenia 10 000 rekorów z bazy x 50 kolumn x 10 000 istniejących wpisów w aplikacji. Oczywiście mocno to zawyżyłem, bo przecież po znalezieniu tego samego "unikalnego klucza" mogę robić return w pętli, ale myślałem, że może jest jakiś typ kolekcji, co zrobi wszystko za mnie. Ja tylko zaczytam dane do tego typu i on się sam porówna, a na końcu wypluje mi różnice.

0

Jeśli nie masz bezpośredniego dostępu do bazy drugiej aplikacji, i nie masz daty modyfikacji rekordu, to to nigdy nie będzie optymalne.

Algorytm:

  1. Skopiuj dane z tabeli oryginalnej do tymczasowej o tej samej strukturze.
  2. Następnym razem, pobierz z tabeli oryginalnej tylko te dane, które różnią się od tych w tabeli tymczasowej. Będzie to brzydki where na kilkadziesiąt porównań, ale raczej nie ma wyjścia.
  3. Uzyskasz w ten sposób zbiór rekordów zmodyfikowanych od ostatniego razu, nazwijmy go S.
  4. Z aplikacji wyciągasz te rekordy, w których kombinacja unikalnych kolumn (zakładam, że można ją traktować jako klucz główny) zawiera się w zbiorze S, i tylko te rekordy aktualizujesz.
  5. Wartości ze zbioru S aktualizujesz w tabeli tymczasowej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1