Skip to content
Sergey Glazunov edited this page Oct 29, 2020 · 22 revisions

Model

Схема базы данных (графическое представление нереляционной модели данных)

model

Коллекции:

  • Node
  • Way
  • Relation

Описание назначений коллекций

Название Описание
Node Содержит информацию о точках на карте
Way Содержит информацию о дорогах на карте
Relation Содержит информацию о связях дорог и точек

Описание назначений коллекций

Node

Название Тип данных Описание
_id ObjectID id точки
lon Numbers Долгота точки
lat Numbers Ширина точки
in_ways Array Пути в которых есть это нода

Way

Название Тип данных Описание
_id ObjectID id дороги
nodes Array список id точек
traffic Numbers состояние дороги(пробка)

Relation

Название Тип данных Описание
_id ObjectID id отношения
memders Array id участников(дорога/точка) отношения

Удельный объем информации. Оценка удельного объема информации, хранимой в модели

В графическом представлении NoSQL и SQL версии нашей модели совпадают.

Type Size
Objectid 12 bytes
Numbers 8 bytes
String 4 bytes

Размер одного Node = 12 + 2*8 + ways_with_nodes * 8

Размер одного Way = 12 + 8 + length_nodes_in_way * 12 + length_tags_in_way * legnth_string_of_tag

Размер одного Relation = 12 + 8 * length_nodes_and_ways_in_relation + length_tags_in_relation * legnth_string_of_tag

Так как количество тегов сильно разнится от объекта к объекту, то нельзя посчитать среднее для него. Также можно сказать и про количество id, которые хранятся в объектах. Поэтому выше описана конечная версия оценки размера бд

Объем нашей БД не может быть статичным, но можно посчитать, от чего он будет зависеть.

На основе этого общий объем БД составляет:

N * (12 + 2*8 + ways_with_nodes * 8) + M * (12 + 8 + length_nodes_in_way * 12 + length_tags_in_way * legnth_string_of_tag) + L * (12 + 8 * length_nodes_and_ways_in_relation + length_tags_in_relation * legnth_string_of_tag), N, M, L >= 0.

N - кол-во Node.

M - кол-во Way. (M ~ N/3)

L - кол-во Relation. (L ~ N/100)

Total = N * (12B + 2*8B + ways_with_nodes(~4) * 8B + 4B * 10) + N/3 * (12B + 8B + length_nodes_in_way(~2) * 12B + length_tags_in_way(~5) * legnth_string_of_tag(~10) * 4B) + N/100 * (12B + 8B * length_nodes_and_ways_in_relation (~4) + length_tags_in_relation (~5) * legnth_string_of_tag(~10) * 4B) = N * 100B + N/3 * 244B + N/100 * 244B = N * 183B

Избыточность модели

Избыточность данных в in_ways в Node. Это сделано для ускорения поиска путей, в которых лежит данная точка. То есть избыточная часть составляет - N * (4 * 8)B = 32B * N.

Чистый объем - 151B.

Запросы

  1. Поиск всех узлов, с координатами в определенном квадрате со стороной FIND_RANGE, которые являются частью какого-то пути
dbnodes.find({
        'lon': {
            '$gt': y - FIND_RANGE,
            '$lt': y + FIND_RANGE
        },
        'lat': {
            '$gt': x - FIND_RANGE,
            '$lt': x + FIND_RANGE
        },
        'in_ways': {
            '$ne': []
        }
    })

SQL:

SELECT * FROM nodes
WHERE (nodes.lon > y - FIND_RANGE) AND (nodes.lon < y + FIND_RANGE)
AND (nodes.lat > x - FIND_RANGE) AND (nodes.lat < x + FIND_RANGE) AND (EXISTS(nodes_in_ways))
  1. Поиск пути по id
db.ways.find_one({'_id': way_id}) 

SQL:

SELECT * FROM ways
WHERE ways._id = way_id
  1. Поиск узла по id
db.nodes.find_one({'_id': node_id})

SQL:

SELECT * FROM nodes
WHERE nodes._id = node_id
  1. Поиск всех объектов - relations, в которые включен конкретный объект
db.relations.find({'members.ref': {'$all': [id]}})

SQL:

SELECT * FROM relations
INNER JOIN members WHERE id in members.ref
  1. Поиск всех путей, которые проходят через данный узел
db.ways.find({'nodes': {'$all': [id]}}) 

SQL:

SELECT * FROM ways
WHERE id in ways.nodes
  1. Изменить список путей, частью которых является данный узел
dbnodes.update_one(
            {'_id': node_id},
            {'$set':
                 {'in_ways': n_ways}
             }) 

SQL:

UPDATE nodes
SET in_ways = n_ways
WHERE _id = node_id
  1. Сохранение узлов, путей, отношений в коллекции
self.db.nodes.save({'_id': id,
                      'lon': lon,
                      'lat': lat,
                      'in_ways': []})

self.db.ways.save({'_id': id, 'nodes': nodes,'avg_speed': 0, 'tags': tags})

self.db.relations.save({'_id': id, 'members': members 'tags': tags})

SQL:

INSERT INTO nodes
VALUES (id, lon, lat, [])


INSERT INTO ways
VALUES (id, nodes, 0, tags)


INSERT INTO nodes
VALUES (id, members, tags)

SQL Graphic

Объем

Объем реляционной базы данных будет отличаться лишь в тегах. Именно: - N/4 * 200B - N/100 * 200B + 4B * (N + N/4 + N/100) = -40B *N. Total V = 143B * N

Вывод

  • SQL показывает себя лучше, чем NoSQL по объему.
  • В SQL реализации модели данных пришлось бы создавать дополнительные таблицы для связей, что увеличивает суммарное количество создаваемых таблиц.
  • Количество запросов, необходимых для выполнения юзкейсов в SQL модели больше.