powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Использование record в CHECK constarint
42 сообщений из 42, показаны все 2 страниц
Использование record в CHECK constarint
    #38556097
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне нужно при вставке для секционированной таблицы проверять соответствует ли запись определенным критериям - для этого я создал функцию в которой в качестве входного параметра является record.

У меня возникает вопрос - как передать текущую запись в данную функцию в выражении CHECK?
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556128
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
или таки использование функций в выражении CHECK для секционированных таблиц - это плохо?
Но тогда как разбивать по различным полям, к примеру:
- хочется секционировать по номерам документов что бы все документы с номерами, начинающимися с 1 попадали в одну секцию, начинающиеся с 2 - в другую и т.д.

ну и куча других примеров найдется
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556156
Фотография SmeL_md
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
секционированние
это что Partitioning (патрицирование) ? если да то check на каждую таблицу + триггер BEFORE INSERT в котором и определяем в какую таблицу писать данные
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556160
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SmeL_md,

с триггерами проблем нет - есть вопрос по CHECK
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556173
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spSmeL_md,

с триггерами проблем нет - есть вопрос по CHECKвы можете передать туда рекорд как ROW-конструктор (см RTFM) (попросту -- перечислением всех полей записи в скобках. можно даже с полседующим кастом к типу).


Код: plsql
1.
F( (a,b,c,d)::mytable )



хотя, вас наверное интересует, как его передать не перечисляя поля [:0]
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556184
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

да, вы правильно поняли - надо чтоб запись целиком без перечисления полей, но данный вопрос наверно отходит на другой план - по такому CHECK движок не сможет строить эффективные планы т.к. результат функции заранее не известен...
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556690
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spМне нужно при вставке для секционированной таблицы проверять соответствует ли запись определенным критериям - для этого я создал функцию в которой в качестве входного параметра является record.

У меня возникает вопрос - как передать текущую запись в данную функцию в выражении CHECK?
Код: sql
1.
2.
ОШИБКА: функции PL/pgSQL не могут принимать тип record
SQL-состояние: 0A000


колитесь, что вы там передаёте
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556695
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE OR REPLACE FUNCTION f_test_reord(f test)
  RETURNS boolean AS
$BODY$BEGIN
	RETURN FALSE;
END;$BODY$
  LANGUAGE plpgsql immutable
  COST 100;
-----------------------
ALTER TABLE test
  ADD CHECK (f_test_reord(test));
------------------------
INSERT INTO test VALUE (7, sadasdasdaasdasdasdas);
---------------------------
ОШИБКА: новая строка в отношении "test" нарушает ограничение-проверку "test_check"
SQL-состояние: 23514
Подробности: Ошибочная строка содержит (7, sadasdasdaasdasdasdas).


ЗЫ
Код: sql
1.
2.
3.
--вариант ddl, отображаемый пж-одмином
ALTER TABLE test
  ADD CONSTRAINT test_check CHECK (f_test_reord(test.*));




PS если ф-я иммутабл - можете строить индекс.
(и для выделения партиции при планировании тоже может сгодиться, если в where будет та же ф-я.)
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556766
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

спасибо большое!
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556777
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
возникла очередная проблема с секционированием:
имеем текстовое поле ContractNo. по нему настроено секционирование и проверка в секциях выглядит так
Код: plsql
1.
2.
3.
4.
partition1 -  CHECK ( ContractNo::int <= 100 )
partition2 -  CHECK ( ContractNo::int <= 200 )
...
partitionN -  CHECK ( ContractNo::int <= N*100 )



вставил случайные данные в разные секции от 1 до 500
Пытаюсь делать выборку

Код: plsql
1.
2.
set constraint_exclusion = on;
select * from documents where ContractNo::int > 100 and ContractNo::int < 300



в плане вижу что идет сканирование всех секций вместо 1й, 2й и 3й

Почему мой where не использует constraint_exclusion?
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556827
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spвозникла очередная проблема с секционированием:
имеем текстовое поле ContractNo. по нему настроено секционирование и проверка в секциях выглядит так
Код: plsql
1.
2.
3.
4.
partition1 -  CHECK ( ContractNo::int <= 100 AND  ContractNo::int > 0 )
partition2 -  CHECK ( ContractNo::int <= 200  AND  ContractNo::int >100 )
...
partitionN -  CHECK ( ContractNo::int <= N*100  AND ContractNo::int > 100*(N-1) )



вставил случайные данные в разные секции от 1 до 500
Пытаюсь делать выборку

Код: plsql
1.
2.
set constraint_exclusion = on;
select * from documents where ContractNo::int > 100 and ContractNo::int < 300



в плане вижу что идет сканирование всех секций вместо 1й, 2й и 3й

Почему мой where не использует constraint_exclusion?
а вы дайте ему эту возможность, тогда и спрашивайте
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556872
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

по вашему настоянию - дал :)
но результат прежний (
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556891
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
Subquery Scan on documents  (cost=1.55..149.56 rows=2 width=72) (actual time=0.057..0.067 rows=3 loops=1)
  Output: documents.id, documents.no
  Filter: (((documents.no)::integer > 100) AND ((documents.no)::integer < 300))
  Rows Removed by Filter: 7
  Buffers: shared hit=7
        Buffers: shared hit=7
        ->  Append  (cost=0.00..109.00 rows=5801 width=40) (actual time=0.006..0.013 rows=10 loops=1)
              Buffers: shared hit=6
              ->  Seq Scan on public.documents  (cost=0.00..1.00 rows=1 width=40) (actual time=0.004..0.004 rows=0 loops=1)
                    Output: documents.id, documents.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_1  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.002 rows=5 loops=1)
                    Output: documents_1.id, documents_1.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_2  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=2 loops=1)
                    Output: documents_2.id, documents_2.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_3  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=1 loops=1)
                    Output: documents_3.id, documents_3.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_4  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=1 loops=1)
                    Output: documents_4.id, documents_4.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_5  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=1 loops=1)
                    Output: documents_5.id, documents_5.no
                    Buffers: shared hit=1
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556941
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sp
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
Subquery Scan on documents  (cost=1.55..149.56 rows=2 width=72) (actual time=0.057..0.067 rows=3 loops=1)
  Output: documents.id, documents.no
  Filter: (((documents.no)::integer > 100) AND ((documents.no)::integer < 300))
  Rows Removed by Filter: 7
  Buffers: shared hit=7
        Buffers: shared hit=7
        ->  Append  (cost=0.00..109.00 rows=5801 width=40) (actual time=0.006..0.013 rows=10 loops=1)
              Buffers: shared hit=6
              ->  Seq Scan on public.documents  (cost=0.00..1.00 rows=1 width=40) (actual time=0.004..0.004 rows=0 loops=1)
                    Output: documents.id, documents.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_1  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.002 rows=5 loops=1)
                    Output: documents_1.id, documents_1.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_2  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=2 loops=1)
                    Output: documents_2.id, documents_2.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_3  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=1 loops=1)
                    Output: documents_3.id, documents_3.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_4  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=1 loops=1)
                    Output: documents_4.id, documents_4.no
                    Buffers: shared hit=1
              ->  Seq Scan on public.documents_5  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.001..0.001 rows=1 loops=1)
                    Output: documents_5.id, documents_5.no
                    Buffers: shared hit=1




у вас условие по (((documents.no)::integer > 100) AND ((documents.no)::integer < 300))
а партиционирование по: partition1 - CHECK ( ContractNo::int <= 100 AND ContractNo::int > 0 )
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556953
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

в данном случае названия полей не играют роли - в начале я назвал ContractNo но потом переименовал в no - вы же понимаете что ПЖ не дал бы создать CHECK если указать неверное поле )
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38556968
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spMaxim Boguk,

в данном случае названия полей не играют роли - в начале я назвал ContractNo но потом переименовал в no - вы же понимаете что ПЖ не дал бы создать CHECK если указать неверное поле )
не знаю, что у вас не играет

делаем полный тест-кейс:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
--DDL--
DROP TABLE IF EXISTS documents CASCADE ;

CREATE TABLE documents  
(id serial primary key
,"no" varchar (5))
;


CREATE TABLE documents_1 (
LIKE documents 
,CHECK ( "no"::int <= 100 AND  "no"::int > 0 )
)
INHERITS (documents);

CREATE TABLE documents_2 (
LIKE documents 
,CHECK ( "no"::int <= 200 AND  "no"::int >100 )
)
INHERITS (documents);

CREATE TABLE documents_3(
LIKE documents 
,CHECK ( "no"::int <= 300 AND  "no"::int >200 )
)
INHERITS (documents);

CREATE TABLE documents_4(
LIKE documents 
,CHECK ( "no"::int <= 400 AND  "no"::int >300 )
)
INHERITS (documents);

CREATE TABLE documents_5(
LIKE documents 
,CHECK ( "no"::int <= 500 AND  "no"::int >400 )
)
INHERITS (documents);
--- триггера писать не буду, с в.п.--
-- ADD TEST DATA ---
do
$do$
DECLARE
	v_sql text;
	k int;
BEGIN
FOR i IN 1..100000
LOOP
	k:=(i %500)/100+1;
	v_sql='
	INSERT INTO documents_'||trim(k::text)||'(id,no) 
	VALUES (DEFAULT,'||((i%500)+1)||');';
	EXECUTE v_sql;
END LOOP;
END;
$do$;
------------------------------
-- TEST --
set constraint_exclusion = on;
EXPLAIN select * from documents where "no"::int > 100 and "no"::int < 300;
--
"Append  (cost=0.00..1178.00 rows=201 width=8)"
"  ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_2  (cost=0.00..589.00 rows=100 width=8)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_3  (cost=0.00..589.00 rows=100 width=8)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
---


ЧЯДНТ ?
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557003
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

спасибо - разобрался - секционирование работает на запросах к таблице, не работает view на секционированной таблице
Чтоб не перегружать пост не писал. что выборку делаю из view:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE OR REPLACE VIEW public.documents_view(
    id,
    no)
AS
  SELECT documents.id,
         documents.no
  FROM documents;



как сделать чтоб view учитывало constraint_exclusion - не пойму
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557053
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spqwwq,

спасибо - разобрался - секционирование работает на запросах к таблице, не работает view на секционированной таблице
Чтоб не перегружать пост не писал. что выборку делаю из view:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE OR REPLACE VIEW public.documents_view(
    id,
    no)
AS
  SELECT documents.id,
         documents.no
  FROM documents;



как сделать чтоб view учитывало constraint_exclusion - не пойму

а что будет если написать?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
explain analyze
select * from
(
  SELECT documents.id as id,
         documents.no as no
  FROM documents
) as documents_view
where "no"::int > 100 and "no"::int < 300;



вообще очень странно все это...
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557060
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
"Append  (cost=0.00..1178.00 rows=201 width=8) (actual time=0.042..540.768 rows=39800 loops=1)"
"  ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28) (actual time=0.004..0.004 rows=0 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_2  (cost=0.00..589.00 rows=100 width=8) (actual time=0.019..108.907 rows=20000 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_3  (cost=0.00..589.00 rows=100 width=8) (actual time=0.025..106.899 rows=19800 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"        Rows Removed by Filter: 200"
"Total runtime: 706.097 ms"

...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557070
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
BEGIN;
CREATE VIEW documents_view AS 
SELECT documents.id as id,
         documents.no as no
  FROM documents;
explain analyze

select * from
  documents_view
where "no"::int > 100 and "no"::int < 300;
---------------------
"Append  (cost=0.00..1178.00 rows=201 width=8) (actual time=0.055..533.910 rows=39800 loops=1)"
"  ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28) (actual time=0.004..0.004 rows=0 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_2  (cost=0.00..589.00 rows=100 width=8) (actual time=0.032..109.195 rows=20000 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_3  (cost=0.00..589.00 rows=100 width=8) (actual time=0.018..102.198 rows=19800 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"        Rows Removed by Filter: 200"
"Total runtime: 691.274 ms"
---------------------------
"ЧЯДНТ"

...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557100
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqMaxim Boguk,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
"Append  (cost=0.00..1178.00 rows=201 width=8) (actual time=0.042..540.768 rows=39800 loops=1)"
"  ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28) (actual time=0.004..0.004 rows=0 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_2  (cost=0.00..589.00 rows=100 width=8) (actual time=0.019..108.907 rows=20000 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Seq Scan on documents_3  (cost=0.00..589.00 rows=100 width=8) (actual time=0.025..106.899 rows=19800 loops=1)"
"        Filter: (((no)::integer > 100) AND ((no)::integer < 300))"
"        Rows Removed by Filter: 200"
"Total runtime: 706.097 ms"



у меня что для view что для таблицы план одинаковый


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
[local]:5432 postgres@temp=# EXPLAIN select * from documents where "no"::int > 100 and "no"::int < 300;
                                      QUERY PLAN
--------------------------------------------------------------------------------------
 Result  (cost=0.00..2617.80 rows=201 width=8)
   ->  Append  (cost=0.00..2617.80 rows=201 width=8)
         ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28)
               Filter: (((no)::integer > 100) AND ((no)::integer < 300))
         ->  Seq Scan on documents_2 documents  (cost=0.00..1308.90 rows=100 width=8)
               Filter: (((no)::integer > 100) AND ((no)::integer < 300))
         ->  Seq Scan on documents_3 documents  (cost=0.00..1308.90 rows=100 width=8)
               Filter: (((no)::integer > 100) AND ((no)::integer < 300))
(8 rows)

Time: 2.260 ms
[local]:5432 postgres@temp=# EXPLAIN select * from documents_view where "no"::int > 100 and "no"::int < 300;
                                      QUERY PLAN
--------------------------------------------------------------------------------------
 Result  (cost=0.00..2617.80 rows=201 width=8)
   ->  Append  (cost=0.00..2617.80 rows=201 width=8)
         ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28)
               Filter: (((no)::integer > 100) AND ((no)::integer < 300))
         ->  Seq Scan on documents_2 documents  (cost=0.00..1308.90 rows=100 width=8)
               Filter: (((no)::integer > 100) AND ((no)::integer < 300))
         ->  Seq Scan on documents_3 documents  (cost=0.00..1308.90 rows=100 width=8)
               Filter: (((no)::integer > 100) AND ((no)::integer < 300))
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557166
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk<>

у меня что для view что для таблицы план одинаковый

<>
"аналогично"(сс)
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557214
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqMaxim Boguk<>

у меня что для view что для таблицы план одинаковый

<>
"аналогично"(сс)

опять автор топика какую то критичную инфу не выдал "Чтоб не перегружать пост"
(к этому бы еще понимание что критично а что нет :))
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557373
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

:) вы правы - утаил WITH(security_barrier = true) с ним и не работает...а надо
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557385
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spMaxim Boguk,

:) вы правы - утаил WITH(security_barrier = true) с ним и не работает...а надо

и не будет... никакие условия не вносятся под security barrier... такой view скорее всего будет вычислять всегда полный запрос внутри а потом уже накладывать все остальные условия поверх... на то он и barrier
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557390
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

а каже тогда блюсти разделение мира и при этом быть уверенным что его не сломают - надо разным группам юзеров давать работать с определенными документами - наилучший способ через view с WITH(security_barrier = true), но получается что в ПЖ нельзя соединить прекрасное с полезным...(
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557406
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
могли бы дать приоритет constraint_exclusion!?
может надо написать разработчикам? или на заборе? :)
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557439
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
BEGIN;
CREATE VIEW documents_view  WITH (security_barrier=true) AS 
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 100 AND  "no"::int > 0 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 200 AND  "no"::int > 100 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 300 AND  "no"::int > 200 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 400 AND  "no"::int > 300 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 500 AND  "no"::int > 400 )
;
----------------------------------------------
explain analyze
select * from
  documents_view
where "no"::int > 100 and "no"::int < 300;
----------------------------------------------
"Append  (cost=0.00..1780.02 rows=202 width=8) (actual time=0.049..874.701 rows=39800 loops=1)"
"  ->  Append  (cost=0.00..889.00 rows=101 width=8) (actual time=0.039..274.288 rows=20000 loops=1)"
"        ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28) (actual time=0.004..0.004 rows=0 loops=1)"
"              Filter: (((no)::integer <= 200) AND ((no)::integer > 100) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"        ->  Seq Scan on documents_2  (cost=0.00..889.00 rows=100 width=8) (actual time=0.016..114.822 rows=20000 loops=1)"
"              Filter: (((no)::integer <= 200) AND ((no)::integer > 100) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Append  (cost=0.00..889.00 rows=101 width=8) (actual time=0.041..286.421 rows=19800 loops=1)"
"        ->  Seq Scan on documents documents_1  (cost=0.00..0.00 rows=1 width=28) (actual time=0.004..0.004 rows=0 loops=1)"
"              Filter: (((no)::integer <= 300) AND ((no)::integer > 200) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"        ->  Seq Scan on documents_3  (cost=0.00..889.00 rows=100 width=8) (actual time=0.019..124.719 rows=19800 loops=1)"
"              Filter: (((no)::integer <= 300) AND ((no)::integer > 200) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"              Rows Removed by Filter: 200"
"Total runtime: 1038.461 ms"



как бе вот так ]:0]
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557494
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

Спасибо за код!
Насколько я понимаю план у такого view будет совсем не оптимальный - у меня на тестовых данных разница во времени выполнения запросов к view и таблице - 8 раз, хотя индексы у всех секций по полю no созданы...
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557540
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопрос к практике применения - поделитесь пожалуйста опытом реального боевого применения секционирования: насколько оправдано, производительность, впечатления, а то я уже сильно сомневаюсь использовать ли
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557617
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
столкнулся с еще одной неприятностью - невозможно контролировать уникальность поля no - я создал уникальный индекс для каждой секции, но уникальность проверяется только на уровне секции а не на уровне всех секций - необходимо в триггерах производить дополнительную проверку на уникальность полей во всех секциях!?
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557626
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
опечатка - вместо уникальность поля no читаем любое другое поле, требующее уникальности во всей таблице
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557654
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как обновить план для вью?
после добавления и удаления секций план запроса показывает обращение к несуществующим секциям
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38557941
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spопечатка - вместо уникальность поля no читаем любое другое поле, требующее уникальности во всей таблице

это известное ограничение партиционирования в postgresql с ним надо мириться и как то жить пока...
вообще если вам требуется жесткий uniq не на serial primary key - скорее всего эту таблицу партиционировать не надо :).

обычно партиционирование это для всяких архивно-накопительных данных с партиционированнием по дате...
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38558631
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

У нас активно растущая база договоров - ежедневно по 200-500 шт
Это самая быстрорастущая таблица. Ее секционирование разумно по дате, но должен соблюдаться и принцип уникальности номеров договоров в совокупности с серией
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38558685
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spMaxim Boguk,

У нас активно растущая база договоров - ежедневно по 200-500 шт
Это самая быстрорастущая таблица. Ее секционирование разумно по дате, но должен соблюдаться и принцип уникальности номеров договоров в совокупности с сериейсекционирование имеет смысл в postgresql в основном, если вам нужно делать DROP старых данных секциями.

(а равносильный delete выполняется часами или сутками )

договора, очевидно, дропаться за разумное время жизни проги не будут.

человек, придумывающий на свою 5-ю точку приключения в виде партицирования (в пг) там, где нужно всего-то продумать правильное индексирование - ССЗБ.

при 1000-х накладных в день и 10-х (20-50) позиций в них нет (по моему опыту) никакой необходимости партицировать таблицу строк накладных (не говоря о шапках).
всё равно, вы её чистить не будете никогда (за время жизни программы -- т.к. в бумаге что-то найти ещё сложнее, чем в программе. а хранить бумагу, и находить что-то в ней надо долго).
а доступаться - индексно.
Единственно - со временем можете сделать партицирование по годам. (при этом уникью нумерации док-тов вам нужно внутри года, согласно законодательства). Ну , это если делать вам будет нечего. ессно.



на худой --
сделайте секционирование по части вашего уникью. (год это у вас, или серия - вам лучше знать).
но я б не стал вообще . (а вот про индексы бы подумал, так чтобы никогда поиск не проходил фулсканом)

поскольку гемора вы с партицированием получаете вагон и тележку (если не собираетесь писать говнокод без ссылочной целостности и прочих признаков приличной учётной БД). а выгод [в вашем случае - точно] - никаких. От слова вообще.
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38558733
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

спасибо!
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38558981
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

Тут возник еще один вопрос не очень освещенный в документации - при создании секций надо ли и какие (партиции на другие таблицы или других тадиц на партицию) создавать связи с другими таблицами?
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38559017
йццй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sp,
с FK при партицировании (мастер таблиц) всё нехорошо

если только ссылающиеся (slave|detail) таблицы не отпартицированы так же (по тому же признаку) что и ссылаемые (master|header). Тогда появляется возможность сделать аккуратные FK-еи между одинаково нарезанными партициями мастеров|шапок и подчинёнок|деталировок

если же партицируется только ссылающаяся сторона - проблем нет.
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38559190
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
йццй,

както вы сложно изъяснились - читал кучу раз :)
понятно только последнее предложение...
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38560402
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
BEGIN;
CREATE VIEW documents_view  WITH (security_barrier=true) AS 
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 100 AND  "no"::int > 0 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 200 AND  "no"::int > 100 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 300 AND  "no"::int > 200 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 400 AND  "no"::int > 300 )
UNION ALL   
SELECT documents.id as id,
         documents.no as no
  FROM documents WHERE ( "no"::int <= 500 AND  "no"::int > 400 )
;
----------------------------------------------
explain analyze
select * from
  documents_view
where "no"::int > 100 and "no"::int < 300;
----------------------------------------------
"Append  (cost=0.00..1780.02 rows=202 width=8) (actual time=0.049..874.701 rows=39800 loops=1)"
"  ->  Append  (cost=0.00..889.00 rows=101 width=8) (actual time=0.039..274.288 rows=20000 loops=1)"
"        ->  Seq Scan on documents  (cost=0.00..0.00 rows=1 width=28) (actual time=0.004..0.004 rows=0 loops=1)"
"              Filter: (((no)::integer <= 200) AND ((no)::integer > 100) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"        ->  Seq Scan on documents_2  (cost=0.00..889.00 rows=100 width=8) (actual time=0.016..114.822 rows=20000 loops=1)"
"              Filter: (((no)::integer <= 200) AND ((no)::integer > 100) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"  ->  Append  (cost=0.00..889.00 rows=101 width=8) (actual time=0.041..286.421 rows=19800 loops=1)"
"        ->  Seq Scan on documents documents_1  (cost=0.00..0.00 rows=1 width=28) (actual time=0.004..0.004 rows=0 loops=1)"
"              Filter: (((no)::integer <= 300) AND ((no)::integer > 200) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"        ->  Seq Scan on documents_3  (cost=0.00..889.00 rows=100 width=8) (actual time=0.019..124.719 rows=19800 loops=1)"
"              Filter: (((no)::integer <= 300) AND ((no)::integer > 200) AND ((no)::integer > 100) AND ((no)::integer < 300))"
"              Rows Removed by Filter: 200"
"Total runtime: 1038.461 ms"



как бе вот так ]:0]

Большая проблема с таким способом, что нельзя оперативно изменить вью при создании секции если мы вставляем данные используя запрос к этому вью!!!
...
Рейтинг: 0 / 0
Использование record в CHECK constarint
    #38560618
йццй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
spqwwq
Код: sql
1.
<>



как бе вот так ]:0]

Большая проблема с таким способом, что нельзя оперативно изменить вью при создании секции если мы вставляем данные используя запрос к этому вью!!!
а кто-то обещал другоэ ?
...
Рейтинг: 0 / 0
42 сообщений из 42, показаны все 2 страниц
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Использование record в CHECK constarint
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]