2011-12-08 9 views
5

mają aplikację, w której wiele firm zamieszcza informacje. dane z każdej firmy są niezależne - nie zachodzą na siebie dane.w postgresql, czy partycje lub wiele baz danych jest bardziej wydajne?

wydajność mądry, to lepiej:

  • przechowywać identyfikator firmy w każdym wierszu każdej tabeli i nie każdy indeks go używać?
  • partycji każda tabela zgodnie z identyfikatorem firmy
  • partycji i utworzyć użytkownika, aby uzyskać dostęp do każdej spółki w celu zapewnienia bezpieczeństwa
  • utworzyć wiele baz danych, po jednym dla każdej ze spółek

aplikacji internetowych opartych o trwałych połączeń .

moje myśli:

  • nowe połączenia pg są drogie, więc pojedyncza baza danych tworzy mniej nowych połączeń
  • posiadające tylko jedną kopię słownika wydaje się bardziej skuteczny niż 200 lub tak
  • wielu baz danych na pewno bezpieczniej od błędu programisty
  • jeśli specyfikacje aplikacji powinny się zmienić, więc firmy będą udostępniać, wiele danych baza byłaby trudna do wdrożenia

Odpowiedz

14

Polecam wyszukiwanie informacji na listach mailingowych PostgreSQL o projektowaniu z wieloma dzierżawionymi. Było dużo dyskusji, a odpowiedź sprowadza się do "to zależy". Istnieją wzajemne kompromisy między gwarancją izolacji, wydajności i łatwości konserwacji.

Powszechnie stosuje się jedną bazę danych, ale jedną schema (przestrzeń nazw) na klienta o tej samej strukturze tabeli w każdym schemacie oraz wspólny lub wspólny schemat dla danych, które są takie same dla wszystkich z nich. Schemat PostgreSQL jest jak "baza danych" MySQL, w której można wyszukiwać w różnych schematach, ale są one domyślnie izolowane. Z danymi klienta w osobnym schemacie można korzystać z ustawienia search_path, zwykle za pośrednictwem ALTER USERcustomername SET search_path = 'customerschema, sharedschema', aby zapewnić każdemu klientowi dostęp do jego danych i tylko ich danych.

Dla dodatkowej ochrony, należy REVOKEALL FROM SCHEMA customerschema FROM public następnie GRANTALL ON SCHEMA customerschema TO thecustomer więc jesteś jedynym z jakiegokolwiek dostępu do niej, robiąc to samo z każdym ze swoich stołów. Pula połączeń może następnie zalogować się przy użyciu stałego konta użytkownika, które ma dostęp do dowolnego schematu klienta, ale ma prawo do tego, aby SET ROLE stał się dowolnym klientem. (Zrób to, przypisując im przynależność do każdej roli klienta za pomocą zestawu NOINHERIT, aby prawa były jawnie zgłaszane za pośrednictwem SET ROLE). Połączenie powinno od razu SET ROLE do klienta, który obecnie działa. Umożliwi to uniknięcie kosztów związanych z tworzeniem nowych połączeń dla każdego klienta przy jednoczesnym zachowaniu silnej ochrony przed błędem programisty prowadzącym do uzyskania dostępu do nieprawidłowych danych klienta. Dopóki pula wykonuje DISCARD ALL i/lub RESET ROLE przed przekazaniem połączeń do następnego klienta, da to bardzo silną izolację bez frustracji indywidualnych połączeń dla poszczególnych użytkowników.

Jeśli Web App środowisko nie posiada basen przyzwoity połączenia wbudowanej (powiedzmy, że używasz PHP z trwałych połączeń), to naprawdę należy umieścić w miejscu pomiędzy good connection pool PG i serwera WWW w każdym razie, ponieważ zbyt wiele połączeń z backendem zaszkodzi twojej wydajności. PgBouncer i PgPool-II są najlepszymi opcjami i mogą poradzić sobie z wykonywaniem DISCARD ALL i RESET ROLE dla Ciebie w trakcie przekazywania połączenia.

Główną wadą tego podejścia jest obciążenie związane z utrzymaniem wielu tabel, ponieważ Twój podstawowy zestaw niepodzielnych tabel jest klonowany dla każdego klienta. Będzie się to sumowało, gdy liczba klientów rośnie, do tego stopnia, że ​​sama liczba tabel do zbadania podczas automatycznego pobierania zaczyna być kosztowna, a każda operacja, która skaluje się w oparciu o całkowitą liczbę tabel w DB, zwalnia. Jest to poważniejszy problem, jeśli myślisz o tym, że masz wiele tysięcy lub dziesiątek tysięcy klientów w tym samym DB, ale zdecydowaniezalecam wykonanie pewnych testów skalowania za pomocą tego projektu przy użyciu fikcyjnych danych przed zatwierdzeniem.

Idealne podejście to prawdopodobnie pojedyncze tabele z automatyczną kontrolą poziomu kontroli na poziomie wiersza, ale niestety jest to coś, czego PostgreSQL jeszcze nie ma. Wygląda na to, że jest w drodze dzięki pracy w systemie SEPostgreSQL, która zapewnia odpowiednią infrastrukturę i interfejsy API, ale nie ma go w wersji 9.1.

+0

wielkie dzięki! (przykro mi, pracowałem ostatnio z MySQL i spowodowało to, że mój mózg nie żyje). Schemat powinien być opcją w wielu bazach danych - w rzeczywistości używano tego w innych projektach. świetny pomysł na ustawienie roli po połączeniu. używasz ustawionej ścieżki, ale najlepsze jest połączenie dwóch. –

+0

Tak, ustawienie roli pozwala używać zabezpieczeń na poziomie bazy danych bez zbytniego bólu. Wspaniale. –

+0

... i pamiętaj, aby użyć porządnej puli połączeń, takiej jak PgPool-II lub PgBouncer, jeśli używasz czegoś pierwotnego po stronie serwera WWW, takiego jak PHP z trwałymi połączeniami. Nie ma takiej potrzeby, jeśli używasz czegoś takiego jak serwer aplikacji Java, który ma własne buforowanie połączeń na serwerze. –

Powiązane problemy