Многие ко многим отношения в Firebase
У меня есть база данных Firebase. У меня есть компании и подрядчики. Подрядчик может работать на несколько компаний, а компания может иметь несколько подрядчиков. Это прямые отношения "многие ко многим". Я хочу иметь возможность ответить на вопросы о компаниях и подрядчиках:
- учитывая компанию, которые являются текущими подрядчиками.
- учитывая подрядчика, на какие компании они работают.
каковы альтернативы для структурирования данных в пределах опорного пункта?
2 ответов
самоответ действительно является одним из способов моделирования этого. Это, вероятно, самый прямой эквивалент того, как вы моделируете это в реляционной базе данных:
- участка
- С
- companyAndContractorsAssignment (таблица соединителей "многие ко многим")
альтернативой было бы использовать 4 верхнего уровня узлы:
- участка
- С
- companyContractors
- contractorCompanies
последние два узла будут выглядеть так:
companyContractors
companyKey1
contractorKey1: true
contractorKey3: true
companyKey2
contractorKey2: true
contractorCompanies
contractorKey1
companyKey1: true
contractorKey2
companyKey2: true
contractorKey3
companyKey1: true
эта двунаправленная структура позволяет вам как искать "подрядчиков для компании", так и "компании для подрядчика", без необходимости запроса. Это должно быть быстрее, особенно при добавлении подрядчиков и компаний.
ли это необходимо для вашего приложения, зависит от случаев использования вам нужно, размеры данных вы ожидаете и многое другое.
рекомендуемая литература моделирование данных NoSQL просмотр Firebase для разработчиков SQL. Этот вопрос также был показан в эпизод #AskFirebase серии youtube.
обновление (2017016)
кто-то выложил последующий вопрос, который ссылается здесь о получении фактического пункты из узлов" подрядчики "и" компании". Вам нужно будет получить их по одному за раз, так как Firebase не имеет эквивалента SELECT * FROM table WHERE id IN (1,2,3)
. Но эта операция не так медленна, как вы можете подумать, потому что запросы передаются по конвейеру через одно соединение. Подробнее об этом читайте здесь:ускорить получение сообщений для моего приложения социальной сети с помощью запроса вместо наблюдения одного события повторно.
после дальнейших исследований я попытаюсь ответить на свой собственный вопрос. Я рассмотрел ряд других сообщений, и одним из решений проблемы "многие ко многим" является хранение списка контракторов в объекте компании и сохранение списка компаний в каждом объекте подрядчика. Это иллюстрируется приведенным ниже примером.
companies : {
companyKey1 : {
name : company1
...
contractors : {
contractorKey1 : true,
contractorKey3 : true
}
}
companyKey2 : {
name : company2
...
contractors : {
contractorKey2 : true,
}
}
}
contrators : {
contractorKey1 : {
name : bill
...
companies : {
companyKey1 : true
}
}
contractorKey2 : {
name : steve
...
companies : {
companyKey1 : true
}
}
contractorKey3 : {
name : jim
...
companies : {
companyKey2 : true
}
}
}
эта организация "работает" в том смысле, что на эти вопросы можно ответить. Но недостатком этого решения является то, что два списка для ведения при изменении назначений подрядчика / компании. Было бы лучше, если бы был способ представить эту информацию в одном списке.
Я думаю, что я придумал лучшее решение. Решение заключается в создании третьего списка, помимо компаний и подрядчиков под названием companyAndContractorAssignment. Элементы этого списка будут представлять отношения между подрядчиком и компанией. Его содержание будет пара полей, contractorKey и в companyKey. Затем мы можем исключить список подрядчиков в компании и список компаний в подрядчике. Эта альтернативная структура представлена ниже. Обратите внимание, что в объекте компании нет списка подрядчиков и нет списка компаний с объектом подрядчика.
companies : {
companyKey1 : {
name : company1
...
}
companyKey2 : {
name : company2
...
}
}
contrators : {
contractorKey1 : {
name : bill
...
}
contractorKey2 : {
name : steve
...
}
contractorKey3 : {
name : jim
...
}
}
companyAndContractorsAssignment : {
key1 : {
contractorKey1 : true,
companyKey1: true,
}
key2 : {
contractorKey3 : true,
companyKey1: true,
}
key3 : {
contractorKey2 : true,
companyKey2: true,
}
эта альтернативная структура позволяет ответить на вопросы, используя запрос orderByChild / equalTo на companyAndContractorsAssignment, чтобы найти все компании для подрядчика или всех подрядчиков для компании. И теперь остается только один список. Я думаю, что это лучшее решение для моих требований.