История версий геоданных. нужны советы по Postgres+PostGIS
Добавлено: 22 июн 2009, 09:55
Идея такова.
Пусть у нас есть таблица с пространственными данными и одним аттрибутом (для простоты)
Тоесть имеем в постгресе таблицу с полями :
gid serial PRIMARY KEY,
"№" varchar(128),
'the_geom'
все это может быть запихнуто в ПГ при помощи shp2pgsql из шейпфайла, главное что опишу на примере этих полей. вообще поля естественно будут ваши, с вашего shp файла.
Нам нужно создать в ПГ дополнительный счетчик, который будет задействован для определения уникальности объекта или группы объектов, сделаем так
CREATE SEQUENCE thenameofmytable_nuid START 1;
И добавим к этим полям
"the_pid" int4 DEFAULT nextval('thenameofmytable_nuid'), - наш неуникальный идентификатор для объекта
"the_login" text DEFAULT user, - кто создал запись
"the_time" timestamp without time zone DEFAULT now(), - время создания (изменения) записи
далее
создаем вид
CREATE OR REPLACE VIEW "thenameofmytable_ptv" AS
SELECT gid, "№", the_pid, the_geom
FROM "thenameofmytable";
назначаем собственника оригинальной таблицы (для опытов - необязательно, наверное)
ALTER TABLE "thenameofmytable" OWNER TO postgres;
правило чтения из таблицы
CREATE OR REPLACE RULE "_RETURN"AS ON SELECT TO "thenameofmytable_ptv" DO INSTEAD
SELECT gid, "№", the_pid, the_geom
FROM "thenameofmytable"
WHERE (the_pid, the_time) IN ( SELECT the_pid, max(the_time) FROM "thenameofmytable" GROUP BY the_pid);
тоесть вернутся по запросу только самые новые (по полю времени) из групп собранных по the_pid
правило добавления записи в таблицу
CREATE OR REPLACE RULE "_INSERT"AS ON INSERT TO "thenameofmytable_ptv" DO INSTEAD
INSERT INTO "thenameofmytable" ( "№", the_geom, the_pid, the_login, the_time)
VALUES ( new."№", new.the_geom, nextval('thenameofmytable_nuid'), user, CURRENT_TIMESTAMP);
новой записи - новый неуникальный идентификатор. туда же имя создателя, и текущее время.
правило на изменение данных
CREATE OR REPLACE RULE "_UPDATE"AS ON UPDATE TO "thenameofmytable_ptv" DO INSTEAD
INSERT INTO "thenameofmytable" ( "№", the_geom, the_pid, the_login, the_time)
VALUES (new."№", new.the_geom, old.the_pid, user, CURRENT_TIMESTAMP);
вместо изменения - создаем запись с новыми данными но старым неуникальным идентификатором.
правило на удаление. пока не проработано. делает "лишь бы что-то", но чтобы можно было отличить удаленные записи.
CREATE OR REPLACE RULE "_DELETE"AS ON DELETE TO "thenameofmytable_ptv" DO INSTEAD
INSERT INTO "thenameofmytable" ( "№", old.the_geom, old.the_pid, 'object.deleted', CURRENT_TIMESTAMP);
собственно заготовка. создает копию записи со старыми данными но имя пользователя меняет на 'object.deleted'
квантум у пользователя работает с этим видом.
У кого какие мысли возникают?
Цель - получить таблицу и карту, состояние которой можно определить на любой момент времени.
Идей насчет удаления две :
1) удаление реально удаляет запись. если у этого геообъекта есть история, автоматом появится предыдущая запись вместо этой.
2) устанавливается флаг "удален", объект исчезает с карты (нужно наверное переписать запрос _RETURN
3) полностью удаляется объект со всей историей. но это наверное зверство, и лишнее.
Также есть подозрение что запрос _RETURN неоптимален.
Пусть у нас есть таблица с пространственными данными и одним аттрибутом (для простоты)
Тоесть имеем в постгресе таблицу с полями :
gid serial PRIMARY KEY,
"№" varchar(128),
'the_geom'
все это может быть запихнуто в ПГ при помощи shp2pgsql из шейпфайла, главное что опишу на примере этих полей. вообще поля естественно будут ваши, с вашего shp файла.
Нам нужно создать в ПГ дополнительный счетчик, который будет задействован для определения уникальности объекта или группы объектов, сделаем так
CREATE SEQUENCE thenameofmytable_nuid START 1;
И добавим к этим полям
"the_pid" int4 DEFAULT nextval('thenameofmytable_nuid'), - наш неуникальный идентификатор для объекта
"the_login" text DEFAULT user, - кто создал запись
"the_time" timestamp without time zone DEFAULT now(), - время создания (изменения) записи
далее
создаем вид
CREATE OR REPLACE VIEW "thenameofmytable_ptv" AS
SELECT gid, "№", the_pid, the_geom
FROM "thenameofmytable";
назначаем собственника оригинальной таблицы (для опытов - необязательно, наверное)
ALTER TABLE "thenameofmytable" OWNER TO postgres;
правило чтения из таблицы
CREATE OR REPLACE RULE "_RETURN"AS ON SELECT TO "thenameofmytable_ptv" DO INSTEAD
SELECT gid, "№", the_pid, the_geom
FROM "thenameofmytable"
WHERE (the_pid, the_time) IN ( SELECT the_pid, max(the_time) FROM "thenameofmytable" GROUP BY the_pid);
тоесть вернутся по запросу только самые новые (по полю времени) из групп собранных по the_pid
правило добавления записи в таблицу
CREATE OR REPLACE RULE "_INSERT"AS ON INSERT TO "thenameofmytable_ptv" DO INSTEAD
INSERT INTO "thenameofmytable" ( "№", the_geom, the_pid, the_login, the_time)
VALUES ( new."№", new.the_geom, nextval('thenameofmytable_nuid'), user, CURRENT_TIMESTAMP);
новой записи - новый неуникальный идентификатор. туда же имя создателя, и текущее время.
правило на изменение данных
CREATE OR REPLACE RULE "_UPDATE"AS ON UPDATE TO "thenameofmytable_ptv" DO INSTEAD
INSERT INTO "thenameofmytable" ( "№", the_geom, the_pid, the_login, the_time)
VALUES (new."№", new.the_geom, old.the_pid, user, CURRENT_TIMESTAMP);
вместо изменения - создаем запись с новыми данными но старым неуникальным идентификатором.
правило на удаление. пока не проработано. делает "лишь бы что-то", но чтобы можно было отличить удаленные записи.
CREATE OR REPLACE RULE "_DELETE"AS ON DELETE TO "thenameofmytable_ptv" DO INSTEAD
INSERT INTO "thenameofmytable" ( "№", old.the_geom, old.the_pid, 'object.deleted', CURRENT_TIMESTAMP);
собственно заготовка. создает копию записи со старыми данными но имя пользователя меняет на 'object.deleted'
квантум у пользователя работает с этим видом.
У кого какие мысли возникают?
Цель - получить таблицу и карту, состояние которой можно определить на любой момент времени.
Идей насчет удаления две :
1) удаление реально удаляет запись. если у этого геообъекта есть история, автоматом появится предыдущая запись вместо этой.
2) устанавливается флаг "удален", объект исчезает с карты (нужно наверное переписать запрос _RETURN
3) полностью удаляется объект со всей историей. но это наверное зверство, и лишнее.
Также есть подозрение что запрос _RETURN неоптимален.