2024 年 9 月 26 日: PostgreSQL 17 发布!
支持版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持版本: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 编号的子集(它们基本上是没有首位 0 数字的 EAN13)。

  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 树和哈希索引支持。此外,还有一些专门的函数;如 表 F.11 所示。在本表中,isn 表示模块的任何一种数据类型。

表 F.11. isn 函数

函数

描述

isn_weak ( boolean ) → boolean

设置“弱输入”模式,并返回新设置。

isn_weak () → boolean

返回“弱模式”的当前状态。

make_valid ( isn ) → isn

验证无效编号(清除无效标记)。

is_valid ( isn ) → boolean

检查是否存在无效标记。


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

为什么要使用“弱模式”?嗯,这可能是因为您拥有大量的 ISBN 编号,而且数量如此之多,以至于由于各种奇怪的原因,其中一些编号的校验位错误(可能是这些编号是从印刷清单中扫描的,OCR 识别错误,可能是这些编号是手动输入的……谁知道呢)。总之,关键是您可能希望清理这些混乱,但您仍然希望能够将所有编号都保存在数据库中,并可能使用外部工具来定位数据库中的无效编号,以便您可以更轻松地验证信息并进行有效性检查;因此,例如,您可能希望选择表中所有无效的编号。

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

您还可以强制插入无效编号,即使不在“弱模式”下,也可以通过在编号末尾添加 ! 字符来实现。

另一个特殊功能是在输入过程中,您可以用 ? 代替校验位,正确的校验位将自动插入。

F.20.4. 示例 #

--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.20.5. 参考文献 #

用于实现该模块的信息是从多个网站收集的,包括

用于分隔的“前缀”也是从以下网站编译的

在创建算法时非常谨慎,并且已对照 ISBN、ISMN、ISSN 用户手册中建议的算法对其进行了仔细验证。

F.20.6. 作者 #

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

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

提交更正

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