Zacznę od tego że niestety pomyliłem się co do opcji WITH CHECK OPTION, niestety w postgresql 9.3 nadal nie działa (lub może trzeba ją jakoś włączyć (ale wątpię) klauzula taka jest bardzo przydatna gdyż dokonuje dla widoku aktualizacji tylko wtedy gdy widok wyświetli modyfikowany/dodawany rekord. Opis trochę pokrętny więc opisze to tak:
Gdy wykonujesz na widoku insert lub update widok sprawdza czy dane w rekordzie spełniają warunki w where jeśli tak to dokonuje zmiany wartości lub dodania rekordu w przeciwnym wypadku zgłasza błąd (fajne jest to że może sprawdzać warunki tylko dla konkretnego widoku opcja with local check option lub też dla widoków od niego zależnych opcja with cascade check option).
Co do twojego przypadku to twoje myślenie o tabelach dziedziczonych jest jak najbardziej OK tyle, że jeśli masz w każdej z tabel po 10000 rekordów (czyli tyle co nic) to strasznie utrudniasz sobie sprawę (ale nie zrozum tego źle, jak przerobisz sobie skrypt na tabele dziedziczone tez będzie OK) poniżej załączam mały przykład (będzie działał pod warunkiem, że nie pracujesz na użytkowniku postgres ale z prawami superusera.
Założenie jest jedno mam jedną tabele i jeden widok wiec w kliencie bazy danych nie muszę budować 5 insertów/updat-ów w zależności od tego kto się zaloguje do bazy
create table t_user_warstwa(
user_name name not null
,warstwa integer not null check (warstwa > 0 and warstwa <=5)
,CONSTRAINT t_user_warstwa_pkey PRIMARY KEY (user_name,warstwa)
);
create table t_warstwa_dane(
id serial primary key
,warstwa integer not null check (warstwa > 0 and warstwa <=5)
,wartosc integer);
create or replace view v_warstwa_dane
as
select d.* from t_warstwa_dane d where exists (select 1 from t_user_warstwa uw where uw.user_name=current_user and uw.warstwa=d.warstwa);
CREATE OR REPLACE RULE "_INSERT" AS
ON INSERT TO v_warstwa_dane
DO INSTEAD insert into t_warstwa_dane (warstwa,wartosc) values ((select warstwa from t_user_warstwa where user_name = current_user and warstwa=new.warstwa),new.wartosc) returning *;
CREATE OR REPLACE RULE "_UPDATE" AS
ON UPDATE TO v_warstwa_dane
DO INSTEAD update t_warstwa_dane set warstwa=(select warstwa from t_user_warstwa where user_name = current_user and warstwa=new.warstwa),wartosc=new.wartosc where id=old.id returning *;
CREATE OR REPLACE RULE "_DELETE" AS
ON DELETE TO v_warstwa_dane
DO INSTEAD DELETE from t_warstwa_dane where warstwa=(select warstwa from t_user_warstwa where user_name = current_user and warstwa=old.warstwa) and id=old.id returning *;
insert into t_user_warstwa values(current_user,1);
insert into t_user_warstwa values('postgres',2);
a tu sprawdź sobie jak to rozwiązanie działa
insert into v_warstwa_dane (warstwa,wartosc) values (1,-1);
insert into v_warstwa_dane (warstwa,wartosc) values (2,-2);
update v_warstwa_dane set wartosc=-2 where warstwa=1 returning *
update v_warstwa_dane set wartosc=-3 where warstwa=2 returning *
delete from v_warstwa_dane where warstwa=2 returning *
delete from v_warstwa_dane where warstwa=1 returning *