首页 > 解决方案 > 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 }
     }
});

或者我应该在每次记录 userSchema 时更新吗?

标签: mongodbmongoosemongoose-schema

解决方案


实际上数据模型的设计取决于这个软件的要求(它如何使用数据)。

据我了解,用户-> 权重关系是一对多的映射。如果您只想存储用户信息及其权重而没有其他附加要求,那么您的模式是可以的。

因此,您将用户数据存储在用户集合中,一个用户对应一个文档。并且您有另一个集合来存储用户的体重数据,该集合中的多个文档属于一个用户。当你想获取一个用户和他的体重数据时,你必须查询2次:一次在用户集合中,另一次在权重集合中。

但是IMO,在设计数据模型时应该考虑其他方面:

表现

  • 数据量?小块数据还是大量数据?
  • 读/写百分比?
  • 是否有用户会频繁访问的热点数据?
  • ……

    使用方便

  • 我可以轻松更新/删除数据吗?

  • …………

我将在下面的不同场景中给出一些建议:

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 。您可以通过$slice获取最旧的 N 条或最新的 N 条重量记录。

但同时你可能会遇到一些问题:

  • 如果用户以非常高的频率添加他们的体重记录。用户集合中的文档大小将增长到非常大和快速。当原始保留空间不足时,这将导致移动文档在 mongodb 存储中的位置。这不利于写入性能。
  • 您如何计算所有用户的平均/顶部/...权重?由于每个用户的体重数据是分开的,因此很难做到这一点。

2.你的用户有大量的体重数据,增长非常快。您需要计算用户的平均值/顶部/...。

请遵循您的原始设计。将数据存储在两个单独的集合中。

结论

有很多不同的建模方法,完全取决于您的要求。您可以查看 Mongodb 建模指南:https ://docs.mongodb.com/manual/core/data-modeling-introduction/


推荐阅读