变更通知、逻辑解码与采样方法
变更通知、逻辑解码与采样方法
本文件包含模块:tcn(触发变更通知)、test_decoding(逻辑解码)、tsm_system_rows/tsm_system_time(系统采样)、unaccent(去除重音符号文本搜索)。
tcn
tcn模块提供一个触发器函数,它通知监听者有关它所附着的任意表上的改变。它必须被用作一个行级AFTER触发器。
这个模块被认为是"可信的",也就是说,它可以由对当前数据库具有CREATE权限的非超级用户安装。
在一个CREATE TRIGGER语句中只可以为该函数提供一个参数,并且是可选的。如果提供该参数,它将被作为用于通知的频道名。如果忽略它,频道名将使用tcn。
通知的负载由表名、一个指示所执行操作类型的字母以及用于主键列的列名/值对构成。每一部分都用逗号与下一部分隔开。为了便于解析对正则表达式的使用,表和列名总是被包裹在双引号内,并且数据值总是被包裹在单引号内。嵌入的引号都被双写。
下面是使用该扩展的简单例子。
test=# create table tcndata
test-# (
test(# a int not null,
test(# b date not null,
test(# c text,
test(# primary key (a, b)
test(# );
CREATE TABLE
test=# create trigger tcndata_tcn_trigger
test-# after insert or update or delete on tcndata
test-# for each row execute function triggered_change_notification();
CREATE TRIGGER
test=# listen tcn;
LISTEN
test=# insert into tcndata values (1, date '2012-12-22', 'one'),
test-# (1, date '2012-12-23', 'another'),
test-# (2, date '2012-12-23', 'two');
INSERT 0 3
Asynchronous notification "tcn" with payload
""tcndata",I,"a"='1',"b"='2012-12-22'" received from server process with PID
22770.
Asynchronous notification "tcn" with payload
""tcndata",I,"a"='1',"b"='2012-12-23'" received from server process with PID
22770.
Asynchronous notification "tcn" with payload
""tcndata",I,"a"='2',"b"='2012-12-23'" received from server process with PID
22770.
test=# update tcndata set c = 'uno' where a = 1;
UPDATE 2
Asynchronous notification "tcn" with payload
""tcndata",U,"a"='1',"b"='2012-12-22'" received from server process with PID
22770.
Asynchronous notification "tcn" with payload
""tcndata",U,"a"='1',"b"='2012-12-23'" received from server process with PID
22770.
test=# delete from tcndata where a = 1 and b = date '2012-12-22';
DELETE 1
Asynchronous notification "tcn" with payload
""tcndata",D,"a"='1',"b"='2012-12-22'" received from server process with PID
22770.
test_decoding
test_decoding是一个逻辑解码输出插件的例子。以作为开发你自己的输出插件的起点。
test_decoding通过逻辑解码机制接收 WAL 并且把它解码成被执行的操作的文本表达形式。
这个插件的典型输出可能是:
test=# SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'include-xids', '0');
location | xid | data
-----------+-----+--------------------------------------------------
0/16D30F8 | 691 | BEGIN
0/16D32A0 | 691 | table public.data: INSERT: id[int4]:2 data[text]:'arg'
0/16D32A0 | 691 | table public.data: INSERT: id[int4]:3 data[text]:'demo'
0/16D32A0 | 691 | COMMIT
0/16D32D8 | 692 | BEGIN
0/16D3398 | 692 | table public.data: DELETE: id[int4]:2
0/16D3398 | 692 | table public.data: DELETE: id[int4]:3
0/16D3398 | 692 | COMMIT
(8 rows)
tsm_system_rows
tsm_system_rows模块提供了表采样方法 SYSTEM_ROWS,它可以用在SELECT 命令的TABLESAMPLE子句中。
这种表采样方法接受一个整数参数,它是要读取的最大行数。得到的采样将总是包含正好这么多行,除非该表中没有足够的行,在那种情况下整个表都会被选择出来。
和内建的SYSTEM采样方法一样,SYSTEM_ROWS执行块级别的采样,所以采样不是完全随机的,而是服从于聚簇效果,特别是只要求少量行时。
SYSTEM_ROWS不支持 REPEATABLE子句。
这个模块被认为是"可信的",也就是说,它可以由对当前数据库具有CREATE权限的非超级用户安装。
示例
这里是一个用SYSTEM_ROWS选择一个表采样的例子。首先安装扩展:
CREATE EXTENSION tsm_system_rows;
然后就可以在SELECT命令中使用它,例如:
SELECT * FROM my_table TABLESAMPLE SYSTEM_ROWS(100);
test=# SELECT * FROM my_table TABLESAMPLE SYSTEM_ROWS(100);
id | xml
----+-----
(0 rows)
这个命令从表my_table中返回一个 100 行的采样(除非该表没有 100 个可见行,那时将会返回其中所有的行)。
tsm_system_time
tsm_system_time模块提供了表采样方法 SYSTEM_TIME,它可以用在SELECT 命令的TABLE SAMPLE子句中。
这种表采样方法接受一个浮点类型的参数,它是花费在读表上的最大毫秒数。 这可以让你直接控制查询进行多久,但付出的代价是很难预测采样的尺寸。 得到的采样将包含在指定时间内能读入的那么多行,除非首先已经读入了整个表。
和内建的SYSTEM采样方法一样, SYSTEM_TIME执行块级别的采样,所以采样不是完全随机的,而是服从于聚簇效果,特别是只选择少量行时。
SYSTEM_TIME不支持 REPEA TABLE子句。
这个模块被认为是"可信的",也就是说,它可以由对当前数据库具有CREATE权限的非超级用户安装。
示例
这里是一个用SYSTEM_TIME选择一个表采样的例子。首先安装扩展:
CREATE EXTENSION tsm_system_time;
然后就可以在SELECT命令中使用它,例如:
SELECT * FROM my_table TABLESAMPLE SYSTEM_TIME(1000);
test=# CREATE TABLE my_table
(id int PRIMARY KEY,
xml text);
CREATE TABLE
test=# SELECT * FROM my_table TABLESAMPLE SYSTEM_TIME(1000);
id | xml
----+-----
(0 rows)
这个命令将返回在 1 秒(1000 毫秒)能读到的my_table 采样。当然,如果 1 秒内就能读完整个表,所有的行都将被返回。
unaccent
unaccent是一个文本搜索字典,它能从词位中移除重音(附加符号)。它是一个过滤词典,这表示它的输出总是会被传递给下一个字典(如果有),这和字典的通常行为不同。这允许为全文搜索做与重音无关的处理。
unaccent的当前实现不能被用作thesaurus字典的正规化字典。
这个模块被认为是"可信的",也就是说,它可以由对当前数据库具有CREATE权限的非超级用户安装。
配置
unaccent字典接受下列选项:
• RULES是包含翻译规则列表的文件的基本名。这个文件必须被存储在$SHAREDIR/tsearch_data/中。它的名称必须以.rules(不包含在RULES参数中)结束。
规则文件具有下面的格式:
• 每一行表示一个由带有重音的字符和不带重音的字符构成的对。第一个字符将被翻译成第二个。例如:
À A
Á A
 A
à A
Ä A
Å A
Æ AE
两个字符必须由空格分隔,并且一行上的任何前导或尾随空白都将被忽略。
• 或者,如果一行只给出一个字符,则删除该字符的实例; 这在用单独的字符表示重音的语言中是有用的。
• 实际上,每个"字符"可以是不包含空格的任何字符串,因此, 除了去除变音符之外,unaccent字典也可以用于其他类型的字符串替换。
• 与其他文本搜索配置文件一样,规则文件必须以UTF-8编码方式存储。加载时,数据将自动转换为当前数据库的编码。任何含有不可翻译字符的行都将被忽略,因此规则文件可以包含当前编码中不适用的规则。
用法
安装unaccent扩展会创建一个文本搜索模板unaccent和一个基于前者的字典unaccent。unaccent字典有默认的参数设置RULES='unaccent',这会让该字典使用标准的unaccent.rules文件。如果希望修改该参数,可以
[mydb=# ALTER TEXT SEARCH DICTIONARY unaccent (RULES='my_rules');]{.mark}
或者基于该模板创建新的字典。
要测试该字典,你可以尝试:
test=# select ts_lexize('unaccent','Hôtel');
ts_lexize
-----------
{Hotel}
(1 row)
这里是一个展示把unaccent字典插入到一个文本搜索配置的例子:
test=# CREATE TEXT SEARCH CONFIGURATION fr ( COPY = french );
test=# ALTER TEXT SEARCH CONFIGURATION fr
ALTER MAPPING FOR hword, hword_part, word
WITH unaccent, french_stem;
test=# select to_tsvector('fr','Hôtels de la Mer');
to_tsvector
-------------------
'hotel':1 'mer':4
(1 row)
test=# select to_tsvector('fr','Hôtel de la Mer') @@ to_tsquery('fr','Hotels');
?column?
----------
t
(1 row)
test=# select ts_headline('fr','Hôtel de la Mer',to_tsquery('fr','Hotels'));
ts_headline
------------------------
<b>Hôtel</b> de la Mer
(1 row)
函数
unaccent()函数从一个给定的字符串中移除重音(附加符号)。基本上,它是unaccent字典的一个包装器,但是它能在普通的文本搜索环境之外使用。
unaccent([dictionary regdictionary, ] string text) returns text
如果省略dictionary参数,则使用名为unaccent并且与unaccent()函数有相同模式的文本搜索词典。
例如:
SELECT unaccent('unaccent', 'Hôtel');
SELECT unaccent('Hôtel');