Многие ко многим отношения в Firebase

У меня есть база данных Firebase. У меня есть компании и подрядчики. Подрядчик может работать на несколько компаний, а компания может иметь несколько подрядчиков. Это прямые отношения "многие ко многим". Я хочу иметь возможность ответить на вопросы о компаниях и подрядчиках:

  1. учитывая компанию, которые являются текущими подрядчиками.
  2. учитывая подрядчика, на какие компании они работают.

каковы альтернативы для структурирования данных в пределах опорного пункта?

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, чтобы найти все компании для подрядчика или всех подрядчиков для компании. И теперь остается только один список. Я думаю, что это лучшее решение для моих требований.