My web app has multiple deployments -- each is a unique site with a unique URL.
Each deployment has different data, UI, etc. but a very similar Postgresql database structure
Yes, schemas are the solution. Use a single PostgreSQL cluster, with a single database.
Create a group for all of app users:
CREATE ROLE app;
Create global "app" schema, where all global shared applications tables will live.
CREATE SCHEMA AUTHORIZATION app;
CREATE TABLE app.objects ( objectid int PRIMARY KEY );
ALTER TABLE app.objects OWNER TO app;
Create separate user (with no superuser rights) for each of deployments:
CREATE USER app01 IN ROLE app;
CREATE USER app02 IN ROLE app;
Optionally, instead of IN ROLE app
, you can grant explicit rights for these users on selected app objects:
GRANT USAGE ON SCHEMA app TO app01;
GRANT SELECT on app.objects TO app01;
Create private schemas, where deployment-dependent tables will live:
CREATE SCHEMA AUTHORIZATION app01;
CREATE SCHEMA AUTHORIZATION app02;
Now you have a private schema for every application deployed; but at the same time you have shared access to global data.
What's nice, is that application does not have to be schema-aware. SELECT * FROM froobles
will by default resolve to SELECT * FROM app01.froobles
, if you are connected as app01
user. You do not have to specify schema name.
As an extra measure, you can use table inheritance to extend global objects on per-deployment basis:
CREATE TABLE app01.objects (
localattr1 int,
localattr2 text
)
INHERITS ( app.objects );