我正在尝试使用LineString和Point进行IPv6地址范围匹配。但我认为这个问题更多地与MySQL如何处理大数精度有关。(请注意,以下使用较小数字的工作没有问题,即IPv4十进制表示法)。
对于IPv4,范围定义为LineString(Point(-1, ip_start), Point(1, ip_end))
。
在创建包含大量数字的Point()
时,我似乎失去了精度,因此我的范围匹配是有缺陷的。
MariaDB [mydb]> set @point=Point(0, 42541828702485584113142439188939931648);
Query OK, 0 rows affected (0.00 sec)
MariaDB [mydb]> select astext(@point);
+-------------------------------+
| astext(@point) |
+-------------------------------+
| POINT(0 4.254182870248558e37) |
+-------------------------------+
1 row in set (0.00 sec)
MariaDB [mydb]> select st_y(@point);
+----------------------+
| st_y(@point) |
+----------------------+
| 4.254182870248558e37 |
+----------------------+
1 row in set (0.00 sec)
MariaDB [mydb]> select cast(st_y(@point) as Decimal(39));
+----------------------------------------+
| cast(st_y(@point) as Decimal(39)) |
+----------------------------------------+
| 42541828702485580000000000000000000000 |
+----------------------------------------+
1 row in set (0.00 sec)
MariaDB [mydb]>
如何准确地使用大数的Point()
?
发布于 2019-09-11 13:15:33
SPATIAL
函数(st_x
、point
等)适用于DOUBLEs
,而不是DECIMAL
。
DECIMAL(39)
应该可以工作。但为什么不直接将其保留为字符串或十六进制字符串(VARCHAR(39) CHARACTER SET ascii
)或BINARY(16)
请解释你的最终目标是什么让你想要使用空间工具。
下面是处理IP地址范围的代码( IPv4或IPv6的单独代码):http://mysql.rjweb.org/doc.php/ipranges
https://stackoverflow.com/questions/57882415
复制相似问题