DBAtlas · Атлас эксплуатации баз данных

Географический / пространственный запрос

Oracle

-- Oracle Spatial: SDO_GEOMETRY column and spatial index
CREATE INDEX location_sidx ON shop(location)
  INDEXTYPE IS MDSYS.SPATIAL_INDEX;
-- Shops within 5 km:
SELECT name FROM shop
WHERE SDO_WITHIN_DISTANCE(location,
  SDO_GEOMETRY(2001, 4326,
    SDO_POINT_TYPE(32.85, 39.92, NULL), NULL, NULL),
  'distance=5 unit=KM') = 'TRUE';

Oracle Spatial хранит географические данные в типе SDO_GEOMETRY; требуются запись USER_SDO_GEOM_METADATA и пространственный индекс. Операторы вроде SDO_WITHIN_DISTANCE, SDO_RELATE и SDO_NN отвечают на запросы расстояния/пересечения/ближайшего соседа. SRID 4326 — система WGS84 (широта/долгота).

PostgreSQL

-- PostGIS extension:
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE INDEX location_gix ON shop USING GIST (location);
-- Shops within 5 km (geography, meters):
SELECT name FROM shop
WHERE ST_DWithin(location,
  ST_SetSRID(ST_MakePoint(32.85, 39.92), 4326)::geography,
  5000);

PostGIS превращает PostgreSQL в полнофункциональную пространственную базу. Он предоставляет типы geometry (плоский) и geography (сферический) и сотни функций ST_, таких как ST_Distance/ST_DWithin/ST_Intersects/ST_Contains. Индекс GiST/SP-GiST ускоряет пространственные запросы.

MySQL

-- Spatial column (with SRID) and SPATIAL index:
ALTER TABLE shop MODIFY location POINT NOT NULL SRID 4326;
ALTER TABLE shop ADD SPATIAL INDEX (location);
-- Compute distance (meters, geography):
SELECT name,
  ST_Distance(location,
    ST_SRID(POINT(32.85, 39.92), 4326)) AS distance
FROM shop
ORDER BY distance LIMIT 10;

MySQL (5.7+) поддерживает соответствующие OGC пространственные типы данных (POINT, POLYGON и т. д.) и функции ST_. Индекс SPATIAL (R-tree) можно создать только в InnoDB/MyISAM и на столбцах NOT NULL; чтобы оптимизатор его использовал, столбец должен быть определён с атрибутом SRID (SRID 4326). С SRID 4326 ST_Distance возвращает геодезическое расстояние в метрах. С POINT(x, y) + ST_SRID x — долгота, y — широта; для ввода WKT (ST_GeomFromText) с SRID 4326 порядок — широта-долгота.

SQL Server

-- geography type and spatial index:
CREATE SPATIAL INDEX location_sidx ON dbo.shop(location);
-- Shops within 5 km (STDistance returns meters):
SELECT name FROM dbo.shop
WHERE location.STDistance(
  geography::Point(39.92, 32.85, 4326)) <= 5000;

SQL Server предлагает два пространственных типа: geography (сферический, широта/долгота) и geometry (плоский). На запросы отвечают методы вроде STDistance, STIntersects и STContains. Пространственный индекс (на основе сетки) повышает производительность. Учитывайте порядок аргументов geography::Point(latitude, longitude, SRID).

MongoDB

// 2dsphere index (for GeoJSON):
db.shop.createIndex({ location: "2dsphere" })
// Shops nearest to a given point ($near):
db.shop.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [32.85, 39.92] },
      $maxDistance: 5000
    }
  }
})

MongoDB хранит географические данные в формате GeoJSON и выполняет сферические запросы с индексом 2dsphere. Поддерживаются операторы $near (сортировка по расстоянию), $geoWithin (внутри области) и $geoIntersects. Координаты — в порядке [долгота, широта]; $maxDistance — в метрах.

Redis

# Built-in geospatial commands (built on sorted sets):
GEOADD shops 32.85 39.92 "kizilay"
GEOADD shops 32.86 39.93 "cankaya"
# Search within 5 km of a point:
GEOSEARCH shops FROMLONLAT 32.85 39.92
  BYRADIUS 5 km ASC

Redis хранит географические координаты в sorted set через GEOADD (longitude latitude member). GEOSEARCH (Redis 6.2+, заменяет старый GEORADIUS) возвращает члены в пределах радиуса или прямоугольника, отсортированные по расстоянию. GEODIST даёт расстояние между двумя точками. Это базовая функция; модуль не нужен.

Elasticsearch

# Map the field as geo_point:
PUT shop
{ "mappings": { "properties": { "location": { "type": "geo_point" } } } }
# Query within 5 km:
GET shop/_search
{ "query": { "geo_distance": {
  "distance": "5km",
  "location": { "lat": 39.92, "lon": 32.85 } } } }

Elasticsearch поддерживает типы полей geo_point (точка) и geo_shape (полигон/линия). Фильтрация выполняется запросами geo_distance (радиус), geo_bounding_box (прямоугольник) и geo_polygon; сортировка — через geo_distance, агрегация — через geohash_grid/geotile_grid. Координаты задаются как lat/lon или массивом [lon, lat].

Открыть в DBAtlas →