isn
模块提供以下国际产品编号标准的数据类型:EAN13、UPC、ISBN(图书)、ISMN(音乐)和 ISSN(期刊)。根据硬编码的前缀列表在输入时验证编号;此前缀列表还用于在输出时对编号进行连字符分隔。由于会不时分配新的前缀,因此前缀列表可能已过时。希望此模块的未来版本将从一个或多个表中获取前缀列表,以便用户可以根据需要轻松更新;但是,目前只能通过修改源代码并重新编译来更新列表。或者,此模块的未来版本可能会取消前缀验证和连字符分隔支持。
此模块被认为是 “可信” 的,也就是说,它可以由在当前数据库上拥有 CREATE
权限的非超级用户安装。
表 F.11 显示了 isn
模块提供的数据类型。
表 F.11. 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 号码的子集(它们基本上是 EAN13,没有第一个 0
数字)。
所有 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 树和哈希索引支持。此外,还有几个专门的函数;如 表 F.12 所示。在此表中,isn
表示模块的任何一种数据类型。
表 F.12. 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 用户手册中建议的算法对它们进行了仔细验证。