F.19. isn
isn
模块为下列的国际产品编号标准提供数据类型:EAN13, UPC, ISBN (books), ISMN (music), and ISSN (serials)。编号在输入时是经过确认的,根据一个前缀的硬编码列表; 这个前缀列表也用于在输出时连接编号。因为不时地分配新的前缀,所以前缀列表可能过期。 希望这个模块的将来版本可以根据需要,从一个或多个可以通过用户容易更新的表中获得前缀列表; 不过,目前该列表只能通过修改源代码和重新编译来更新。或者,在这个模块的将来版本中, 前缀确认或连接支持可能会被删除。
F.19.1. 数据类型
Table F-10显示了isn
模块支持的数据类型。
Table 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(通用产品条码) |
一些备注:
ISBN13, ISMN13, ISSN13编号都是EAN13编号。
EAN13编号并不总是ISBN13, ISMN13 或 ISSN13(有些是)。
一些ISBN13编号可以以ISBN显示。
一些ISMN13编号可以以ISMN显示。
一些ISSN13编号可以以ISSN显示。
UPC编号是EAN13编号的一个子集(它们基本上是没有第一个
0
数字的EAN13)。所有UPC, ISBN, ISMN 和 ISSN编号都可以用EAN13编号表示。
在内部,所有这些类型使用相同的表示(一个64位整数),并且所有类型相互之间可以转换。 提供多种类型控制显示格式和允许对应该表示一个编号的特定类型的输入更严格的有效性检查。
ISBN
, ISMN
, 和 ISSN
类型将在可能时显示编号的短版本(ISxN 10), 不适合端版本的编号显示ISxN 13格式。EAN13
, ISBN13
, ISMN13
和ISSN13
类型总是显示ISxN的长版本(EAN13)。
F.19.2. 转换
isn
模块支持下列的类型转换对:
ISBN13 <=> EAN13
ISMN13 <=> EAN13
ISSN13 <=> EAN13
ISBN <=> EAN13
ISMN <=> EAN13
ISSN <=> EAN13
UPC <=> EAN13
ISBN <=> ISBN13
ISMN <=> ISMN13
ISSN <=> ISSN13
当从EAN13
转换到其他类型时,有一个运行时检查,值在其他类型的领域内, 如果不在则抛出一个错误。其他转换只是简单的确认,总是会成功。
F.19.3. 函数和操作符
isn
模块提供标准的比较运算符,加上B-tree和哈希索引支持所有的这些数据类型。 另外,有几个专门的函数;显示在Table F-11中。在这个表中, isn
意为模块的数据类型之一。
Table 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
代码。