Logika biznesowa w bazie danych przy użyciu SchemaKeepera

Celem tego artykułu jest wykorzystanie przykładu biblioteki opiekun schematu pokaż narzędzia, które mogą znacznie uprościć proces tworzenia baz danych w projektach PHP z wykorzystaniem systemu PostgreSQL DBMS.

Informacje zawarte w tym artykule przydadzą się przede wszystkim programistom, którzy chcą maksymalnie wykorzystać możliwości PostgreSQL, ale borykają się z problemami w utrzymaniu logiki biznesowej umieszczonej w bazie danych.

W tym artykule nie będziemy opisywać zalet ani wad przechowywania logiki biznesowej w bazie danych. Zakłada się, że wybór został już dokonany przez czytelnika.

Rozważane będą następujące pytania:

  1. W jakiej formie powinien być przechowywany zrzut struktury bazy danych w systemie kontroli wersji (zwanym dalej VCS)
  2. Jak śledzić zmiany w strukturze bazy danych po zapisaniu zrzutu
  3. Jak przenieść zmiany w strukturze bazy danych na inne środowiska bez konfliktów i gigantycznych plików migracyjnych
  4. Jak zorganizować proces równoległej pracy nad projektem przez kilku programistów
  5. Jak bezpiecznie wdrożyć więcej zmian w strukturze bazy danych w środowisku produkcyjnym

    Opiekun schematu przeznaczony do pracy z procedurami składowanymi napisanymi w tym języku PL / pgSQL. Nie przeprowadzono testów z innymi językami, więc użycie może nie być tak skuteczne lub może nie być możliwe.

Jak przechowywać zrzut struktury bazy danych w VCS

biblioteka opiekun schematu zapewnia funkcję saveDump, który zapisuje strukturę wszystkich obiektów z bazy danych jako osobne pliki tekstowe. Wynikiem jest katalog zawierający strukturę bazy danych, podzieloną na pogrupowane pliki, które można łatwo dodać do VCS.

Przyjrzyjmy się konwersji obiektów z bazy danych na pliki na kilku przykładach:

Typ объекта
Schemat
Nazwa
Względna ścieżka do pliku

stół
publiczny
Rachunki
./public/tables/accounts.txt

Procedura składowana
publiczny
uwierzytelnianie (hash bigint)
./public/functions/auth(int8).sql

Wprowadzenie
Rezerwacja
Taryf
./booking/views/tariffs.txt

Zawartość plików stanowi tekstową reprezentację struktury konkretnego obiektu bazy danych. Na przykład w przypadku procedur składowanych zawartość pliku będzie pełną definicją procedury składowanej, zaczynając od bloku CREATE OR REPLACE FUNCTION.

Jak widać z powyższej tabeli, w ścieżce do pliku znajdują się informacje o typie, schemacie i nazwie obiektu. Takie podejście ułatwia nawigację po zrzucie i przeglądzie kodu zmian w bazie danych.

rozbudowa .sql w przypadku plików z kodem źródłowym procedury składowanej tę opcję wybrano tak, aby IDE automatycznie udostępniało narzędzia do interakcji z bazą danych po otwarciu pliku.

Jak śledzić zmiany w strukturze bazy danych po zapisaniu zrzutu

Zapisując w VCS zrzut aktualnej struktury bazy danych, uzyskujemy możliwość sprawdzenia, czy po utworzeniu zrzutu zaszły zmiany w strukturze bazy danych. W bibliotece opiekun schematu do wykrywania zmian w strukturze bazy danych dostępna jest funkcja verifyDump, która zwraca informację o różnicach bez skutków ubocznych.

Alternatywnym sposobem sprawdzenia jest ponowne wywołanie funkcji saveDump, określając ten sam katalog i sprawdź w VCS pod kątem zmian. Ponieważ wszystkie obiekty z bazy danych są zapisywane w oddzielnych plikach, VCS pokaże tylko zmienione obiekty.
Główną wadą tej metody jest konieczność nadpisywania plików, aby zobaczyć zmiany.

Jak przenieść zmiany w strukturze bazy danych na inne środowiska bez konfliktów i gigantycznych plików migracyjnych

Dzięki funkcji deployDump Kod źródłowy procedur składowanych można edytować dokładnie w taki sam sposób, jak zwykły kod źródłowy aplikacji. Możesz dodawać/usuwać nowe wiersze w kodzie procedury składowanej i natychmiast przekazywać zmiany do kontroli wersji lub tworzyć/usuwać procedury składowane, tworząc/usuwając odpowiednie pliki w katalogu zrzutów.

Na przykład, aby utworzyć nową procedurę składowaną w schemacie public po prostu utwórz nowy plik z rozszerzeniem .sql w katalogu public/functions, umieść w nim kod źródłowy procedury składowanej, łącznie z blokiem CREATE OR REPLACE FUNCTION, a następnie wywołaj funkcję deployDump. Modyfikowanie i usuwanie procedury składowanej odbywa się w ten sam sposób. W ten sposób kod trafia jednocześnie do VCS i bazy danych.

Jeśli w kodzie źródłowym jakiejkolwiek procedury składowanej pojawi się błąd lub rozbieżność pomiędzy nazwami pliku i procedurą składowaną, wówczas deployDump zakończy się niepowodzeniem, wyświetlając tekst błędu. Niedopasowanie procedur składowanych między zrzutem a bieżącą bazą danych jest niemożliwe podczas używania deployDump.

Podczas tworzenia nowej procedury składowanej nie ma potrzeby ręcznego wprowadzania prawidłowej nazwy pliku. Wystarczy, że plik będzie miał rozszerzenie .sql. Po rozmowie deployDump tekst błędu będzie zawierał poprawną nazwę, której można użyć do zmiany nazwy pliku.

deployDump pozwala na zmianę parametrów funkcji lub typu zwracanego bez dodatkowych działań, podczas gdy w przypadku klasycznego podejścia byłoby to konieczne
wykonaj najpierw DROP FUNCTION, ale tylko wtedy CREATE OR REPLACE FUNCTION.

Niestety, zdarzają się sytuacje, w których deployDump nie można automatycznie zastosować zmian. Na przykład, jeśli funkcja wyzwalacza używana przez co najmniej jeden wyzwalacz zostanie usunięta. Takie sytuacje są rozwiązywane ręcznie za pomocą plików migracji.

Jeśli jesteś odpowiedzialny za migrację zmian do procedur przechowywanych opiekun schematu, wówczas należy użyć plików migracyjnych, aby przenieść inne zmiany w konstrukcji. Na przykład dobrą biblioteką do pracy z migracjami jest doktryna/migracje.

Migracje należy zastosować przed uruchomieniem deployDump. Pozwala to na dokonanie wszelkich zmian w strukturze i rozwiązanie problematycznych sytuacji, dzięki czemu zmiany w procedurach składowanych zostaną później przeniesione bez problemów.

Praca z migracjami zostanie opisana bardziej szczegółowo w kolejnych sekcjach.

Jak zorganizować proces równoległej pracy nad projektem przez kilku programistów

Konieczne jest utworzenie skryptu pełnej inicjalizacji bazy danych, który zostanie uruchomiony przez programistę na jego komputerze roboczym, dostosowujący strukturę lokalnej bazy danych do zrzutu zapisanego w VCS. Najłatwiej jest podzielić inicjalizację lokalnej bazy danych na 3 kroki:

  1. Zaimportuj plik o podstawowej strukturze, który będzie nosił nazwę np. base.sql
  2. Stosowanie migracji
  3. Zadzwoń deployDump

base.sql jest punktem wyjścia, od którego stosowane i wykonywane są migracje deployDumpOznacza to, że base.sql + миграции + deployDump = актуальная структура БД. Możesz utworzyć taki plik za pomocą narzędzia pg_dump. używany base.sql wyłącznie podczas inicjowania bazy danych od zera.

Wywołajmy skrypt w celu pełnej inicjalizacji bazy danych refresh.sh. Przepływ pracy może wyglądać następująco:

  1. Deweloper uruchamia się w swoim środowisku refresh.sh i pobiera bieżącą strukturę bazy danych
  2. Programista przystępuje do pracy nad postawionym zadaniem, modyfikując lokalną bazę danych na potrzeby nowej funkcjonalności (ALTER TABLE ... ADD COLUMN itp)
  3. Po wykonaniu zadania programista wywołuje funkcję saveDumpaby zatwierdzić zmiany wprowadzone w bazie danych w VCS
  4. Ponowne uruchomienie dewelopera refresh.sh, a następnie verifyDumpktóry teraz pokazuje listę zmian, które należy uwzględnić w migracji
  5. Programista przenosi wszystkie zmiany struktury do pliku migracji i uruchamia się ponownie refresh.sh и verifyDump, a jeśli migracja zostanie poprawnie skompilowana, verifyDump nie pokaże żadnych różnic pomiędzy lokalną bazą danych a zapisanym zrzutem

Opisany powyżej proces jest zgodny z zasadami gitflow. Każda gałąź w VCS będzie zawierać własną wersję zrzutu, a podczas łączenia gałęzi zrzuty zostaną scalone. W większości przypadków po fuzji nie trzeba podejmować żadnych dodatkowych działań, jednak jeśli zmiany zostaną wprowadzone w różnych gałęziach, na przykład w tej samej tabeli, może pojawić się konflikt.

Rozważmy sytuację konfliktową na przykładzie: istnieje oddział rozwijać, z którego odchodzą dwie gałęzie: feature1 и feature2, z którymi nie ma konfliktu rozwijać, ale popadają w konflikty między sobą. Zadanie polega na połączeniu obu gałęzi w rozwijać. W takim przypadku zaleca się najpierw połączyć jedną z gałęzi rozwijaća następnie połączyć rozwijać do pozostałej gałęzi, rozwiązując konflikty w pozostałej gałęzi, a następnie łącząc ostatnią gałąź rozwijać. W fazie rozwiązywania konfliktów może być konieczne naprawienie pliku migracji w ostatniej gałęzi, tak aby pasował do ostatecznego zrzutu, który zawiera wyniki scalania.

Jak bezpiecznie wdrożyć więcej zmian w strukturze bazy danych w środowisku produkcyjnym

Dzięki obecności zrzutu aktualnej struktury bazy danych w VCS możliwe staje się sprawdzenie produkcyjnej bazy danych pod kątem dokładnej zgodności z wymaganą strukturą. Dzięki temu wszystkie zmiany zamierzone przez twórców zostały pomyślnie przeniesione do bazy produkcyjnej.

ponieważ DDL w PostgreSQL jest transakcyjne, zaleca się zachować następującą kolejność wdrażania, aby w przypadku nieoczekiwanego błędu można było „bezboleśnie” wykonać ROLLBACK:

  1. Rozpocznij transakcję
  2. Wykonaj wszystkie migracje w transakcji
  3. W tej samej transakcji wykonaj deployDump
  4. Nie kończąc transakcji, wykonaj verifyDump. Jeśli nie ma błędów, uruchom COMMIT. Jeśli występują błędy, uruchom ROLLBACK

Kroki te można łatwo zintegrować z istniejącymi podejściami do wdrażania aplikacji, w tym z zerowym przestojem.

wniosek

Dzięki opisanym powyżej metodom możliwe jest wyciśnięcie maksymalnej wydajności z projektów „PHP + PostgreSQL”, poświęcając przy tym stosunkowo niewielką wygodę programowania w porównaniu z implementacją całej logiki biznesowej w głównym kodzie aplikacji. Ponadto przetwarzanie danych w PL / pgSQL często wygląda bardziej przejrzyście i wymaga mniej kodu niż ta sama funkcjonalność napisana w PHP.

Źródło: www.habr.com

Dodaj komentarz