Postgresql 中文操作指南

F.21. isn — data types for international standard numbers (ISBN, EAN, UPC, etc.) #

isn 模块为以下国际产品编号标准提供数据类型:EAN13、UPC、ISBN(书籍)、ISMN(音乐)和 ISSN(连续出版物)。输入时,该模块根据一个硬编码的前缀列表对号进行验证;此前缀列表还用于在输出时对号进行连字符分隔。由于会时不时分配新的前缀,因此前缀列表可能会过时。我们希望此模块的未来版本将从一个或多个表中获取前缀列表,根据需要,用户可以轻松地对其进行更新;然而,当前,仅当修改源代码并重新编译后才能更新前缀列表。或者,在将来版本的此模块中,可能会取消前缀验证和连字符分隔支持。

此模块被认为是“受信任的”,也就是说,它可以由在当前数据库上具有 CREATE 权限的非超级用户安装。

F.21.1. Data Types #

Table F.11显示了_isn_模块提供的的数据类型。

Table F.11. isn Data Types

Data Type

Description

EAN13

欧共体物品编号,始终以 EAN13 显示格式显示

ISBN13

国际标准书号,采用新的 EAN13 显示格式显示

ISMN13

国际标准音乐号,采用新的 EAN13 显示格式显示

ISSN13

国际标准连续出版物号,采用新的 EAN13 显示格式显示

ISBN

采用旧的短显示格式显示的国际标准书号

ISMN

国际标准音乐号将按照旧的简短显示格式显示

ISSN

国际标准期刊号将按照旧的简短显示格式显示

UPC

Universal Product Codes

一些事项:

在内部,所有这些类型都使用相同的表示(一个 64 位整数),并且所有类型都是可互换的。提供多个类型以控制显示格式,并允许对应该表示某一特定类型的数字的输入进行更严格的有效性检查。

ISBNISMNISSN 类型会在任何可能的情况下显示该数字的短版本(ISxN 10),并且对于不符合短版本的数字,将显示 ISxN 13 格式。EAN13ISBN13ISMN13ISSN13 类型将始终显示 ISxN(EAN13)的长版本。

F.21.2. Casts #

isn 模块提供以下类型转换对:

EAN13 转换为另一个类型时,系统会在运行时检查该值是否在另一类型的域内,如果不是,则会抛出错误。其它类型转换仅仅是重标记,它始终都会成功。

F.21.3. Functions and Operators #

isn 模块提供标准比较运算符,以及 B 树和哈希索引支持以便处理所有这些数据类型。另外还有一些专门函数,如图 Table F.12 中所示。在此数据表中,_isn_表示模块的其中一种数据类型。

Table F.12. isn Functions

Function

Description

isn_weak ( boolean ) → boolean 设置弱输入模式,并返回新的设置。

isn_weak () → boolean 返回弱模式的当前状态。

make_valid ( isn ) → isn 验证无效的号码(清除无效标志)。

is_valid ( isn ) → boolean 检查无效标志的存在。

使用 Weak 模式以便能够将无效数据插入表中。无效表示校验位错误,而不是缺少数字。

为什么要使用弱模式?好吧,可能是您有一大批 ISBN 号码,而且它们的数量如此之多,出于奇怪的原因,有些号码的校验位错误(也许这些号码是从印刷清单中扫描的,OCR 识别错误,也许这些号码是手动捕获的…​ 谁知道呢)。无论如何,重点是您可能想清理这些混乱,但您仍然希望能够拥有数据库中的所有号码,并可能使用外部工具查找数据库中的无效号码,以便您可以验证信息并更轻松地对其进行验证;因此,例如,您将希望选择表中的所有无效号码。

当您使用弱模式将无效号码插入表中时,该号码将使用更正后的校验位插入,但它将在结尾处显示感叹号 (!),例如 0-11-000322-5!。可以使用 is_valid 函数检查此无效标记,并可以使用 make_valid 函数将其清除。

您还可以强制插入无效号码,即使不在弱模式下,方法是在数字末尾添加 ! 字符。

另一个特殊功能是,在输入期间,您可以在校验位的位置写 ?,正确的校验位将自动插入。

F.21.4. Examples #

--Using the types directly:
SELECT isbn('978-0-393-04002-9');
SELECT isbn13('0901690546');
SELECT issn('1436-4522');

--Casting types:
-- note that you can only cast from ean13 to another type when the
-- number would be valid in the realm of the target type;
-- thus, the following will NOT work: select isbn(ean13('0220356483481'));
-- but these will:
SELECT upc(ean13('0220356483481'));
SELECT ean13(upc('220356483481'));

--Create a table with a single column to hold ISBN numbers:
CREATE TABLE test (id isbn);
INSERT INTO test VALUES('9780393040029');

--Automatically calculate check digits (observe the '?'):
INSERT INTO test VALUES('220500896?');
INSERT INTO test VALUES('978055215372?');

SELECT issn('3251231?');
SELECT ismn('979047213542?');

--Using the weak mode:
SELECT isn_weak(true);
INSERT INTO test VALUES('978-0-11-000533-4');
INSERT INTO test VALUES('9780141219307');
INSERT INTO test VALUES('2-205-00876-X');
SELECT isn_weak(false);

SELECT id FROM test WHERE NOT is_valid(id);
UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!';

SELECT * FROM test;

SELECT isbn13(id) FROM test;

F.21.5. Bibliography #

有关实现此模块的信息是从多个站点收集的,包括:

连字符使用的前缀也编译自:

在创建算法的过程中非常谨慎,并根据官方 ISBN、ISMN、ISSN 用户手册中的建议算法对其进行了细致的验证。

F.21.6. Author #

Germán Méndez Bravo (Kronuz),2004-2006

此模块的灵感来自于 Garrett A. Wollman 的 isbn_issn 代码。