2010-09-30 20 views
12

SytuacjaJak zmienić projekt bazy danych w wdrożonej aplikacji?

Tworzę C#/WPF 4 aplikacji przy użyciu bazy danych SQL Compact Edition jako backend z Entity Framework i wdrażania z ClickOnce.

Jestem całkiem nowy dla aplikacji korzystających z baz danych, choć nie podejrzewam, że będę miał duży problem z zaprojektowaniem i zbudowaniem oryginalnej bazy danych. Obawiam się jednak, że w przyszłości będę musiał dodać lub zmienić niektóre funkcje, które będą wymagały zmiany projektu bazy danych po wdrożeniu bazy danych, a użytkownik ma dane w bazie danych.

Pytania

  1. Czy to w ogóle możliwe, aby popchnąć zaktualizowany projekt bazy danych do użytkowników poprzez aktualizację ClickOnce w ten sam sposób, to jest do zmiany kodu?

  2. W jaki sposób wpłynęłoby to na dane użytkownika?

  3. Jak to się robi w rzeczywistych sytuacjach? Jakie są najlepsze praktyki?

ja zorientować, że w najgorszym wypadku będę musiał zbudować jakąś „wersja” numer w ustawieniach bazy danych lub program i stworzyć jakąś rutynę migrować aktualny użytkownika wersję bazy danych do nowej jeden.

Doceniam wszelkie informacje na temat mojego problemu. Wielkie dzięki.

+3

vewy, vewy, carefuwy – annakata

Odpowiedz

12

Istnieje kilka "sztuczek", które są wykorzystywane podczas projektowania baz danych, aby umożliwić zmiany projektu.

Po pierwsze, wielu projektantów baz danych tworzy widoki na kodowanie, zamiast kodować bezpośrednio do tabel. Dzięki temu tabele mogą być zmieniane (dzielone lub łączone itp.), A jednocześnie wymagają aktualizacji widoków. Możesz sprawdzić, jakie są tego techniki.

Po drugie, można rzeczywiście dodać informacje o wersji do bazy danych (zwykle wykonywane jako tabela "wersja" z jednym polem). Aktualizowanie bazy danych może odbywać się za pomocą kodu lub skryptów. Jeden system, nad którym pracowałem, automatycznie sprawdza wersję bazy danych, a następnie stopniowo aktualizuje schemat za pomocą wersji w kodzie, dopóki nie zostanie dopasowana do wymaganej wersji środowiska wykonawczego. To było dość przedsięwzięcie.

+1

+1 Pracuję nad systemem, który sprawdza wersje bazy danych, a następnie aktualizuje schemat za pomocą kodu (mieszanki instrukcji definicji danych SQL i kodu do manipulowania strukturą bazy danych, poprzez ADO w naszym przypadku).Jedyną alternatywą, którą mogę wymyślić jest wyodrębnienie danych użytkownika ze starych baz danych do czystej nowej bazy danych. Byłoby to również dość duże przedsięwzięcie. – MarkJ

+0

+1 do przeglądania abstrakcji – annakata

+0

Dzięki za odpowiedź. SQL Server CE nie obsługuje widoków, ale ta sztuczka może się przydać innym. =) Myślę, że zamierzam zaimplementować jakiś system do rekurencyjnej migracji danych użytkownika, wersja po wersji, do aktualnej wersji DB. Ułatwi mi to również radzenie sobie z sytuacją przywracania kopii zapasowych, które mogą być w starszych wersjach. (Jednak myślę, że zrobię co w mojej mocy, aby zaprojektować bazę danych, więc nie ma ona zbyt dużego uaktualnienia!) –

2

Myślę, że wasz "najgorszy" przypadek jest właściwie całkiem niezłą drogą do przebycia w tej sytuacji. Utrzymanie wersji bazy danych w bazie danych i sprawdzenie aplikacji i zaktualizowanie bazy danych w razie potrzeby. Jeśli poprawnie zbudujesz narzędzie do aktualizacji, powinno być możliwe zachowanie danych użytkownika. W zależności od aktualizacji może się to wiązać z tworzeniem tymczasowych tabel do przechowywania istniejących danych i ponownego ich umieszczania na nowych wersjach tabel. Możesz być w stanie include a new SDF file z nowym schematem na miejscu w procesie aktualizacji i po prostu przenieść dane. W ten sposób może być nieco łatwiej - można użyć nazewnictwa plików w celu rozróżnienia wersji i uruchomienia kodu aktualizacji w ten sposób.

+0

Tak, jeśli poszedłem z "najgorszym przypadkiem", zrobiłbym nowy pusty SDF i przeniosłem dane użytkownika od starego do nowego, a następnie zmień nazwę pliku lub coś podobnego do tego. –

2

Niestety kontrola wersji i zarządzanie zmianami dla baz danych jest rozpaczliwie, rozpaczliwie daleko od tego, co można zrobić z resztą kodu.

Jeśli masz środowisko tylko do użytku wewnętrznego, istnieje wiele narzędzi, które mogą ci pomóc (DBGhost, Red Gate ma nowszą aplikację, niektóre aplikacje do zarządzania wdrożeniem), ale wszystkie z nich są mniej niż pełne rozwiązania imho, ale są w większości wystarczająco dobre.

W przypadku rozwiązań dostarczanych przez klienta naprawdę nie masz nic lepszego niż najgorszy przypadek, obawiam się. Po prostu spróbuj zaprojektować z myślą o elastyczności - patrz odpowiedź Dr.Herbie.

To nie jest rozwiązany problem.

2

"Smart Client Deployment z ClickOnce" Briana Noyesa ma świetny rozdział w tej kwestii. (Rozdział 5) ISBN 978-0-32-119769-6

Sugeruje on coś takiego:

if(ApplicationDeployment.CurrentDeployment.IsFirstRun) { 
    MigrateData(); 
} 

private void MigrateData() { 
    string previousDb = Path.Combine(ApplicationDeployment.CurrentDeployment.DataDirectory, @".\pre\mydb.sdf"); 

    if(!File.Exists(previousDb)) 
     return; 

    string oldConnString = @"Data Source=|DataDirectory|\.pre\mydb.sdf"; 
    string newConnString = @"Data Source=|DataDirectory|\mydb.sdf"; 

    //If you are using datasets perform any migration here, with the old and new table adapters. 
    //Otherwise use an .sql data migration script. 
    //Store the version of the database in the database, and check that in the beginning of your update script and GOTO the correct line in the SQL script. 

} 
+0

To brzmi jak przydatna książka. Na pewno to sprawdzę. Dzięki. –

+0

Mam tę książkę. Sekcja o mojej sytuacji jest prawie dokładnie. Wielkie dzięki za wskazówkę do książki, naprawdę nauczyło mnie to wiele o ClickOnce. –

+0

@Benny Jobigan, a co za tym idzie - skopiuj plik z ".pre" do domyślnego (tj. Do DataDirectory) i uruchom tylko skrypty aktualizacji, np. ALTER TABELA ... DODAJ KOLUMNY ... Co o tym sądzisz? – prostynick

2

Typowym rozwiązaniem jest to numer wersji gdzieś w bazie danych. Jeśli masz tabelę z różnymi danymi systemowymi, wyślij ją tam lub stwórz tabelę z jednym rekordem tylko po to, aby zachować numer wersji DB. Następnie za każdym razem, gdy program się uruchamia, sprawdź, czy wersja bazy danych jest mniejsza niż oczekiwana wersja. Jeśli tak, uruchom wymagane polecenia SQL CREATE, ALTER, etc, aby je przyspieszyć. Miej skrypt lub funkcję dla każdej zmiany wersji. Jeśli widzisz, że baza danych jest aktualnie w wersji 6, a kod oczekuje wersji 8, wykonaj aktualizację od 6 do 7 i aktualizację od 7 do 8.

Inną metodą, którą wykorzystaliśmy w jednym projekcie, w którym pracowałem, była wysłana tylko do schematu, bez bazy danych z kodem. Za każdym razem, gdy instalujesz nową wersję, instalator instalowałby także najnowszą kopię tej nowej pustej bazy danych. Następnie, po uruchomieniu programu, porównuje aktualny schemat bazy danych użytkownika z nowym schematem bazy danych i określa, jakie zmiany bazy danych były potrzebne w locie. Podobnie, jeśli w tabeli "schematu odniesienia" Foo miał kolumnę o nazwie Bar i nie było kolumny Bar w bieżącej bazie danych użytkownika, wygenerowalibyśmy "alter table Foo add Bar ..." i uruchomimy ją. Podczas pisania pierwszej wersji programu, aby to zrobić, było sporo pracy, kiedy już to zrobiliśmy, było prawie zero konserwacji, aby utrzymać aktualny schemat DB. Konwersja została przeprowadzona w locie.

Należy zauważyć, że ten schemat nie obsługuje zmian w bazie danych, które wymagają zmiany wartości danych, na przykład w przypadku dodania nowej kolumny, która musi być początkowo zapełniona, wykonując pewne obliczenia na danych z innych tabel lub niektórych takich. Ale jeśli możesz wygenerować nowe dane ze starych danych, musi to oznaczać, że nowe dane są zbędne, a twoja baza danych nie jest znormalizowana. Nie sądzę, aby sytuacja nas zaskoczyła.

0

Miałem ten sam problem z aplikacją na Androida z bazą danych SQLite dodającą tabelę. Zmieniłem nazwę bazy danych, aby zawierało rozszerzenie wersji, takie jak: theDataBaseV1, usunięto poprzednią, a aplikacja działa poprawnie.

Właśnie zmienił nazwę bazy danych i nazwy w tej linii kodu

private static final String DATABASE_NAME = "busesBogotaV2.db"; 

w DBManager gdy jego zamiar otworzyć.

Czy ktoś wie, czy to trywialne rozwiązanie ma jakieś niezamierzone konsekwencje?

+0

W systemie Android, jeśli używasz [SQLiteOpenHelper] (http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html), ma on metodę, którą można przesłonić, aby pomóc w migracji bazy danych po aktualizacji i obniżeniu. –

+0

Tak, wiem, ale w moim przypadku nie mam wersji w bazie danych. Mam 10 000 pobrań ze zwykłą prostą db, jak mogę włączyć wersję? czy jest już wdrożona aplikacja? –

Powiązane problemy