Структура базы данных MongoDB и рекомендации по лучшей практике
Я занимаюсь разработкой программного обеспечения для отслеживания маршрутов/оптимизации для моей компании по сбору мусора и хотел бы получить некоторые отзывы о моей текущей структуре данных/ситуации.
Вот упрощенная версия моей структуры MongoDB:
База данных
Коллекции:
"клиенты" - сбор данных, содержащий все данные клиента.
[
{
"cust_id": "1001",
"name": "Customer 1",
"address": "123 Fake St",
"city": "Boston"
},
{
"cust_id": "1002",
"name": "Customer 2",
"address": "123 Real St",
"city": "Boston"
},
{
"cust_id": "1003",
"name": "Customer 3",
"address": "12 Elm St",
"city": "Boston"
},
{
"cust_id": "1004",
"name": "Customer 4",
"address": "16 Union St",
"city": "Boston"
},
{
"cust_id": "1005",
"name": "Customer 5",
"address": "13 Massachusetts Ave",
"city": "Boston"
}, { ... }, { ... }, ...
]
"грузовики" - сбор данных, содержащий все данные грузовика.
[
{
"truckid": "21",
"type": "Refuse",
"year": "2011",
"make": "Mack",
"model": "TerraPro Cabover",
"body": "Mcneilus Rear Loader XC",
"capacity": "25 cubic yards"
},
{
"truckid": "22",
"type": "Refuse",
"year": "2009",
"make": "Mack",
"model": "TerraPro Cabover",
"body": "Mcneilus Rear Loader XC",
"capacity": "25 cubic yards"
},
{
"truckid": "12",
"type": "Dump",
"year": "2006",
"make": "Chevrolet",
"model": "C3500 HD",
"body": "Rugby Hydraulic Dump",
"capacity": "15 cubic yards"
}
]
"drivers" - сбор данных, содержащий все данные драйвера.
[
{
"driverid": "1234",
"name": "John Doe"
},
{
"driverid": "4321",
"name": "Jack Smith"
},
{
"driverid": "3421",
"name": "Don Johnson"
}
]
"списки маршрутов" - сбор данных, содержащий все предопределенные списки маршрутов.
[
{
"route_name": "monday_1",
"day": "monday",
"truck": "21",
"stops": [
{
"cust_id": "1001"
},
{
"cust_id": "1010"
},
{
"cust_id": "1002"
}
]
},
{
"route_name": "friday_1",
"day": "friday",
"truck": "12",
"stops": [
{
"cust_id": "1003"
},
{
"cust_id": "1004"
},
{
"cust_id": "1012"
}
]
}
]
"маршруты" - сбор данных, содержащий данные для всех активных и завершенных маршрутов.
[
{
"routeid": "1",
"route_name": "monday1",
"start_time": "04:31 AM",
"status": "active",
"stops": [
{
"customerid": "1001",
"status": "complete",
"start_time": "04:45 AM",
"finish_time": "04:48 AM",
"elapsed_time": "3"
},
{
"customerid": "1010",
"status": "complete",
"start_time": "04:50 AM",
"finish_time": "04:52 AM",
"elapsed_time": "2"
},
{
"customerid": "1002",
"status": "incomplete",
"start_time": "",
"finish_time": "",
"elapsed_time": ""
},
{
"customerid": "1005",
"status": "incomplete",
"start_time": "",
"finish_time": "",
"elapsed_time": ""
}
]
}
]
Вот такой процесс:
Каждый день драйверы начинаются с "Запуск нового маршрута". Перед запуском нового маршрута драйверы должны сначала ввести данные:
Как только все данные будут введены правильно, начнется "Начать новый маршрут":
- Создать новый объект в коллекции "маршруты"
- Коллекция запросов "списки маршрутов" для "день" + "грузовик" соответствует и возвращает "останавливается"
- Вставить "списки маршрутов в " маршруты
Когда драйвер продолжит свои ежедневные остановки/задачи, коллекция "маршрутов" будет обновляться соответствующим образом.
По завершении всех задач у водителя будет возможность завершить процесс маршрута, просто изменив поле "статус" на "активное" из "полного" в коллекции "маршруты" .
Что о суммирует его. Любые отзывы, мнения, комментарии, ссылки, тактика оптимизации приветствуются.
Заранее благодарим за ваше время.
Ответы
Ответ 1
Схема базы данных выглядит как "классическая" схема реляционной базы данных. Mongodb хорошо подходит для денормализации данных. Я думаю, при отображении маршрутов вы загружаете всех связанных клиентов, водителей, грузовиков.
Если вы хотите сделать вашу систему очень быстрой, вы можете вставить все в сборку маршрутов.
Поэтому я предлагаю следующие модификации вашей схемы:
- клиенты - как есть
- грузовики - как есть
- драйверы - как есть
-
маршрутный список:
Вставить данные о клиентах внутри стопов вместо ссылки. Также вставляем грузовик. В этом случае схема будет:
{
"route_name": "monday_1",
"day": "monday",
"truck": {
_id = 1,
// here will be all truck data
},
"stops": [{
"customer": {
_id = 1,
//here will be all customer data
}
}, {
"customer": {
_id = 2,
//here will be all customer data
}
}]
}
-
маршруты:
Когда драйвер начинает новый маршрут маршрутизации маршрута из списка маршрутов и дополнительно вставляет информацию о драйвере:
{
//copy all route-list data (just make new id for the current route and leave reference to routes-list. In this case you will able to sync route with route-list.)
"_id": "1",
route_list_id: 1,
"start_time": "04:31 AM",
"status": "active",
driver: {
//embedd all driver data here
},
"stops": [{
"customer": {
//all customer data
},
"status": "complete",
"start_time": "04:45 AM",
"finish_time": "04:48 AM",
"elapsed_time": "3"
}]
}
Я думаю, вы спрашиваете себя, что делать, если в основной коллекции изменились драйвер, клиент или другие денормализованные данные. Да, вам нужно обновить все денормализованные данные в других коллекциях. Вам, вероятно, понадобится обновить миллиарды документов (в зависимости от размера вашей системы), и все в порядке. Вы можете сделать это асинхронно, если потребуется много времени.
Что улучшает структуру данных?
- Каждый документ содержит все данные, которые могут отображаться в приложении. Так, например, вам не нужны пользователи, связанные с нагрузкой, водитель, грузовик, когда вам нужны маршруты отображения.
- Вы можете делать любые сложные запросы в своей базе данных. Например, в вашей схеме вы можете создать запрос, который будет возвращать все маршруты, которые содержат остановки в конце клиента с именем = "Билл" (вам нужно сначала загрузить клиента по имени, получить идентификатор и посмотреть идентификатор клиента в вашей текущей схеме).
Вероятно, вы спрашиваете себя, что ваши данные могут быть несинхронизированы в некоторых случаях, но для решения этого вам просто нужно создать несколько unit test, чтобы убедиться, что вы правильно обновили данные denormolized.
Надежда выше поможет вам увидеть мир не с реляционной стороны, с точки зрения базы данных документа.