PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

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

F.20.1. 数据类型
F.20.2. 类型转换
F.20.3. 函数与操作符
F.20.4. 配置参数
F.20.5. 示例
F.20.6. 参考文献
F.20.7. 作者

isn 模块为以下国际产品编号标准提供数据类型:EAN13、UPC、ISBN(图书)、ISMN(音乐)与 ISSN(连续出版物)。输入时会根据一个硬编码的前缀列表进行校验;该前缀列表也用于在输出时为编号添加连字符。由于新前缀会不时被分配,该前缀列表可能过时。本模块的未来版本有望从一个或多个表中获取前缀列表,以便用户可以按需轻松更新;但目前,该列表只能通过修改源码并重新编译来更新。另一种可能的做法是,本模块的未来版本直接移除前缀校验与连字符支持。

该模块被视为“可信”模块,也就是说,拥有当前数据库 CREATE 权限的非超级用户也可以安装它。

F.20.1. 数据类型 #

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

Table 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 位整数),并且都可以互换。提供多种类型是为了控制显示格式,并对应当表示某一特定类型编号的输入执行更严格的校验。

ISBN、ISMN 与 ISSN 类型在可能时显示编号的短版本(ISxN 10),对于不适合短版本的编号则显示 ISxN 13 格式。EAN13、ISBN13、ISMN13 与 ISSN13 类型始终显示 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 树与哈希索引支持。此外还有几个专用函数,见 Table F.11。在该表中,isn 表示模块的任意一种数据类型。

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

实现该模块的信息收集自多个网站,包括:

用于连字的前缀也编译自:

算法编写过程中颇为用心,并且与官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致核对。

F.20.7. 作者 #

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

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