Doporučil bych vyhledat informace na e-mailových konferencích PostgreSQL o designu pro více nájemců. Bylo tam hodně diskuzí a odpověď se scvrkává na „záleží“. Mezi zaručenou izolací, výkonem a udržovatelností existují kompromisy ve všech směrech.
Běžným přístupem je použití jedné databáze, ale jednoho schéma (namespace) na zákazníka se stejnou strukturou tabulky v každém schématu a navíc sdíleným nebo společným schématem pro data, která jsou ve všech stejná. Schéma PostgreSQL je jako "databáze" MySQL v tom, že můžete dotazovat přes různá schémata, ale ta jsou ve výchozím nastavení izolovaná. S údaji o zákaznících v samostatném schématu můžete použít search_path
nastavení, obvykle prostřednictvím ALTER USER
customername SET search_path = 'customerschema, sharedschema'
aby každý zákazník viděl svá data a pouze svá data.
Pro další ochranu byste měli REVOKE
ALL FROM SCHEMA customerschema FROM public
pak GRANT
ALL ON SCHEMA customerschema TO thecustomer
takže jsou jediní, kdo k němu má jakýkoli přístup, a totéž dělají s každým ze svých stolů. Váš fond připojení se pak může přihlásit pomocí pevného uživatelského účtu, který má ne GRANT
ed přístup k jakémukoli zákaznickému schématu, ale má právo na SET ROLE
stát se jakýmkoli zákazníkem. (Udělejte to tak, že jim poskytnete členství v každé zákaznické roli s nastaveným NOINHERIT, takže práva musí být explicitně nárokována prostřednictvím SET ROLE
). Připojení by mělo okamžitě SET ROLE
zákazníkovi, jako v současnosti působí. To vám umožní vyhnout se režii vytváření nových připojení pro každého zákazníka a zároveň zachovat silnou ochranu proti chybám programátoru vedoucí k přístupu k nesprávným datům zákazníka. Pokud fond provede DISCARD ALL
a/nebo RESET ROLE
před předáním připojení dalšímu klientovi vám to poskytne velmi silnou izolaci bez frustrace jednotlivých připojení na uživatele.
Pokud vaše prostředí webové aplikace nemá vestavěný slušný fond připojení (řekněme, že používáte PHP s trvalými připojeními), pak skutečně potřeba umístit dobrý fond připojení
na místě mezi Pg a webovým serverem, protože příliš mnoho připojení k backendu poškodí váš výkon. PgBouncer
a PgPool-II
jsou nejlepší možnosti a mohou se snadno postarat o provedení DISCARD ALL
a RESET ROLE
pro vás během předávání připojení.
Hlavní nevýhodou tohoto přístupu je režie s údržbou tolika tabulek, protože vaše základní sada nesdílených tabulek je klonována pro každého zákazníka. S rostoucím počtem zákazníků se bude sčítat až do bodu, kdy se samotný počet tabulek ke kontrole během autovakuování začne prodražovat a kde se zpomalí jakákoli operace, která se škáluje na základě celkového počtu tabulek v DB. Toto je spíše problém, pokud uvažujete o mnoha tisících nebo desetitisících zákazníků ve stejné databázi, ale já silně doporučujeme, abyste s tímto návrhem provedli nějaké testy škálování pomocí fiktivních dat, než se do něj zapojíte.
Ideálním přístupem budou pravděpodobně jednotlivé tabulky s automatickým zabezpečením na úrovni řádků, které řídí viditelnost n-tic, ale to je bohužel něco, co PostgreSQL zatím nemá. Vypadá to, že je to na cestě díky práci SEPostgreSQL na přidání vhodné infrastruktury a API, ale není to ve verzi 9.1.