我应该为地理位置点创建一个单独的表吗?

Tha*_*sis 5 postgresql database-design spatial routing

我正在为在某些方面类似于 Uber 的服务开发后端(只是为您提供一般上下文的简化)。用户将预订乘车,因此用户将定义接送地点。这些位置将是一个城市的地址(未来可能会有多个城市)。我将从前端/应用程序收到的位置将采用纬度、经度和 google-maps-verified 地址的形式。

我想知道我是否应该将这些位置存储为一个单独的表,或者我是否应该将这些位置嵌入到我需要它们的任何表中。例如,bookings桌子将有一个上车地点和一个下车地点。这些应该只是对locations表的引用,还是应该添加更多列来存储位置?我将需要每个位置至少 3 列(纬度、长度、地址字符串),如果我们决定将街道地址分解为更多组件,则可能会有更多列。

我认为这两种方法在内存和时间性能之间进行权衡:

  • 单独的表将节省一些空间,因为我们避免多次复制相同的信息。但我不确定会节省多少空间,因为我们还没有足够的真实数据。我的大致估计是,一个中等规模的城市有数以万计的唯一地址。因此,如果我们进行 100 次乘车预订,则重叠的可能性很小。如果我们有 100,000 个乘车预订,那么肯定会有相当多的重叠。然而,空间并不是我们设计的真正限制因素,即使有数百万的预订。如果我们在数据库中多花 100MB,这并不重要。
  • 单独的表会使处理速度变慢。首先,每次我们收到预订请求时,我们都必须搜索请求中的位置是否已存在于我们的数据库中。如果没有,我们添加它们,否则我们使用现有的引用。由于我们的数据库中可能有数万个地址,这将需要一些时间。与我们其他耗时的任务相比,这额外的时间是否重要?另一个耗时任务的示例是调用 google-maps api 以查找从一个位置到另一个位置的路线并获得旅行时间估计。我相信此操作将花费比在我们的数据库中搜索更长的时间。因此,当我们遇到其他瓶颈时,优化数据库访问可能没有多大意义。其他操作呢?假设我们想在一个边界 [lat, long] 框中查找预订。使用单独的表可能会变得更加耗时,因为我们需要一个完整的表连接。或者做一个繁琐的两步搜索,在我们的表中找到边界框内的位置 ID,然后搜索bookings带有这些 ID 的表。如果我们在边界框中有数百或数千个位置,这可能不是一个好方法。但同样,我不确定尝试优化此操作的效用。我不确定我需要按位置搜索的频率。似乎不是那么频繁,所以我不会以任何方式获得/失去太多。

在我看来,没有基于时空权衡的有力论据。我还应该考虑其他方面吗?例如:设计清晰、易于开发、灵活性和可扩展性。如果模型需要改变,单独的表格方法似乎提供了更多的结构和更大的灵活性的机会。例如,将街道地址分解为多个组成部分(街道、城市、州)可能是有益的。如果我们要在其他表中使用位置列,我们就不太可能这样做(我们需要已经使用至少 3 列,并且将地址分成 3 个组件,使这个数字变为 5)。关于灵活性:在未来,我们可能会有多点骑行。拥有位置表将对此有所帮助。

我倾向于单独的表格,但我没有看到支持或反对它的有力论据。我还缺少其他论点吗?

不确定以下细节是否相关,但我将使用 postgresql 作为 RDBMS,使用 sqlalchemy 作为 ORM 来查询数据库。

Eva*_*oll 3

在某些方面类似于 Uber [...] 接送地点

所以你需要使用PostGIS和PgRouting。

每个位置至少需要 3 列(纬度、经度、地址字符串)

不,因为长/纬度适合POINT您必须从中生成拓扑的a 。

我想知道是否应该将位置存储为单独的表,

当然,您应该将它们与有关节点的信息一起存储。GIS 只是数据。所有 PostgreSQL 表都位于无序堆中。您不会无缘无故地将表分解为 1:1 关系。geog使用具有列的可为空字段存储您的位置geography(POINT 4326)

如果我们决定将街道地址分成更多部分。

在专业的地理信息系统项目中你不会这样做。您可以让扩展程序address_standardizer为您做这件事。因此,您存储用户输入,然后可以缓存具有stdaddr记录类型的列。

但我不确定会节省多少空间,因为我们还没有足够的真实数据。

我认为你首先关心的应该是如何最好地完成这项任务。我认为您还不够熟悉,无法开始优化。在开始这个项目之前,我建议您先熟悉一下 GIS:

学习内容:~600 页可能会在将来为您节省大量时间。