#sql #postgresql #postgresql-9.1 #database-partitioning
#sql #postgresql #postgresql-9.1 #база данных -разбиение
Вопрос:
Я создал простую структуру разделов, как указано ниже:
Главная таблица
CREATE TABLE parent_table
(
id_n numeric(19,0) NOT NULL,
name_v character varying(255),
location_n numeric(19,0),
CONSTRAINT parent_table_pkey PRIMARY KEY (id_n )
)
Дочерние таблицы
CREATE TABLE child_table_location_1
(
-- Inherited from table parent_table: id_n numeric(19,0) NOT NULL,
-- Inherited from table parent_table: name_v character varying(255),
-- Inherited from table parent_table: location_n numeric(19,0),
CONSTRAINT child_table_location_1_pkey PRIMARY KEY (id_n ),
CONSTRAINT child_table_location_1_location_n_check CHECK (location_n = 1::numeric)
)INHERITS (parent_table)
CREATE TABLE child_table_location_2
(
-- Inherited from table parent_table: id_n numeric(19,0) NOT NULL,
-- Inherited from table parent_table: name_v character varying(255),
-- Inherited from table parent_table: location_n numeric(19,0),
CONSTRAINT child_table_location_2_pkey PRIMARY KEY (id_n ),
CONSTRAINT child_table_location_2_location_n_check CHECK (location_n = 2::numeric)
)INHERITS (parent_table)
Триггер
CREATE OR REPLACE FUNCTION PARTITION_INSERTION_TRIGGER()
RETURNS TRIGGER AS
$
BEGIN
EXECUTE 'INSERT INTO '|| QUOTE_IDENT('child_table_location_'||NEW.LOCATION_N)||' SELECT ($1).*' USING NEW;
RETURN NEW;
END;
$
LANGUAGE PLPGSQL;
CREATE TRIGGER INSERT_INTO_PARTITION_TRIGGER BEFORE INSERT ON PARENT_TABLE FOR EACH ROW EXECUTE PROCEDURE PARTITION_INSERTION_TRIGGER();
Я создаю триггер таким образом, чтобы на основе поля location данные заполнялись в соответствующих дочерних таблицах.
Теперь я использую следующие сценарии вставки:
INSERT INTO parent_table(id_n, name_v, location_n) VALUES (1, 'aaa', 1);
INSERT INTO parent_table(id_n, name_v, location_n) VALUES (2, 'bbb', 2);
INSERT INTO parent_table(id_n, name_v, location_n) VALUES (3, 'ccc', 1);
INSERT INTO parent_table(id_n, name_v, location_n) VALUES (4, 'ddd', 2);
INSERT INTO parent_table(id_n, name_v, location_n) VALUES (5, 'eee', 1);
INSERT INTO parent_table(id_n, name_v, location_n) VALUES (6, 'fff', 2);
Когда я выбираю из отдельных таблиц:
Дочерняя таблица 1
id_n| name_v| location_n
1|"aaa"|1
3|"ccc"|1
5|"eee"|1
Дочерняя таблица 2
id_n| name_v| location_n
2|"bbb"|2
4|"ddd"|2
6|"fff"|2
Но когда я запрашиваю в главной таблице:
Родительская таблица
id_n|name_v|location_n
1|"aaa"|1
1|"aaa"|1
2|"bbb"|2
2|"bbb"|2
3|"ccc"|1
3|"ccc"|1
4|"ddd"|2
4|"ddd"|2
5|"eee"|1
5|"eee"|1
6|"fff"|2
6|"fff"|2
Я получаю повторяющиеся записи из родительской таблицы даже после ограничения первичного ключа в поле id.
Почему это происходит и какие изменения я должен внести в свой дизайн.
Ожидание быстрого ответа.
Заранее спасибо.
Комментарии:
1. Привет всем, решаемая путем изменения функции PARTITION_INSERTION_TRIGGER . Вместо возврата НОВОГО возвращено значение NULL 🙂
Ответ №1:
Возврат NULL не является чистым способом.
Элегантное решение — использовать триггер «ВМЕСТО»
См.: http://www.postgresql.org/docs/9.3/static/sql-createtrigger.html
Комментарии:
1.
instead of
работает только с представлениями и поэтому не применяется при использовании разделения таблиц