Правая схема MongoDB и Mongoose

Я пишу приложение, которое каждый день собирает информацию о весе пользователя. Я новичок в мире баз данных NoSQL. Поэтому я хотел бы вначале выбрать правильную схему.

Витрина выглядит так: пользователь говорит только один раз важные данные, такие как рост или возраст, и после этого пользователь может измерить его вес.

Прямо сейчас я написал это так:

var userSchema = new Schema({
    randomId: {type: Number, required: false, unique: true },
    name: String,
    userId:  {type: String, required: true},
    hight: Number,
    gender: String,
    waist: Number,
    age: Number,
    updated: { type: Date, default: Date.now }
});

как хранить информацию о весе каждый день?

Следует ли мне создать новую модель веса с указанием веса и даты?

var weightSchema = new Schema({
    name: String,
    userId:  {type: String, required: true},
    weightValue:{
       value: Number,
       updated: { type: Date, default: Date.now }
     }
});

или S следует обновлять каждый раз документ userSchema?


person Anna K    schedule 08.05.2018    source источник
comment
Единственно правильный способ зависит исключительно от того, как вы собираетесь использовать данные. Внедренные данные будут загружаться намного быстрее, поскольку они уже находятся в документе, но ссылочные данные обычно требуются там, где количество встраиваемых записей слишком велико для того, чтобы это было приемлемо. Если вы ищете лучший штамп, то на самом деле его просто нет. Делайте то, что лучше всего соответствует шаблонам использования вашего собственного приложения.   -  person Neil Lunn    schedule 09.05.2018


Ответы (1)


На самом деле дизайн модели данных зависит от требований этого программного обеспечения (как оно использует данные).

Насколько я понимаю, отношение «пользователь -> вес» - это сопоставление «один ко многим». Если вы просто хотите сохранить информацию о пользователях и их весах, и НИКАКИХ других дополнительных требований, ваша схема в порядке.

Таким образом, вы храните пользовательские данные в пользовательской коллекции, один пользователь для одного документа. И у вас есть еще одна коллекция для хранения данных о весе пользователя, несколько документов в этой коллекции принадлежат одному пользователю. Если вы хотите получить данные об одном пользователе и его весе, вам нужно запросить 2 раза: один в коллекции пользователей, другой в коллекции веса.

Но ИМО, при разработке модели данных следует учитывать и другие аспекты:

Представление

  • Объем данных? Небольшие фрагменты данных или много данных?
  • Процент чтения / записи?
  • Есть ли какие-либо горячие данные, к которым пользователь будет часто обращаться?
  • ......

    Легкость использования

  • Могу ли я легко обновить / удалить данные?

  • .......

Я дам несколько предложений по другому сценарию ниже:

1. Вы учитываете производительность чтения и НЕ будете хранить слишком много записей веса для одного пользователя.

Вы можете объединить схему пользователя и схему весов в одну схему, причем схема пользователя содержит массив для хранения всех записей веса пользователя. Это называется денормализованной моделью, которую обычно предлагает Mongodb. Ваша схема выглядит так:

(У меня нет среды программирования JS на моем ПК, поэтому не подтверждаю, что это может быть скомпилировано без ошибок. Просто используйте это как ссылку.)

var weightSchema = new Schema({
    value: Number,
    updated: { type: Date, default: Date.now }
});
var userSchema = new Schema({
    randomId: {type: Number, required: false, unique: true },
    name: String,
    userId:  {type: String, required: true},
    hight: Number,
    gender: String,
    waist: Number,
    age: Number,
    weights: [weightSchema],  // Here are the weight records.
    updated: { type: Date, default: Date.now }
});
mongoose.model('user', userSchema);

Теперь у вас есть только одна коллекция для хранения данных о пользователях и их весе. Один документ для одного пользователя. Вы можете получить преимущества:

  • модель данных, которая проще для понимания человеком
  • более высокая производительность чтения, потому что mongodb теперь нужно запрашивать только одну коллекцию. Вы можете получить все данные одного пользователя, загрузив один документ. Вы можете использовать $ push, когда пользователь добавить новую запись веса. И вы можете получить самые старые N или последние N записей веса с помощью $ slice.

Но при этом могут возникнуть проблемы:

  • Если пользователь очень часто добавляет свои записи веса. Размер документа в пользовательской коллекции вырастет до очень большого и быстро. Это приведет к перемещению позиции документа в хранилище mongodb, когда зарезервированного пространства origin недостаточно. Это НЕ повлияет на производительность записи.
  • Как можно рассчитать средний / максимальный / ... вес для всех пользователей? Поскольку данные о весе у каждого пользователя разделены, это сделать сложно.

2. У ваших пользователей много данных о весе, и они очень быстро растут. И вам нужно рассчитать среднее / максимальное / ... по пользователям.

Пожалуйста, следуйте дизайну вашего происхождения. Храните данные в двух отдельных коллекциях.

Заключение

Есть много разных методов моделирования, все зависит от ваших требований. Вы можете ознакомиться с руководством по моделированию Mongodb: https://docs.mongodb.com/manual/core/data-modeling-introduction/

person yellowB    schedule 09.05.2018