sql >> Database >  >> RDS >> PostgreSQL

in postgresql, zijn partities of meerdere databases efficiënter?

Ik raad aan om op de PostgreSQL-mailinglijsten te zoeken naar informatie over multi-tenanted design. Er is daar veel discussie geweest en het antwoord komt neer op "het hangt ervan af". Er zijn overal afwegingen tussen gegarandeerde isolatie, prestaties en onderhoudbaarheid.

Een gebruikelijke benadering is het gebruik van één enkele database, maar één schema (naamruimte) per klant met dezelfde tabelstructuur in elk schema, plus een gedeeld of gemeenschappelijk schema voor gegevens dat overal hetzelfde is. Een PostgreSQL-schema is als een MySQL-"database" in die zin dat u in verschillende schema's kunt zoeken, maar ze zijn standaard geïsoleerd. Met klantgegevens in een apart schema kunt u de zoekpad instelling, meestal via GEBRUIKER VERANDEREN klantnaam SET search_path ='klantschema, gedeeldschema' om ervoor te zorgen dat elke klant zijn gegevens ziet en alleen zijn gegevens.

Voor extra bescherming moet u REVOKE ALLES VAN SCHEMA klantschema VAN openbaar dan GRANT ALLES OP SCHEMA klantschema AAN de klant dus zij zijn de enige die er toegang toe hebben en doen hetzelfde met elk van hun tafels. Uw verbindingspool kan dan inloggen met een vast gebruikersaccount dat nee . heeft SUBSIDIE ed toegang tot elk klantschema, maar heeft het recht op ROL INSTELLEN om enige klant te worden. (Doe dat door ze lidmaatschap te geven van elke klantrol met NOINHERIT-set, zodat rechten expliciet moeten worden geclaimd via SET ROLE ). De verbinding moet onmiddellijk SET ROLE voor de klant waar het momenteel mee werkt. Zo vermijdt u de overhead van het maken van nieuwe verbindingen voor elke klant, terwijl u een sterke bescherming behoudt tegen programmeerfouten die leiden tot toegang tot de gegevens van de verkeerde klant. Zolang de pool een DISCARD ALL en/of een RESET ROL voordat u verbindingen uitdeelt aan de volgende klant, geeft dat u een zeer sterke isolatie zonder de frustratie van individuele verbindingen per gebruiker.

Als uw web-app-omgeving geen behoorlijke ingebouwde verbindingspool heeft (bijvoorbeeld, u gebruikt PHP met permanente verbindingen), dan echt moet een goede verbindingspool plaatsen tussen Pg en de webserver, omdat te veel verbindingen met de backend uw prestaties schaden. PgBouncer en PgPool-II zijn de beste opties, en kunnen handig zorgen voor het uitvoeren van de ALLES VERWIJDEREN en RESET ROL voor u tijdens de overdracht van de verbinding.

Het belangrijkste nadeel van deze aanpak is de overhead die gepaard gaat met het onderhouden van zoveel tabellen, aangezien uw basisset van niet-gedeelde tabellen voor elke klant wordt gekloond. Het zal oplopen naarmate het aantal klanten groeit, tot het punt waarop het enorme aantal tafels dat moet worden onderzocht tijdens autovacuüm-runs duur begint te worden en waar elke bewerking die wordt geschaald op basis van het totale aantal tabellen in de DB vertraagt. Dit is meer een probleem als u denkt vele duizenden of tienduizenden klanten in dezelfde database te hebben, maar ik sterk raad u aan een aantal schaaltests uit te voeren met dit ontwerp met behulp van dummy-gegevens voordat u zich eraan vastlegt.

De ideale aanpak zijn waarschijnlijk enkele tabellen met automatische beveiliging op rijniveau die de zichtbaarheid van tuple controleert, maar helaas heeft PostgreSQL dat nog niet. Het lijkt erop dat het onderweg is dankzij het SEPostgreSQL-werk door geschikte infrastructuur en API's toe te voegen, maar het is niet in 9.1.




  1. Index opnieuw opbouwen op InnoDB

  2. Een database maken in Cloud Sites

  3. de kolomnamen van de Oracle-tabel weergeven

  4. Alleen de aangrenzende rijen groeperen