F.19. isn

isn模块为下列的国际产品编号标准提供数据类型:EAN13, UPC, ISBN (books), ISMN (music), and ISSN (serials)。编号在输入时是经过确认的,根据一个前缀的硬编码列表; 这个前缀列表也用于在输出时连接编号。因为不时地分配新的前缀,所以前缀列表可能过期。 希望这个模块的将来版本可以根据需要,从一个或多个可以通过用户容易更新的表中获得前缀列表; 不过,目前该列表只能通过修改源代码和重新编译来更新。或者,在这个模块的将来版本中, 前缀确认或连接支持可能会被删除。

F.19.1. 数据类型

表 F-10显示了isn模块支持的数据类型。

表 F-10. isn 数据类型

数据类型描述
EAN13 European Article Numbers(欧洲文章号), 总是以 EAN13 显示格式显示
ISBN13 International Standard Book Numbers(国际标准书号),以新EAN13显示格式显示
ISMN13 International Standard Music Numbers(国际标准音乐号),以新EAN13显示格式显示
ISSN13 International Standard Serial Numbers(国际标准序列号),以新EAN13显示格式显示
ISBN International Standard Book Numbers(国际标准书号),以旧的短显示格式显示
ISMN International Standard Music Numbers(国际标准音乐号),以旧的短显示格式显示
ISSN International Standard Serial Numbers(国际标准序列号),以旧的短显示格式显示
UPC Universal Product Codes(通用产品条码)

一些备注:

  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, ISMN13ISSN13类型总是显示ISxN的长版本(EAN13)。

F.19.2. 转换

isn模块支持下列的类型转换对:

当从EAN13转换到其他类型时,有一个运行时检查,值在其他类型的领域内, 如果不在则抛出一个错误。其他转换只是简单的确认,总是会成功。

F.19.3. 函数和操作符

isn模块提供标准的比较运算符,加上B-tree和哈希索引支持所有的这些数据类型。 另外,有几个专门的函数;显示在表 F-11中。在这个表中, isn意为模块的数据类型之一。

表 F-11. isn 函数

函数返回描述
isn_weak(boolean)boolean设置weak输入模式 (返回新的设置)
isn_weak()boolean获取当前 weak 模式的状态
make_valid(isn)isn确认一个无效数字(清除无效标识)
is_valid(isn)boolean检查无效标识的存在

Weak模式用于可以插入无效数据到表中。无效的意思是检查位为wrong, 而不是说它们是丢失的数字。

为什么想要使用weak模式?很好,可能你有一个巨大的ISBN编号的采集,其中的一些因为怪异的原因有wrong检查位 (可能编号是从打印列表扫描进来的,而OCR(光学字符识别)获取编号错误,也或许编号是手动捕获的……谁知道呢)。 无论如何,关键是你可能想要清理这个烂摊子,但是你又想要在你的数据库中有所有的编号, 或许使用一个额外的工具在数据库中定位无效编号,这样你就可以验证信息并使其更容易的生效; 例如你想要在表中选择所有无效编号。

当你使用weak模式插入无效编号到一个表中时,该编号将带有修正的检查位插入, 但是在显示时将在后面带有一个叹号标记(!),例如0-11-000322-5!。 这些无效标记可以用is_valid函数检查然后用make_valid函数清除。

即使不在weak模式下,你也可以强制插入无效编号,通过在编号后面附加!字符。

另一个特别特征是在输入期间,可以在检查位上写?,并且正确的检查位将自动插入。

F.19.4. 例子

--直接使用类型:
SELECT isbn('978-0-393-04002-9');
SELECT isbn13('0901690546');
SELECT issn('1436-4522');

--转换类型:
-- 请注意,你只能从ean13转换到另外一个类型当
-- 数字在目标类型的领域中将会是有效的;
-- 因此下列将不会工作: select isbn(ean13('0220356483481'));
-- 但是他们将:
SELECT upc(ean13('0220356483481'));
SELECT ean13(upc('220356483481'));

--创建一个单个字段的表以保持ISBN编码:
CREATE TABLE test (id isbn);
INSERT INTO test VALUES('9780393040029');

--自动计算校验数位(观察'?'):
INSERT INTO test VALUES('220500896?');
INSERT INTO test VALUES('978055215372?');

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

--使用weak模式:
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.19.5. 参考文献

实施这个模块的信息从几个站点收集而来,包括:

用于连字符的前缀也从下列编译而来:

在算法创建期间要小心,并且他们对在官方 ISBN, ISMN, ISSN 用户手册中建议的算法进行仔细的验证。

F.19.6. 作者

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

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