×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

При отключении обработки cookie наш сайт продолжит функционировать, однако будут использоваться исключительно необходимые технические файлы, без которых работа ресурса невозможна.

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

3.14.4. Фильтры строк

3.14.4.1. Правила фильтров строк
3.14.4.2. Ограничения выражений
3.14.4.3. Преобразования UPDATE
3.14.4.4. Секционированные таблицы
3.14.4.5. Начальная синхронизация данных
3.14.4.6. Комбинирование нескольких фильтров строк
3.14.4.7. Примеры

По умолчанию все данные из всех опубликованных таблиц реплицируются соответствующим подписчикам. Объем реплицируемых данных может быть ограничен с помощью фильтр строк. Пользователь может использовать фильтры строк по соображениям функциональности, безопасности или производительности. Если для опубликованной таблицы установлен фильтр строк, строка реплицируется только в том случае, если ее данные удовлетворяют выражению фильтра строк. Это позволяет выполнять частичную репликацию набора таблиц. Фильтр строк определяется для каждой таблицы. Используйте предложение WHERE после имени таблицы для каждой опубликованной таблицы, в которой требуется фильтрация данных. WHERE Предложение должно быть заключено в скобки. См. CREATE PUBLICATION for details.

3.14.4.1. Правила фильтров строк #

Фильтры строк применяются перед публикацией изменений. Если выражение фильтра строк возвращает значение false или NULL то строка не реплицируется. Выражение в WHERE предложении вычисляется с использованием той же роли, которая используется для соединения для репликации (т. е. роли, указанной в CONNECTION предложении CREATE SUBSCRIPTION). Фильтры строк не влияют на TRUNCATE команду.

3.14.4.2. Ограничения выражений #

Предложение WHERE допускает использование только простых выражений. Оно не может содержать пользовательские функции, операторы, типы и правила сортировки, ссылки на системные столбцы или встроенные функции, не являющиеся постоянными (immutable).

Если публикация включает UPDATE или DELETE операции, то предложение фильтра строк WHERE должно содержать только те столбцы, которые входят в идентификатор реплики (см. REPLICA IDENTITY). Если публикация включает только INSERT операции, то предложение фильтра строк WHERE предложение может использовать любой столбец.

3.14.4.3. Преобразования UPDATE #

При обработке операции UPDATE выражение фильтра строк вычисляется как для старой, так и для новой строки (т. е. с использованием данных до и после обновления). Если оба результата вычисления — true, выполняется репликация UPDATE изменение. Если оба результата вычисления false, изменение не реплицируется. Если только одна из старой или новой строк соответствует выражению фильтра строк, то UPDATE преобразуется в INSERT или DELETE, во избежание нарушения согласованности данных. Строка на Подписчике должна соответствовать тому, что определено выражением фильтра строк на Издателе.

Если старая строка удовлетворяет выражению фильтра строк (она была отправлена Подписчику), а новая строка — нет, то с точки зрения согласованности данных старая строка должна быть удалена на Подписчике. Следовательно, UPDATE преобразуется в DELETE.

Если старая строка не удовлетворяет выражению фильтра строк (она не была отправлена Подписчику), а новая строка удовлетворяет ему, то с точки зрения согласованности данных новая строка должна быть добавлена на Подписчик. Следовательно, UPDATE преобразуется в INSERT.

Таблица 3.14.1 содержит сводную информацию о примененных преобразованиях.

Таблица 3.14.1. UPDATE Сводка преобразований

Старая строкаНовая строкаПреобразование
не соответствуетне соответствуетне реплицировать
не соответствуетсоответствуетINSERT
соответствуетне соответствуетDELETE
соответствуетсоответствуетUPDATE

3.14.4.4. Секционированные таблицы #

Если публикация содержит секционированную таблицу, параметр публикации publish_via_partition_root определяет, какой фильтр строк используется. Если publish_via_partition_root имеет значение true, то фильтр строк корневой секционированной таблицы используется. В противном случае, если publish_via_partition_root имеет значение false (по умолчанию), для каждой секции используется фильтр строк.

3.14.4.5. Начальная синхронизация данных #

Если подписка требует копирования существующих данных таблицы и публикация содержит WHERE предложения, на подписчика копируются только те данные, которые удовлетворяют выражениям фильтра строк.

Если подписка включает несколько публикаций, в которых таблица была опубликована с различными WHERE выражения, строки, удовлетворяющие любому из выражений, будут скопированы. Подробнее см. Раздел 3.14.4.6 для получения подробных сведений.

Предупреждение

Поскольку начальная синхронизация данных не учитывает параметр «публикация» при копировании существующих данных таблицы, могут быть скопированы строки, которые не были бы реплицированы с помощью DML. См. Раздел 3.14.8.1, а также Раздел 3.14.2.2 для ознакомления с примерами.

Примечание

Если подписчик использует версию до 15 включительно, при копировании существующих данных фильтры строк не применяются, даже если они определены в публикации. Это связано с тем, что в предыдущих версиях поддерживается только копирование всей таблицы целиком.

3.14.4.6. Комбинирование нескольких фильтров строк #

Если подписка включает несколько публикаций, в которых одна и та же таблица опубликована с различными фильтрами строк (для одной и той же «публикация» операции), эти выражения объединяются оператором OR, так что строки, удовлетворяющие любому любому из выражений, будут реплицированы. Это означает, что все остальные фильтры строк для той же таблицы становятся избыточными, если:

  • Одна из публикаций не имеет фильтра строк.

  • Одна из публикаций была создана с использованием FOR ALL TABLES. Данное предложение не допускает использование фильтров строк.

  • Одна из публикаций была создана с использованием FOR TABLES IN SCHEMA и таблица принадлежит к указанной схеме. Данное предложение не допускает использование фильтров строк.

3.14.4.7. Примеры #

Создание таблиц для использования в следующих примерах.

test_pub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
CREATE TABLE
test_pub=# CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d));
CREATE TABLE
test_pub=# CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g));
CREATE TABLE

Создание нескольких публикаций. Публикация p1 включает одну таблицу (t1), для которой определен фильтр строк. Публикация p2 включает две таблицы. Таблица t1 не имеет фильтра строк, а таблица t2 имеет фильтр строк. Публикация p3 содержит две таблицы, и для обеих определен фильтр строк.

test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a > 5 AND c = 'Новый Южный Уэльс');
CREATE PUBLICATION
test_pub=# CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99);
CREATE PUBLICATION
test_pub=# CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10);
CREATE PUBLICATION

psql может использоваться для отображения выражений фильтра строк (если они определены) для каждой публикации.

test_pub=# \dRp+
                               Публикация p1
  Владелец   | Все таблицы | Вставки | обновления | удаление | команды TRUNCATE | через корневую таблицу
----------+------------+---------+---------+---------+-----------+----------
 postgres | f          | t       | t       | t       | t         | f
Таблицы:
    "public.t1" WHERE ((a > 5) AND (c = 'Новый Южный Уэльс'::text))

                               Публикация p2
  Владелец   | Все таблицы | Вставки | Обновления | Удаления | Команды TRUNCATE | Через корневую таблицу
----------+------------+---------+---------+---------+-----------+----------
 postgres | f          | t       | t       | t       | t         | f
Таблицы:
    "public.t1"
    "public.t2" WHERE (e = 99)

                               Публикация p3
  Владелец   | Все таблицы | Вставки | Обновления | Удаления | Команды TRUNCATE | Через корневую таблицу
----------+------------+---------+---------+---------+-----------+----------
 postgres | f          | t       | t       | t       | t         | f
Таблицы:
    "public.t2" WHERE (d = 10)
    "public.t3" WHERE (g = 10)

psql может использоваться для вывода выражений фильтра строк (если они определены) для каждой таблицы. Видно, что таблица t1 входит в состав двух публикаций, но имеет фильтр строк только в p1. Видно, что таблица t2 входит в состав двух публикаций и имеет разные фильтры строк в каждой из них.

test_pub=# \d t1
                 Таблица "public.t1"
 Столбец |  Тип   | Правило сортировки | Допускающий значение NULL | По умолчанию
--------+---------+-----------+----------+---------
 a      | integer |           | не NULL |
 b      | integer |           |          |
 c      | text    |           | не NULL |
Индексы:
    "t1_pkey" PRIMARY KEY, btree (a, c)
Публикации:
    "p1" WHERE ((a > 5) AND (c = 'Новый Южный Уэльс'::text))
    "p2"

test_pub=# \d t2
                 Таблица "public.t2"
 Столбец |  Тип   | Правило сортировки | Допускающий значение NULL | По умолчанию
--------+---------+-----------+----------+---------
 d      | integer |           | не NULL |
 e      | integer |           |          |
 f      | integer |           |          |
Индексы:
    "t2_pkey" PRIMARY KEY, btree (d)
Публикации:
    "p2" WHERE (e = 99)
    "p3" WHERE (d = 10)

test_pub=# \d t3
                 Таблица "public.t3"
 Столбец |  Тип   | Правило сортировки | Допускающий значение NULL | По умолчанию
--------+---------+-----------+----------+---------
 g      | integer |           | not null |
 h      | integer |           |          |
 i      | integer |           |          |
Индексы:
    "t3_pkey" PRIMARY KEY, btree (g)
Публикации:
    "p3" WHERE (g = 10)

На узле-подписчике создается таблица t1 с тем же определением, что и на издателе, а также создание подписки s1 , подписывающаяся на публикацию p1.

test_sub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
CREATE TABLE
test_sub=# CREATE SUBSCRIPTION s1
test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
test_sub-# PUBLICATION p1;
CREATE SUBSCRIPTION

Выполняется вставка строк. Только те строки, которые удовлетворяют t1 WHERE публикации, p1 реплицируются.

test_pub=# INSERT INTO t1 VALUES (2, 102, 'NSW');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES (3, 103, 'QLD');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES (4, 104, 'VIC');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES (5, 105, 'ACT');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES (6, 106, 'NSW');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES (7, 107, 'NT');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES (8, 108, 'QLD');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES (9, 109, 'NSW');
INSERT 0 1

test_pub=# SELECT * FROM t1;
 a |  b  |  c
---+-----+-----
 2 | 102 | NSW
 3 | 103 | QLD
 4 | 104 | VIC
 5 | 105 | ACT
 6 | 106 | NSW
 7 | 107 | NT
 8 | 108 | QLD
 9 | 109 | NSW
(8 rows)

test_sub=# SELECT * FROM t1;
 a |  b  |  c
---+-----+-----
 6 | 106 | Новый Южный Уэльс
 9 | 109 | Новый Южный Уэльс
(2 строки)

Обновление данных, при котором и старые, и новые значения строк удовлетворяют t1 WHERE условию публикации p1. Функция UPDATE реплицирует изменение в обычном режиме.

test_pub=# UPDATE t1 SET b = 999 WHERE a = 6;
UPDATE 1

test_pub=# SELECT * FROM t1;
 a |  b  |  c
---+-----+-----
 2 | 102 | Новый Южный Уэльс
 3 | 103 | Квинсленд
 4 | 104 | Виктория
 5 | 105 | Действие
 7 | 107 | Северная территория
 8 | 108 | Квинсленд
 9 | 109 | Новый Южный Уэльс
 6 | 999 | Новый Южный Уэльс
(8 строк)

test_sub=# SELECT * FROM t1;
 a |  b  |  c
---+-----+-----
 9 | 109 | Новый Южный Уэльс
 6 | 999 | Новый Южный Уэльс
(2 строки)

Обновление данных, при котором старые значения строк не удовлетворяли t1 WHERE условию публикации p1, однако значения новой строки удовлетворяют этому условию. Это действие UPDATE преобразуется в INSERT и изменение реплицируется. Проверьте наличие новой строки на стороне подписчика.

test_pub=# UPDATE t1 SET a = 555 WHERE a = 2;
UPDATE 1

test_pub=# SELECT * FROM t1;
  a  |  b  |  c
-----+-----+-----
   3 | 103 | Квинсленд
   4 | 104 | Виктория
   5 | 105 | Действие
   7 | 107 | Северная территория
   8 | 108 | Квинсленд
   9 | 109 | Новый Южный Уэльс
   6 | 999 | Новый Южный Уэльс
 555 | 102 | Новый Южный Уэльс
(8 rows)

test_sub=# SELECT * FROM t1;
  a  |  b  |  c
-----+-----+-----
   9 | 109 | Новый Южный Уэльс
   6 | 999 | Новый Южный Уэльс
 555 | 102 | Новый Южный Уэльс
(3 rows)

Обновление данных, в которых значения исходной строки соответствовали условию t1 WHERE условию публикации p1, а значения новой строки — нет. Данное действие UPDATE преобразуется в DELETE и изменение реплицируется. Следует отметить, что строка удаляется на стороне подписчика.

test_pub=# UPDATE t1 SET c = 'VIC' WHERE a = 9;
UPDATE 1

test_pub=# SELECT * FROM t1;
  a  |  b  |  c
-----+-----+-----
   3 | 103 | QLD
   4 | 104 | VIC
   5 | 105 | ACT
   7 | 107 | NT
   8 | 108 | QLD
   6 | 999 | NSW
 555 | 102 | NSW
   9 | 109 | VIC
(8 rows)

test_sub=# SELECT * FROM t1;
  a  |  b  |  c
-----+-----+-----
   6 | 999 | NSW
 555 | 102 | NSW
(2 rows)

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

Создайте секционированную таблицу на издателе.

test_pub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
CREATE TABLE
test_pub=# CREATE TABLE child PARTITION OF parent DEFAULT;
CREATE TABLE

Создайте такие же таблицы на подписчике.

test_sub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
CREATE TABLE
test_sub=# CREATE TABLE child PARTITION OF parent DEFAULT;
CREATE TABLE

Создайте публикацию p4, а затем подпишитесь на нее. Параметр публикации publish_via_partition_root установлен в значение true. Фильтры строк определены как для секционированной таблицы (родительская таблица), так и для секции (дочерняя таблица).

test_pub=# CREATE PUBLICATION p4 FOR TABLE parent WHERE (a < 5), child WHERE (a >= 5)
test_pub-# WITH (publish_via_partition_root=true);
CREATE PUBLICATION

test_sub=# CREATE SUBSCRIPTION s4
test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s4'
test_sub-# PUBLICATION p4;
CREATE SUBSCRIPTION

Вставьте несколько значений напрямую в родительская таблица и дочерняя таблица таблицы. Репликация выполняется с использованием фильтра строк родительская таблица (поскольку publish_via_partition_root истинно).

test_pub=# INSERT INTO parent VALUES (2), (4), (6);
INSERT 0 3
test_pub=# INSERT INTO child VALUES (3), (5), (7);
INSERT 0 3

test_pub=# SELECT * FROM parent ORDER BY a;
 a
---
 2
 3
 4
 5
 6
 7
(6 rows)

test_sub=# SELECT * FROM parent ORDER BY a;
 a
---
 2
 3
 4
(3 rows)

Повторите тот же тест, но с другим значением для publish_via_partition_root. Параметр публикации publish_via_partition_root устанавливается в значение false. Фильтр строк определен для секции (дочерняя таблица).

test_pub=# DROP PUBLICATION p4;
DROP PUBLICATION
test_pub=# CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a >= 5)
test_pub-# WITH (publish_via_partition_root=false);
CREATE PUBLICATION

test_sub=# ALTER SUBSCRIPTION s4 REFRESH PUBLICATION;
ALTER SUBSCRIPTION

Выполните операции вставки на издателе аналогично предыдущим действиям. Репликация осуществляется с использованием фильтра строк дочерняя таблица (поскольку publish_via_partition_root имеет значение false).

test_pub=# TRUNCATE parent;
TRUNCATE TABLE
test_pub=# INSERT INTO parent VALUES (2), (4), (6);
INSERT 0 3
test_pub=# INSERT INTO child VALUES (3), (5), (7);
INSERT 0 3

test_pub=# SELECT * FROM parent ORDER BY a;
 a
---
 2
 3
 4
 5
 6
 7
(6 rows)

test_sub=# SELECT * FROM child ORDER BY a;
 a
---
 5
 6
 7
(3 rows)
Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению