isn
模块为下列国际产品编号标准提供数据类型:EAN13、UPC、ISBN(图书)、ISMN(音乐)和 ISSN(期刊)。针对输入的数字,将根据硬编码的前缀列表进行验证;此外,还会使用此前缀列表对输出的数字进行连字符分隔。由于会时不时分配新前缀,因此前缀列表可能不是最新的。我们希望此模块未来版本可以从一个或多个表中获取前缀列表,以便用户可根据需要轻松更新;但是,目前只能通过修改源代码并重新编译来更新列表。或者,未来的此模块版本可能会放弃前缀验证和连字符分隔支持。
此模块被视为 “可信”,也就是说,具备当前数据库上 CREATE
权限的非超级用户可以安装此模块。
表 F.10 显示了 isn
模块提供的数据类型。
表 F.10. isn
数据类型
数据类型 | 说明 |
---|---|
EAN13 |
欧洲商品编号,始终以 EAN13 显示格式显示 |
ISBN13 |
要以新的 EAN13 显示格式显示的国际标准书号 |
ISMN13 |
要以新的 EAN13 显示格式显示的国际标准音乐号 |
ISSN13 |
要以新的 EAN13 显示格式显示的国际标准连续出版物号 |
ISBN |
以旧的简短显示格式显示的国际标准书号 |
ISMN |
以旧的简短显示格式显示的国际标准音乐号 |
ISSN |
以旧的简短显示格式显示的国际标准连续出版物号 |
UPC |
通用产品代码 |
一些注释
ISBN13、ISMN13 和 ISSN13 是 EAN13 号码。
EAN13 号码不始终是 ISBN13、ISMN13 或 ISSN13 号码(部分号码是)。
部分 ISBN13 号码可以显示为 ISBN。
部分 ISMN13 号码可以显示为 ISMN。
部分 ISSN13 号码可以显示为 ISSN。
UPC 号码是 EAN13 号码的子集(基本上,UPC 是没有第一个 0
数字的 EAN13)。
所有 UPC、ISBN、ISMN 和 ISSN 号码都可以表示为 EAN13 号码。
在内部,所有这些类型均使用相同的表示形式(64 位整数),并且都可互换。提供多种类型以控制显示格式,并允许对假定表示特定类型数字的输入进行更严格的有效性检查。
在可能的情况下,ISBN
、ISMN
和 ISSN
类型将显示该数字的简短版本(ISxN 10),并且会为不适合该简短版本的数字显示 ISxN 13 格式。EAN13
、ISBN13
、ISMN13
和 ISSN13
类型始终会显示 ISxN(EAN13)的长版本。
isn
模块提供以下类型的强制转换对
ISBN13 <=> EAN13
ISMN13 <=> EAN13
ISSN13 <=> EAN13
ISBN <=> EAN13
ISMN <=> EAN13
ISSN <=> EAN13
UPC <=> EAN13
ISBN <=> ISBN13
ISMN <=> ISMN13
ISSN <=> ISSN13
执行从 EAN13
到其他类型的强制转换时,会对值是否在此其他类型的范围内进行运行时检查,如果值不在此范围内,则会抛出错误。其他强制转换只是会始终成功的重新标记。
isn
模块提供标准比较运算符,以及对所有这些数据类型进行 B-tree 和哈希索引支持。此外还有若干专门函数;如 表 F.11 所示。在此表中,isn
表示模块的任何一种数据类型。
表 F.11. isn
函数
弱模式用于将无效数据插入到表中。无效表示校验数字错误,而不是存在丢失的数字。
您为什么要使用弱模式?好吧,可能是您拥有一个巨大的 ISBN 号码集合,而且其中有很多号码,由于某些原因,其中某些号码的校验位是错误的(可能是从打印列表中扫描的号码,且 OCR 获取的号码是错误的,可能是手动获取的号码……谁知道呢)。不管怎样,重点是您可能想清理混乱,但仍然希望能够将所有号码保存在数据库中,并且可能使用外部工具查找数据库中的无效号码,以便更容易地验证和确认信息;因此,例如您需要选择表中的所有无效号码。
当您在弱模式下将无效号码插入表中时,将使用更正的校验位插入号码,但它将在末尾显示一个感叹号 (!
),例如 0-11-000322-5!
。此无效标记可以使用 is_valid
函数进行检查,并使用 make_valid
函数进行清除。
您还可以强制插入无效号码,即使不在弱模式下,方法是在号码末尾附加 !
字符。
另一个特殊功能是,在输入期间,您可以在校验位的位置输入 ?
,正确的校验位将自动插入。
--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;
有关实施此模块的信息是从包括以下内容在内的多个网站收集的
用于连字号的前缀也是从以下内容编译的
在创建算法的过程中,人们很谨慎,并且根据官方 ISBN、ISMN、ISSN 用户手册中的建议算法对其进行了细致的验证。