在这篇文章中,我们将讨论 Manticore Search 3.0 中文档 ID 数据类型的变化。
在之前的版本中,文档 ID 是无符号大整数。在 3.0 中,我们切换到有符号大整数。这个决定的原因是使文档 ID 与 bigint 属性保持一致,因为大多数情况下即使是有符号大整数也应该足够,而且我们正在朝着自动生成 ID 的方向发展。
然而在一些少见的情况下,这个变化可能会成为一个问题,在本文中,我们将更详细地了解这种差异以及如果出现问题如何克服它。
无符号大整数支持的值在 0 和 18,446,744,073,709,551,615 ( 264-1) 之间,而有符号大整数可以取值在 −9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 ( −263 到 263−1)。有符号的正范围足够容纳大数据集(至少没有已知的 Manticore 集合超过惊人的 9+ 万亿文档)。问题只会在文档 ID 不是递增的值,而是使用无符号大整数的哈希时发生。对于这些情况,如果不可能切换到可以适应有符号类型的哈希,可以使用简单的转换来存储和检索哈希,具体说明如下。
在实时索引的情况下,支持自动生成 ID 的功能将很快添加。在 RT 文档 ID 不是来自数据库的 ID,而只是生成的(通过哈希或其他方法)情况下,当自动生成发生在 Manticore 的一侧时,事情将变得更加简单。
为什么不支持两种数据类型?
在 Manticore 中支持有符号和无符号 ID 会导致更多麻烦而不是帮助。例如,一些客户端对响应中预期的数据类型非常严格。在响应中发送无符号 ID 将会引起很多混淆,因为客户端被指示预期为有符号大整数。
如何处理这个变化?
为了与 Manticore Search 中的变化保持一致,文档 ID 类型可能需要在您的应用程序和数据源中进行更改。如果 ID 存储在数据库中,但它们从未达到正的有符号范围( 263 -1),那么事情就简单了:只需将列转换为有符号。如果您的 ID 超过了该值,则需要将数字转换为有符号范围。
超出有符号正范围( 263 -1)的值可以通过从它们中减去 264 来作为负数,这将把 263(有符号正范围内的第一个数字)转换为 -263,并将 264-1(最大的无符号大整数)转换为 -1。如果您是基于返回无符号大整数的哈希函数生成 ID,这也可以用于此。
例如,在 MySQL 中,要将无符号大整数转换为适合有符号大整数,我们可以使用 IF (id>>63, -(~id) - 1, id)
。要将“映射”后的有符号数字转换回无符号,我们可以使用 IF (signed_id<0, ~0^~signed_id, signed_id)
。使用位函数的原因是 MySQL 仅支持位函数处理超过 9223372036854775807(63 位)的数字。
SELECT id, if (id>>63, -(~id) - 1, id) AS mapped_to_signed,
signed_id, if (signed_id<0, ~0^~signed_id, signed_id) AS unsigned_from_mapped
FROM test ORDER BY id
id | unsigned_to_mapped | signed_id | unsigned_from_mapped |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 |
9223372036854775807 | 9223372036854775807 | 9223372036854775807 | 9223372036854775807 |
9223372036854775808 | -9223372036854775808 | -9223372036854775808 | 9223372036854775808 |
9223372036854775809 | -9223372036854775807 | -9223372036854775807 | 9223372036854775809 |
18446744073709551613 | -3 | -3 | 18446744073709551613 |
18446744073709551614 | -2 | -2 | 18446744073709551614 |
18446744073709551615 | -1 | -1 | 18446744073709551615 |
我们知道这个变化可能会带来一些麻烦,但这是一次性变化,必须执行以享受最新的 Manticore Search。