2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.20. isn — 国际标准编号(ISBN、EAN、UPC 等)的数据类型 #

isn 模块提供了以下国际产品编号标准的 数据类型:EAN13、UPC、ISBN(图书)、ISMN(音乐)和 ISSN(期刊)。数字在输入时会根据硬编码的前缀列表进行验证;此前缀列表也用于在输出时进行连字符添加。由于前缀会不时分配新号码,因此前缀列表可能已过时。希望该模块的未来版本能够从一个或多个易于用户根据需要更新的表中获取前缀列表;然而,目前,只能通过修改源代码并重新编译来更新列表。或者,前缀验证和连字符支持可能会从该模块的未来版本中删除。

此模块被认为是受信任的,这意味着非超级用户也可以在其拥有的数据库上安装它,前提是他们具有 CREATE 权限。

F.20.1. 数据类型 #

表 F.10 显示了 isn 模块提供的数据类型。

表 F.10. isn 数据类型

数据类型 描述
EAN13 欧洲商品编码,始终以 EAN13 显示格式显示
ISBN13 国际标准书号,将以新的 EAN13 显示格式显示
ISMN13 国际标准音乐号,将以新的 EAN13 显示格式显示
ISSN13 国际标准连续出版物号,将以新的 EAN13 显示格式显示
ISBN 国际标准书号,将以旧的短格式显示
ISMN 国际标准音乐号,将以旧的短格式显示
ISSN 国际标准连续出版物号,将以旧的短格式显示
UPC 万国码

一些说明

  1. ISBN13、ISMN13、ISSN13 号码都是 EAN13 号码。

  2. EAN13 号码不总是 ISBN13、ISMN13 或 ISSN13(有些是)。

  3. 某些 ISBN13 号码可以显示为 ISBN。

  4. 某些 ISMN13 号码可以显示为 ISMN。

  5. 某些 ISSN13 号码可以显示为 ISSN。

  6. UPC 号码是 EAN13 号码的子集(它们基本上是 EAN13 号码去掉开头的 0 位数字)。

  7. 所有 UPC、ISBN、ISMN 和 ISSN 号码都可以表示为 EAN13 号码。

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

当可能时,ISBNISMNISSN 类型将显示编号的短版本(ISxN 10),而对于不适合短版本的编号,将显示 ISxN 13 格式。而 EAN13ISBN13ISMN13ISSN13 类型将始终显示 ISxN 的长版本(EAN13)。

F.20.2. 转换 #

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

  • ISBN13 <=> EAN13

  • ISMN13 <=> EAN13

  • ISSN13 <=> EAN13

  • ISBN <=> EAN13

  • ISMN <=> EAN13

  • ISSN <=> EAN13

  • UPC <=> EAN13

  • ISBN <=> ISBN13

  • ISMN <=> ISMN13

  • ISSN <=> ISSN13

当从 EAN13 转换为其他类型时,会在运行时检查该值是否在该类型的域内,如果不是,则会抛出错误。其他转换只是标签的重新分配,并且总是会成功。

F.20.3. 函数和运算符 #

模块 isn 提供了标准的比较运算符,以及对所有这些数据类型的 B-tree 和 hash 索引支持。此外,还有几个专用函数,如 表 F.11 所示。在此表中,isn 表示模块中的任何一种数据类型。

表 F.11. isn 函数

函数

描述

make_valid ( isn ) → isn

清除值中的无效校验位标志。

is_valid ( isn ) → boolean

检查是否存在无效校验位标志。

isn_weak ( boolean ) → boolean

设置弱输入模式,并返回新设置。保留此函数是为了向后兼容。设置弱模式的推荐方法是通过 isn.weak 配置参数。

isn_weak () → boolean

返回弱模式的当前状态。保留此函数是为了向后兼容。检查弱模式的推荐方法是通过 isn.weak 配置参数。


F.20.4. 配置参数 #

isn.weak (boolean) #

isn.weak 启用弱输入模式,该模式允许在 ISN 输入值校验位错误时也接受它们。默认值为 false,会拒绝无效的校验位。

为什么您想使用弱模式?嗯,可能是因为您拥有大量 ISBN 号码,并且由于一些奇怪的原因,其中一些号码的校验位是错误的(也许号码是从打印列表中扫描的,OCR 错误地读取了号码,也许号码是手动输入的……谁知道呢)。无论如何,关键是您可能想清理这些混乱,但仍然希望将所有号码都保留在数据库中,并可能使用外部工具来定位数据库中的无效号码,以便您可以更轻松地验证信息并确认其有效性;因此,例如,您可能希望选择表中的所有无效号码。

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

当不处于弱模式时,您也可以通过在号码末尾添加 ! 字符来强制插入标记为无效的号码。

另一个特殊功能是,在输入时,您可以用 ? 替换校验位,系统会自动插入正确的校验位。

F.20.5. 示例 #

--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:
SET isn.weak TO true;
INSERT INTO test VALUES('978-0-11-000533-4');
INSERT INTO test VALUES('9780141219307');
INSERT INTO test VALUES('2-205-00876-X');
SET isn.weak TO 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.20.6. 参考文献 #

实现此模块的信息来自多个网站,包括

用于连字符的prefixes也是从以下网站收集的

在创建算法时非常谨慎,并且它们已根据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了仔细验证。

F.20.7. 作者 #

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

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

提交更正

如果您在文档中发现任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。