Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 26 additions & 198 deletions zh/14/ddl.sgml

Large diffs are not rendered by default.

53 changes: 7 additions & 46 deletions zh/14/dml.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -220,15 +220,10 @@ DELETE FROM products;
<secondary>RETURNING</secondary>
</indexterm>

<indexterm zone="dml-returning">
<primary>MERGE</primary>
<secondary>RETURNING</secondary>
</indexterm>

<para>
有时候,在修改行的同时取得这些行中的数据会很有用。
<command>INSERT</command>、<command>UPDATE</command>、
<command>DELETE</command> 和 <command>MERGE</command> 命令都支持可选的
<command>DELETE</command> 命令都支持可选的
<literal>RETURNING</literal> 子句。使用
<literal>RETURNING</literal> 可以避免额外执行一次数据库查询来收集这些数据;当原本难以可靠地识别被修改的行时,这一点尤其有价值。
</para>
Expand All @@ -243,7 +238,7 @@ DELETE FROM products;

<para>
在 <command>INSERT</command> 中,<literal>RETURNING</literal>
默认可用的数据是插入后的行。对于简单的插入,这并没有太大用处,
可用的数据是插入后的行。对于简单的插入,这并没有太大用处,
因为它只是重复客户端提供的数据。但在依赖计算得出的缺省值时,它就会非常方便。例如,当使用
<link linkend="datatype-serial"><type>serial</type></link>
列提供唯一标识符时,<literal>RETURNING</literal> 可以返回分配给新行的 ID:
Expand All @@ -258,7 +253,7 @@ INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;

<para>
在 <command>UPDATE</command> 中,<literal>RETURNING</literal>
默认可用的数据是被修改行的新内容。例如:
可用的数据是被修改行的新内容。例如:
<programlisting>
UPDATE products SET price = price * 1.10
WHERE price &lt;= 99.99
Expand All @@ -268,51 +263,17 @@ UPDATE products SET price = price * 1.10

<para>
在 <command>DELETE</command> 中,<literal>RETURNING</literal>
默认可用的数据是被删除行的内容。例如:
可用的数据是被删除行的内容。例如:
<programlisting>
DELETE FROM products
WHERE obsoletion_date = 'today'
RETURNING *;
</programlisting>
</para>

<para>
在 <command>MERGE</command> 中,<literal>RETURNING</literal>
默认可用的数据是源行的内容,加上被插入、更新或删除的目标行内容。由于源和目标通常有许多相同的列,指定
<literal>RETURNING *</literal> 可能会导致大量重复列,因此更常见也更有用的做法是对其加以限定,只返回源行或目标行。例如:
<programlisting>
MERGE INTO products p USING new_products n ON p.product_no = n.product_no
WHEN NOT MATCHED THEN INSERT VALUES (n.product_no, n.name, n.price)
WHEN MATCHED THEN UPDATE SET name = n.name, price = n.price
RETURNING p.*;
</programlisting>
</para>

<para>
在这些命令中,也都可以显式返回被修改行的旧内容和新内容。例如:
<programlisting>
UPDATE products SET price = price * 1.10
WHERE price &lt;= 99.99
RETURNING name, old.price AS old_price, new.price AS new_price,
new.price - old.price AS price_change;
</programlisting>
在这个示例中,写 <literal>new.price</literal> 与直接写
<literal>price</literal> 是一样的,但前者能使含义更清晰。
</para>

<para>
这种返回新旧值的语法可用于
<command>INSERT</command>、<command>UPDATE</command>、
<command>DELETE</command> 和 <command>MERGE</command> 命令,但通常旧值会是
<literal>NULL</literal>(对于 <command>INSERT</command>),而新值会是
<literal>NULL</literal>(对于 <command>DELETE</command>)。不过,在某些情况下,它对这些命令仍然有用。例如,在
<command>INSERT</command> 中,如果带有
<link linkend="sql-on-conflict"><literal>ON CONFLICT DO UPDATE</literal></link>
子句,那么对于发生冲突的行,旧值将是非 <literal>NULL</literal> 的。类似地,如果某个
<command>DELETE</command> 被改写成 <command>UPDATE</command>(通过
<link linkend="sql-createrule">重写规则</link>),新值也可能是非 <literal>NULL</literal> 的。
</para>




<para>
如果目标表上有触发器(<xref linkend="triggers"/>),那么
<literal>RETURNING</literal> 可用的数据就是经触发器修改后的行。因此,查看由触发器计算出的列,也是
Expand Down
18 changes: 1 addition & 17 deletions zh/14/docguide.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -361,23 +361,7 @@ ADDITIONAL_FLAGS='-Xmx1500m'
</sect1>


<sect1 id="docguide-build-meson">
<title>使用 Meson 构建文档</title>

<para>
要使用 Meson 构建文档,请在运行下列命令之一之前切换到<filename>build</filename>目录,
或者在命令中添加<option>-C build</option>。
</para>

<para>
若只构建文档的<acronym>HTML</acronym>版本:
<screen>
<prompt>build$ </prompt><userinput>ninja html</userinput>
</screen>
输出位于子目录<filename>build/doc/src/sgml</filename>中。
</para>
</sect1>



<sect1 id="docguide-authoring">
<title>文档编写</title>
Expand Down
164 changes: 10 additions & 154 deletions zh/14/fuzzystrmatch.sgml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- doc/src/sgml/fuzzystrmatch.sgml -->

<sect1 id="fuzzystrmatch" xreflabel="fuzzystrmatch">
<title>fuzzystrmatch &mdash; 确定字符串的相似性和距离</title>
<title>fuzzystrmatch</title>

<indexterm zone="fuzzystrmatch">
<primary>fuzzystrmatch</primary>
Expand All @@ -15,8 +15,7 @@
<para>
目前,<function>soundex</function>、<function>metaphone</function>、
<function>dmetaphone</function> 和 <function>dmetaphone_alt</function> 函数
不能很好地处理多字节编码(例如 UTF-8)。对于这类数据,请使用
<function>daitch_mokotoff</function> 或 <function>levenshtein</function>。
不能很好地处理多字节编码(例如 UTF-8)。
</para>
</caution>

Expand Down Expand Up @@ -84,150 +83,7 @@ SELECT * FROM s WHERE difference(s.nm, 'john') &gt; 2;
</programlisting>
</sect2>

<sect2 id="fuzzystrmatch-daitch-mokotoff">
<title>Daitch-Mokotoff Soundex</title>

<para>
与原始的 Soundex 系统一样,Daitch-Mokotoff Soundex 也是通过将发音相近的名字
转换为相同代码来进行匹配。不过,与原始系统相比,Daitch-Mokotoff Soundex
对非英语名字要有用得多。相对于原始系统,主要改进包括:

<itemizedlist spacing="compact" mark="bullet">
<listitem>
<para>
代码基于前六个有意义的字母,而不是前四个。
</para>
</listitem>
<listitem>
<para>
一个字母或字母组合可映射为十种可能的代码,而不是七种。
</para>
</listitem>
<listitem>
<para>
如果两个连续字母只对应一个发音,则它们会被编码为单个数字。
</para>
</listitem>
<listitem>
<para>
当某个字母或字母组合可能有不同发音时,会生成多个代码以覆盖所有可能性。
</para>
</listitem>
</itemizedlist>
</para>

<indexterm>
<primary>daitch_mokotoff</primary>
</indexterm>

<para>
该函数为输入生成 Daitch-Mokotoff Soundex 代码:
</para>

<synopsis>
daitch_mokotoff(<parameter>source</parameter> text) 返回 text[]
</synopsis>

<para>
结果可能包含一个或多个代码,取决于存在多少种合理的发音,因此以数组表示。
</para>

<para>
由于 Daitch-Mokotoff Soundex 代码仅由 6 个数字组成,
<parameter>source</parameter> 最好是单个单词或名字。
</para>

<para>
下面是一些示例:
</para>

<programlisting>
SELECT daitch_mokotoff('George');
daitch_mokotoff
-----------------
{595000}

SELECT daitch_mokotoff('John');
daitch_mokotoff
-----------------
{160000,460000}

SELECT daitch_mokotoff('Bierschbach');
daitch_mokotoff
-----------------------------------------------------------
{794575,794574,794750,794740,745750,745740,747500,747400}

SELECT daitch_mokotoff('Schwartzenegger');
daitch_mokotoff
-----------------
{479465}
</programlisting>

<para>
对于单个名字的匹配,可以直接使用 <literal>&amp;&amp;</literal> 操作符比较返回的
text 数组:只要存在任意重叠就可视为匹配。为提高效率,可以使用 GIN 索引,
见 <xref linkend="gin"/> 以及下面的示例:
</para>

<programlisting>
CREATE TABLE s (nm text);
CREATE INDEX ix_s_dm ON s USING gin (daitch_mokotoff(nm)) WITH (fastupdate = off);

INSERT INTO s (nm) VALUES
('Schwartzenegger'),
('John'),
('James'),
('Steinman'),
('Steinmetz');

SELECT * FROM s WHERE daitch_mokotoff(nm) &amp;&amp; daitch_mokotoff('Swartzenegger');
SELECT * FROM s WHERE daitch_mokotoff(nm) &amp;&amp; daitch_mokotoff('Jane');
SELECT * FROM s WHERE daitch_mokotoff(nm) &amp;&amp; daitch_mokotoff('Jens');
</programlisting>

<para>
若要对任意数量、任意顺序的名字进行索引和匹配,可以使用全文检索功能。
见 <xref linkend="textsearch"/> 以及下面的示例:
</para>

<programlisting>
CREATE FUNCTION soundex_tsvector(v_name text) RETURNS tsvector
BEGIN ATOMIC
SELECT to_tsvector('simple',
string_agg(array_to_string(daitch_mokotoff(n), ' '), ' '))
FROM regexp_split_to_table(v_name, '\s+') AS n;
END;

CREATE FUNCTION soundex_tsquery(v_name text) RETURNS tsquery
BEGIN ATOMIC
SELECT string_agg('(' || array_to_string(daitch_mokotoff(n), '|') || ')', '&amp;')::tsquery
FROM regexp_split_to_table(v_name, '\s+') AS n;
END;

CREATE TABLE s (nm text);
CREATE INDEX ix_s_txt ON s USING gin (soundex_tsvector(nm)) WITH (fastupdate = off);

INSERT INTO s (nm) VALUES
('John Doe'),
('Jane Roe'),
('Public John Q.'),
('George Best'),
('John Yamson');

SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('john');
SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('jane doe');
SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('john public');
SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('besst, giorgio');
SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('Jameson John');
</programlisting>

<para>
如果希望在索引重新检查时避免重新计算 soundex 代码,可以使用单独列上的索引
来代替表达式索引。为此可使用存储生成列;参见
<xref linkend="ddl-generated-columns"/>。
</para>
</sect2>


<sect2 id="fuzzystrmatch-levenshtein">
<title>Levenshtein</title>

Expand All @@ -244,10 +100,10 @@ SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('Jameson John');
</indexterm>

<synopsis>
levenshtein(source text, target text, ins_cost int, del_cost int, sub_cost int) 返回 int
levenshtein(source text, target text) 返回 int
levenshtein_less_equal(source text, target text, ins_cost int, del_cost int, sub_cost int, max_d int) 返回 int
levenshtein_less_equal(source text, target text, max_d int) 返回 int
levenshtein(text source, text target, int ins_cost, int del_cost, int sub_cost) 返回 int
levenshtein(text source, text target) 返回 int
levenshtein_less_equal(text source, text target, int ins_cost, int del_cost, int sub_cost, int max_d) 返回 int
levenshtein_less_equal(text source, text target, int max_d) 返回 int
</synopsis>

<para>
Expand Down Expand Up @@ -313,7 +169,7 @@ test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
</indexterm>

<synopsis>
metaphone(source text, max_output_length int) 返回 text
metaphone(text source, int max_output_length) 返回 text
</synopsis>

<para>
Expand Down Expand Up @@ -354,8 +210,8 @@ test=# SELECT metaphone('GUMBO', 4);
</indexterm>

<synopsis>
dmetaphone(source text) 返回 text
dmetaphone_alt(source text) 返回 text
dmetaphone(text source) 返回 text
dmetaphone_alt(text source) 返回 text
</synopsis>

<para>
Expand Down
35 changes: 1 addition & 34 deletions zh/14/passwordcheck.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -51,38 +51,5 @@
</para>
</caution>

<sect2 id="passwordcheck-configuration-parameters">
<title>配置参数</title>

<variablelist>
<varlistentry>
<term>
<varname>passwordcheck.min_password_length</varname> (<type>integer</type>)
<indexterm>
<primary><varname>passwordcheck.min_password_length</varname> 配置参数</primary>
</indexterm>
</term>
<listitem>
<para>
可接受的最小密码长度(按字节计)。默认值为 8。只有超级用户才能更改此设置。
</para>
<note>
<para>
如果用户提供的是预加密密码,则该参数不起作用。
</para>
</note>
</listitem>
</varlistentry>
</variablelist>

<para>
在通常使用时,该参数设置在 <filename>postgresql.conf</filename> 中,但超级用户也可以在自己的会话中动态修改它。典型用法如下:
</para>

<programlisting>
# postgresql.conf
passwordcheck.min_password_length = 12
</programlisting>
</sect2>


</sect1>
Loading