2009-05-23 16 views
5

Mam dane źródło danych tygodniowo, które mam zamiar parsować i umieścić w bazie danych. Dane niewiele się zmienią z tygodnia na tydzień, ale powinienem regularnie aktualizować bazę danych. Oprócz tej cotygodniowej aktualizacji dane są statyczne.Jaki jest najlepszy sposób na aktualizację (lub zamianę) całej tabeli bazy danych na uruchomionym komputerze?

Na razie przebudowanie całej bazy danych nie stanowi problemu, ale docelowo ta baza danych będzie działać, a ludzie mogą przesyłać zapytania do bazy danych podczas jej przebudowy. Ilość danych nie jest mała (kilkaset megabajtów), więc nie ładuje się tego natychmiastowo, a osobiście chcę nieco bardziej niezawodnego systemu niż "Mam nadzieję, że nikt nie zapyta, gdy baza danych jest w rozsypce".

Pomyślałem o kilku różnych sposobach rozwiązania tego problemu i zastanawiałem się, jaka byłaby najlepsza metoda. Oto moje pomysły do ​​tej pory:

  1. Zamiast wymieniać całe tabele, kwerendy dla różnicy między moim bieżącej bazy danych i co chcę umieścić w bazie danych. Wygląda na to, że może to być niepotrzebna praca.

  2. Tworzenie fałszywych tabel danych, a następnie zmiana nazwy tabeli (lub posiadanie kodu serwera w kierunku nowych tabel danych).

  3. Po prostu informując użytkowników, że serwis przechodzi konserwację i wyłącza system na kilka minut. (Nie jest to lepsze z oczywistych względów, ale jeśli jest to daleko najlepsza odpowiedź, którą chętnie zaakceptuję.)

Myśli?

+0

Jakiś konkretny system baz danych, który masz na myśli? –

+0

Obecnie używam MySQL, ale mogę skończyć używając PostgreSQL. –

Odpowiedz

5

nie mogę mówić dla MySQL, PostgreSQL, ale ma transakcyjnej DDL. Jest to wspaniała cecha i oznacza, że ​​twoja druga opcja, ładowanie nowych danych do obojętnego stołu, a następnie wykonywanie zmiany nazwy tabeli, powinna działać świetnie. Jeśli chcesz zamienić tabelę foo na foo_new, musisz tylko załadować nowe dane do foo_new i uruchomić skrypt, aby zmienić nazwę. Ten skrypt powinien zostać wykonany we własnej transakcji, więc jeśli coś z tą nazwą zmieni się na złe, zarówno foo jak i foo_new pozostaną nietknięte po wycofaniu.

Głównym problemem związanym z tym podejściem jest to, że może trochę nieładnie obchodzić się z kluczami obcymi z innych tabel, które mają klucz foo. Ale przynajmniej masz gwarancję, że Twoje dane pozostaną spójne.

Lepszym podejściem w dłuższej perspektywie, jak sądzę, jest jedynie bezpośrednie uaktualnianie danych (twoja pierwsza opcja). Ponownie możesz trzymać wszystkie aktualizacje w pojedynczej transakcji, więc masz gwarancję semantyki wszystko-albo-nic. Jeszcze lepsze byłyby aktualizacje online, po prostu aktualizując dane bezpośrednio w miarę pojawiania się nowych informacji. Może to nie być opcja dla Ciebie, jeśli potrzebujesz wyników zadania wsadowego innej osoby, ale jeśli możesz to zrobić, jest to najlepsza opcja.

1

Z którego serwera bazy danych korzystasz? SQL 2005 i nowszy zapewnia metodę blokowania o nazwie "Migawka". Pozwala na otwarcie transakcji, wykonanie wszystkich aktualizacji, a następnie zatwierdzenie, podczas gdy użytkownicy bazy danych nadal przeglądają dane przed transakcją. Zwykle transakcja blokuje twoje tabele i blokuje ich zapytania, ale blokowanie migawek byłoby idealne w twoim przypadku.

Więcej informacji tutaj: http://blogs.msdn.com/craigfr/archive/2007/05/16/serializable-vs-snapshot-isolation-level.aspx

Ale to wymaga SQL Server, więc jeśli używasz coś innego ....

1

Kilka systemów baz danych (ponieważ nie określił swoje, będę zachować to ogólnie) oferują SQL: 2003 oświadczenie Standardowy nazywa MERGE które zasadniczo pozwalają

  • wstawić nowe wiersze do tabeli docelowej ze źródła, które nie istnieją tam jeszcze
  • aktualizacji istniejących wierszy w tabeli docelowej w oparciu o nowe wartości ze źródła
  • ewentualnie nawet usunąć wiersze z tarczy, które nie pojawiają się w tabeli importowej już

SQL Server 2008 to pierwsza ofiara Microsoft mieć to oświadczenie - sprawdź więcej here, here lub here.

Inny system bazodanowy prawdopodobnie będzie miał podobne implementacje - jest to mimo wszystko instrukcja SQL: 2003 Standard.

Marc

3
BEGIN; 
DELETE FROM TABLE; 
INSERT INTO TABLE; 
COMMIT; 

Użytkownicy zobaczą zmianę natychmiast po naciśnięciu przycisku zatwierdzenia. Wszelkie zapytania rozpoczęte, zanim zatwierdzenie zostanie uruchomione na starych danych, cokolwiek później zostanie uruchomione na nowych danych. Baza danych rzeczywiście wyczyści starą tabelę po zakończeniu ostatniego użytkownika. Ponieważ wszystko jest "statyczne" (jesteś jedynym, który je zmienia, i tylko raz w tygodniu), nie musisz się martwić o żadne problemy z blokadą lub limity czasu. W przypadku MySQL zależy to od InnoDB. PostgreSQL to robi, a SQL Server nazywa to "migawką" i nie pamiętam szczegółów z mojej głowy, ponieważ rzadko używam tego.

Jeśli "izolacja transakcji" Google i nazwa dowolnej bazy danych, której używasz, znajdziesz odpowiednie informacje.

+1

Tak, ale jeśli ładowanie kilkuset megabajtów danych zajmuje kilka minut, twój system nie będzie mógł obsłużyć klienta w tym czasie ..... to rozwiązanie jest świetne tylko dla NAPRAWDĘ małych zestawów danych. Co się stanie, jeśli Twoje dane będą miały integralność referencyjną? Możesz po prostu nie być w stanie całkowicie wymazać stołu bazowego na początek ... –

+2

Tak, będziesz w stanie obsłużyć klienta w tym czasie. To jest punkt izolacji transakcji. Jeśli masz integralność referencyjną, musisz usunąć rzeczy we właściwej kolejności, tak jak trzeba je wstawić we właściwej kolejności. –

+1

To jest oczywiście właściwe rozwiązanie SQL, wykorzystujące transakcje. – bortzmeyer

1

Użyj różnych nazw tabel (mytable_ [yyyy] _ [wk]) i widoku, aby podać stałą nazwę (mytable). Po całkowitym zaimportowaniu nowej tabeli zaktualizuj swój widok, aby korzystać z tej tabeli.

2

Rozwiązaliśmy ten problem, używając mechanizmu dziedziczenia/ograniczeń tabeli PostgreSQL. Tworzysz wyzwalacz, który automatycznie tworzy podszabawki podzielony na partycje na podstawie pola daty.

This artykuł był źródłem, którego użyłem.

Powiązane problemy