tło
Piszę wiele dużych raportów i ogólnie prowadzę dużą dokumentację medyczną DB (piszę SP, funkcje, zadania itp.). Oryginalny schemat i oprogramowanie, które go używa, pochodzi od innego dostawcy, więc nie mogę wiele zmienić strukturalnie. Istnieje wiele zapisów, które wymagają śledzenia, takich jak laboratoria, procedury, szczepionki itp. I są one rozrzucone po dziesiątkach tabel, z których wiele jest rozdętych i źle indeksowanych (udało mi się to nieco naprawić).
Problem
Problem polega na tym, że ponieważ mamy niewielką kontrolę nad bazą danych, a ponieważ może ona zmieniać się z dowolnej aktualizacji lub poprawki, sprawia, że pisanie i obsługa tych raportów jest trudna i żmudna - szczególnie, gdy nakładają się na siebie duże nakłady. Wystarczy jedna łatka i utknąłem przepisując duże części tuzina raportów. Ponadto zapytania szybko stają się zaciemnione i powolne w miarę łączenia, zagnieżdżania zaznaczeń i nakładania stosów.
Moje „rozwiązanie”
Mój plan polegał na zapisaniu wszystkich tych rekordów w jednej tabeli „catch-all” i zapisaniu wyzwalaczy na oryginalnych tabelach w celu utrzymania rekordów w tej tabeli zbiorczej. Oczywiście musiałbym upewnić się, że moje wyzwalacze były nienaruszone po aktualizacji, ale byłoby to o wiele łatwiejsze z punktu widzenia łatwości konserwacji i po prostu odwoływania się do danych.
Tabela byłaby cienka i długa, przechowująca tylko wymagane dane, mniej więcej tak:
CREATE TABLE dbo.HCM_Event_Log (
id INT IDENTITY,
type_id INT NULL,
orig_id VARCHAR(36) NULL,
patient_id UNIQUEIDENTIFIER NOT NULL,
visit_id UNIQUEIDENTIFIER NULL,
lookup_id VARCHAR(50) NULL,
status VARCHAR(15) NULL,
ordered_datetime DATETIME NULL,
completed_datetime DATETIME NULL,
CONSTRAINT PK_HCM_Event_Log PRIMARY KEY CLUSTERED (id)
)
Potem miałbym różne tabele relacyjne dla takich rzeczy jak ID_typu i grupowanie elementów.
Zaczynam zastanawiać się nad tym pomysłem, ponieważ kilka z tych tabel jest napisanych dość często, SP i raporty, które piszę, również często odnoszą się do danych. Dlatego obawiam się, że ta tabela stanie się koszmarem blokowania rekordów i wydajności przy tak dużej liczbie operacji we / wy.
Moje pytanie
Czy to zły czy dobry pomysł? Zdaję sobie sprawę, że każda sytuacja jest inna w SQL Server (2008 R2 Standard Edition BTW) i reguła „czasami”, ale tak naprawdę szukam tylko ogólnych porad.
Zacząłem rozważać skorzystanie z brokera usług, ale wykonuję tylko proste aktualizacje / wstawki ( zobacz alternatywę dla zaakceptowanej odpowiedzi ). Dane w wielu przypadkach muszą być przesyłane w czasie rzeczywistym, więc użycie kopii zapasowej bazy danych naprawdę nie działałoby. Wydajność już stanowi dla nas pewien problem, ale większość z nich dotyczy sprzętu, który wkrótce zostanie rozwiązany.
źródło
Odpowiedzi:
Jeśli dobrze cię zrozumiałem,
Chciałbym podejść do tego w ten sposób:
W takim przypadku możesz dostosować strukturę i indeksy swojej bazy danych, aby poprawić wydajność raportów, bez wpływu na system innej firmy. O ile oryginalna struktura danych nie zmieni się gwałtownie, logika zapytań dotyczących raportów nie zmieni się, jeśli baza danych innej firmy ulegnie zmianie. Trzeba będzie dostosować tylko proces synchronizacji.
Proces synchronizacji jest w rzeczywistości procesem konwersji - konwertujesz dane z zewnętrznych baz danych na potrzebną strukturę. Częścią tego procesu konwersji może być naprawienie wszelkich problemów z normalizacją, które może mieć oryginalna baza danych innej firmy. Tylko ta część systemu musi znać wewnętrzną strukturę systemu zewnętrznego i zależeć od niej. Główne raporty i główne zapytania zależą tylko od bazy danych.
Tak więc, głównym celem jest - oddzielenie i ograniczenie części systemu, która zależy od wewnętrznych elementów systemu innej firmy.
aktualizacja
Odnośnie wymagań w czasie rzeczywistym. BTW, zawsze myślałem, że definicja „w czasie rzeczywistym” to „gwarantowany czas reakcji”, a nie „jakiś mały czas reakcji”. Oczywiście zależy to od zastosowania. W mojej praktyce wystarczy zsynchronizować dwie bazy danych w ciągu minuty od wykrytej zmiany. Jeśli użytkownik zobaczy raport na ekranie i pewne podstawowe zmiany danych, raport należy jakoś ponownie uruchomić, aby odzwierciedlić tę zmianę. Możesz sondować zmiany lub odsłuchiwać jakieś zdarzenie / wiadomość, nadal należy ponownie wykonać zapytanie dotyczące raportu, aby wyświetlić najnowsze zmiany.
Już zamierzasz pisać wyzwalacze, aby przechwytywać zmiany w oryginalnych tabelach i zapisywać je w jednej tabeli ogólnej. Przechwytuj zmiany zgodnie z zamierzeniami, ale zapisuj je w odpowiednio znormalizowanych tabelach, a nie w jednej tabeli.
Jest to więc skrajny przypadek - konwersja struktury danych firm zewnętrznych na wewnętrzną strukturę danych odbywa się w wyzwalaczach uruchamianych w
INSERT/UPDATE/DELETE
tabelach firm zewnętrznych. To może być trudne. Kod wyzwalaczy zależałby od wewnętrznej struktury obu systemów. Jeżeli konwersja nie jest trywialna, może opóźnić oryginałINSERT/UPDATE/DELETE
do momentu jego awarii. Jeśli w twoim wyzwalaczu jest błąd, może to wpłynąć na pierwotną transakcję aż do momentu jej niepowodzenia. Jeśli zmieni się system innej firmy, może to spowodować uszkodzenie wyzwalacza, co spowodowałoby niepowodzenie transakcji systemu zewnętrznego.Mniej skrajny przypadek. Aby kod twoich wyzwalaczy był prostszy i mniej podatny na błędy, napisz wszystkie przechwycone zmiany do niektórych tabel pomostowych / kontrolnych / różnicowych, ustaw flagę / wyślij komunikat o oczekujących zmianach i uruchom główny proces konwersji, który przejdzie za pomocą tych tabel pośrednich i wykonaj konwersję. Najważniejsze jest to, że potencjalnie ciężki proces konwersji powinien nastąpić poza zakresem oryginalnej transakcji.
Na drugi rzut oka wygląda prawie jak twoja oryginalna sugestia w pytaniu. Różnica polega jednak na tym, że wszystkie tabele przechwytywania przechowują dane tylko tymczasowo; ilość danych jest niewielka - tylko to się zmieniło; nie musi to być pojedynczy stół; ostatecznie dane będą przechowywane w osobnych, odpowiednio znormalizowanych stałych tabelach, nad którymi masz pełną kontrolę, które są niezależne od systemu zewnętrznego i które możesz dostroić do swoich zapytań.
źródło
Zasadniczo umieść go w znormalizowanym zestawie tabel, abyś mógł dostosować etap importowania zamiast zmieniać złożone raporty i zapytania. Ale dane powinny być nadal znormalizowane, co będzie wymagało wielu tabel (ale z dobrymi indeksami).
Jak wspomnieli inni, nie używaj wyzwalaczy, synchronizuj partiami.
Nie martw się o wiele sprzężeń, gdy dane są normalizowane i odpowiednio indeksowane, nie powodują znacznych kosztów ani obciążeń związanych z zarządzaniem.
Czas na denormalizację w coś takiego jak hurtownia danych to czas, kiedy trzeba mieć możliwość wykonania wielu różnych zapytań o dane, których nie można przewidzieć. Ma swoje wady i koszty ogólne i powinien być używany w stosownych przypadkach, a nie jako codzienna sprawa.
źródło
Pracowałem z bardzo podobną sytuacją w przeszłości w firmie produkcyjnej 24x7 i ostatecznie zdecydowałem się na replikację transakcyjną. Możliwe jest skonfigurowanie replikacji DDL tak, aby można było wypychać wszelkie zmiany, które zmieniają subskrybent. Oczywiście są plusy i minusy wszystkiego i musisz je zważyć, aby określić, co możesz wesprzeć w stosunku do tego, co działa najlepiej dla firmy.
Z dobrej strony:
Istnieją jednak wady:
źródło
Wyzwalacze mają tak wiele problemów, że powinieneś ich unikać:
Lepszą opcją jest zadanie, które okresowo kopiuje dane do nowej tabeli. Twoje raporty mogą być uruchamiane z kopii. Zadanie, które kopiuje wiersze, jest łatwe do napisania i utrzymania i nie ma ryzyka, że wpłynie to na działanie aplikacji innej firmy.
źródło
NOCOUNT
? 4. W tabeli docelowej nie byłoby żadnych wyzwalaczy, a dla innych mogłem zapewnić to samo.