Как правильно структурировать такого рода данные в Firestore?
Я видел видео и читал документацию Cloud firestore из сервиса Google Firebase, но я не могу понять это, исходя из базы данных реального времени.
Я имею в виду это веб-приложение, в котором я хочу хранить своих поставщиков из разных категорий продуктов. Я хочу выполнить поисковый запрос по всем моим продуктам, чтобы найти, какие поставщики у меня есть для такого продукта, и в конечном итоге получить доступ к информации об этом поставщике.
Я планирую использовать эту структуру для этой цели:
Providers ( Collection )
Provider 1 ( Document )
Name
City
Categories
Provider 2
Name
City
Products ( Collection )
Product 1 ( Document )
Name
Description
Category
Provider ID
Product 2
Name
Description
Category
Provider ID
Итак, мой вопрос в том, является ли этот подход правильным способом доступа к информации о поставщике, как только я получу нужный мне продукт?
Я знаю, что это возможно в базе данных реального времени, используя идентификатор поставщика, я мог бы выполнить поиск этого поставщика в разделе провайдеры, но с Firestore я не уверен, возможно ли это или это правильный подход.
Переведено автоматически
Ответ 1
Как правильно структурировать такого рода данные в Firestore?
Вам нужно знать, что не существует "идеального", "наилучшего" или "правильного" решения для структурирования облачной базы данных Firestore. Лучшее и корректное решение - это решение, которое соответствует вашим потребностям и упрощает вашу работу. Имейте также в виду, что в мире баз данных NoSQL также нет единой "правильной структуры данных". Все данные моделируются с учетом вариантов использования, которые требуются вашему приложению. Это означает, что того, что работает для одного приложения, может быть недостаточно для другого приложения. Таким образом, не для всех существует правильное решение. Эффективная структура базы данных типа NoSQL полностью зависит от того, как вы собираетесь запрашивать ее.
То, как вы структурируете свои данные, мне нравится. В общем, есть два способа, которыми вы можете достичь того же результата. Первым способом было бы сохранить ссылку на поставщика в объекте product (как вы уже делаете) или скопировать весь объект provider в документе product. Этот последний метод называется denormalization
и является довольно распространенной практикой, когда речь заходит о Firebase. Поэтому мы часто дублируем данные в базах данных NoSQL для удовлетворения запросов, которые иначе могут быть невозможны. Для лучшего понимания я рекомендую вам посмотреть это видео, Денормализация является обычной в базе данных Firebase. Это для базы данных Firebase в реальном времени, но те же принципы применимы и к облачному Firestore.
Кроме того, при дублировании данных необходимо помнить одну вещь. Точно так же, как вы добавляете данные, их необходимо поддерживать. Другими словами, если вы хотите обновить / удалить объект provider , вам нужно сделать это везде, где он существует.
Теперь вы можете задаться вопросом, какой метод лучше. В самом общем смысле, наилучший способ хранения ссылок или дублирования данных в базе данных NoSQL полностью зависит от требований вашего проекта.
Итак, вам следует задать себе несколько вопросов о данных, которые вы хотите дублировать, или просто сохранить их в качестве ссылок:
- Они статичны или будут меняться со временем?
- Если это так, нужно ли обновлять каждый дублирующийся экземпляр данных, чтобы все они оставались синхронизированными? Это то, о чем я также упоминал ранее.
- Когда дело доходит до Firestore, вы проводите оптимизацию с точки зрения производительности или стоимости?
Если ваши дублирующиеся данные должны изменяться и оставаться синхронизированными в одно и то же время, то в будущем вам может быть трудно поддерживать актуальность всех этих дубликатов. Это также может означать, что вы потратите много денег на поддержание всех этих документов в актуальном состоянии, поскольку для каждого изменения потребуется чтение и запись для каждого документа. В этом случае выигрышным вариантом будет сохранение только ссылок.
При таком подходе вы пишете очень мало дублирующихся данных (в значительной степени только Provider ID
). Таким образом, это означает, что ваш код для записи этих данных будет довольно простым и довольно быстрым. Но при чтении данных вам нужно будет загрузить данные из обеих коллекций, что означает дополнительный вызов базы данных. Обычно это не является большой проблемой с производительностью для разумного количества документов, но определенно требует большего количества кода и большего количества вызовов API.
Если вам нужно, чтобы ваши запросы были очень быстрыми, вы можете предпочесть дублировать больше данных, чтобы клиенту приходилось читать только один документ для каждого запрашиваемого элемента, а не несколько документов. Но вы также можете зависеть от локальных кэшей клиента, что делает это дешевле, в зависимости от данных, которые клиент должен прочитать.
При таком подходе вы дублируете все данные для provider
для каждого product
документа. Это означает, что код для записи этих данных более сложный, и вы определенно храните больше данных, на один объект поставщика больше для каждого документа продукта. И вам нужно будет выяснить, поддерживать ли актуальность каждого документа и как это сделать. Но, с другой стороны, чтение product
документа теперь дает вам всю информацию о provider
документе за одно чтение.
This is a common consideration in NoSQL databases: you'll often have to consider write performance and disk storage vs. reading performance and scalability.
For your choice of whether or not to duplicate some data, it is highly dependent on your data and its characteristics. You will have to think that through on a case-by-case basis.
So in the end, remember that both are valid approaches, and neither of them is pertinently better than the other. It all depends on what your use-cases are and how comfortable you are with this new technique of duplicating data. Data duplication is the key to faster reads, not just in Cloud Firestore or Firebase Realtime Database but in general. Any time you add the same data to a different location, you're duplicating data in favor of faster read performance. Unfortunately in return, you have a more complex update and higher storage/memory usage. But you need to note that extra calls in Firebase real-time database, are not expensive, in Firestore are. How much duplication data versus extra database calls is optimal for you, depends on your needs and your willingness to let go of the "Single Point of Definition mindset", which can be called very subjective.
After finishing a few Firebase projects, I find that my reading code gets drastically simpler if I duplicate data. But of course, the writing code gets more complex at the same time. It's a trade-off between these two and your needs that determines the optimal solution for your app. Furthermore, to be even more precise you can also measure what is happening in your app using the existing tools and decide accordingly. I know that is not a concrete recommendation but that's software development. Everything is about measuring things.
Remember also, that some database structures are easier to be protected with some security rules. So try to find a schema that can be easily secured using Cloud Firestore Security Rules.
Please also take a look at my answer from this post where I have explained more about collections
, maps
and arrays
in Firestore.