MongoDB и Mongoose правильная схема - PullRequest
0 голосов
/ 09 мая 2018

Я пишу приложение, которое собирает информацию о весе пользователя каждый день. Я новичок в мире баз данных 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 }
     }
});

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

1 Ответ

0 голосов
/ 09 мая 2018

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

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

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

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

Производительность

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

    Удобство использования

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

  • .......

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

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

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

(У меня на компьютере нет среды программирования 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, когда зарезервированного места происхождения недостаточно. Это НЕ будет хорошо с точки зрения производительности записи.
  • Как рассчитать средний / максимальный / ... вес для всех пользователей? Поскольку данные о весе разделены для каждого пользователя, это трудно сделать.

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

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

Заключение

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

...