瑞安·兰伯特:ltree能否用于嵌套地点数据?

💡 原文英文,约800词,阅读约需3分钟。
📝

内容提要

本文讨论了使用ltree数据类型处理嵌套地点数据的可行性。作者尝试将OpenStreetMap数据存储为嵌套的多边形数据,并探索了ltree是否适用于此目的。然而,ltree对字符的限制以及对负数BIGINT的不支持使其不适合处理OpenStreetMap数据。尽管可以通过删除不支持的字符来解决部分问题,但这并不理想。作者认为在当前情况下,使用ltree并不能提供所需的可用性优势。

🔎

延伸解读

ltree 的字符限制与 OSM 数据冲突

ltree 标签仅接受有限范围的字母数字字符,空格不被支持。OpenStreetMap 中的地点名称常包含空格(如“United States”),直接转换为 ltree 会导致语法错误。虽然可以删除空格,但这需要在查询逻辑中增加额外处理层,影响使用便利性。

负数 BIGINT 主键无法用于 ltree

PgOSM Flex 沿用 OpenStreetMap 的惯例,用正数 ID 表示节点和路径,负数 ID 表示关系。但 ltree 不支持负数 BIGINT,例如 '-1.2.-5'::ltree 会触发语法错误。因此,无法直接利用现有的 BIGINT 主键来构建 ltree 路径。

国际字符支持但特殊符号仍是障碍

测试表明 ltree 可以处理国际字符,如 'hello.横浜市' 能成功转换。然而,像 '#' 这样的特殊符号仍会导致语法错误。OSM 数据中常出现此类符号,若要通过 ltree 使用,必须预先清理所有不支持的字符,这增加了数据处理的复杂性。

改造数据以适应 ltree 的代价过高

作者认为,虽然技术上可以通过修改数据(如删除空格和特殊字符、创建新键)来适配 ltree,但这会影响所有查询方式,并增加不必要的复杂性。最终,作者判断在当前场景下,ltree 无法提供所需的可用性优势,因此不适合用于 OpenStreetMap 的嵌套地点数据。

❓

Q&A

ltree数据类型适合用来存储OpenStreetMap的嵌套地点数据吗?

不适合。ltree对字符的限制以及对负数BIGINT的不支持使其不适合处理OpenStreetMap数据。

ltree对字符有什么限制?

ltree标签仅接受有限范围的字母数字字符,具体范围取决于数据库locale,例如在C locale下允许A-Za-z0-9_-,空格不被支持。

为什么负数BIGINT不能用于ltree?

因为负数BIGINT会导致ltree语法错误,例如'-1.2.-5'::LTREE会报错。

PgOSM Flex目前如何存储嵌套地点数据?

PgOSM Flex使用TEXT[]和BIGINT[]数组列来存储嵌套多边形数据,例如{"United States","Colorado"}。

ltree支持国际字符吗?

支持。例如'hello.横浜市'::ltree可以正常工作。

作者尝试了哪些方法使ltree适用于OpenStreetMap数据?

作者尝试删除空格和不支持的字符,以及考虑使用BIGINT主键,但都因ltree的限制而失败。

➡️

继续阅读