mongodb中是否有更好的设计来制作软件包/钱包系统?

时间:2019-04-11 12:58:28

标签: node.js mongodb express mongoose

我正试图用不同的用户创建一个打包/钱包系统。

我在mongodb中有4个收藏集:

业务

const businessSchema = new mongoose.Schema({
  name: { type: String, unique: true },
  .
  .
  .
  packages: [{
    kind: String,
    price: Number,
    numberOfitems: Number
  }]

})

用户

const userSchema = new mongoose.Schema({
  userName: { type: String, unique: true },
  userType: {
    type: String,
    enum: ["USER", "BusinessOwner"],
    default: "USER"
  }
  .
  .
  .
  wallets:[{
    businessID: { type: mongoose.Schema.Types.ObjectId, ref: 'Business'},
    numberOfItems: Number,
    kind: String
  }]

})

购买

const purchasesSchema = new mongoose.Schema({
  userID: { type: mongoose.Schema.Types.ObjectId, ref: 'User'},
  businessID: { type: mongoose.Schema.Types.ObjectId, ref: 'Business'},
  purchasedPackage:{
    numberOfItems: Number,
    kind: String,
    price: Number
  }

})

兑换订单

const orderSchema = new mongoose.Schema({
  userID: { type: mongoose.Schema.Types.ObjectId, ref: 'User'},
  businessID: { type: mongoose.Schema.Types.ObjectId, ref: 'Business'},
  order:{
    numberOfItems: Number,
    kind: String
  }

})

业务逻辑流如下:

  • 企业主创建一个包裹。
  • 用户购买包裹并创建交易。
  • 用户可以兑换商品并创建订单。

我正在努力找到一种更简单的方法来实现此工作流程,同时减少冗余。

这是我第一次在Stackoverflow上发帖,请对我轻松一点:)

1 个答案:

答案 0 :(得分:0)

我认为,设计基于文档的数据库在很大程度上取决于应用程序如何向用户显示数据,换句话说,可以使用哪些API。因此,这取决于系统和用户界面的要求。因此,在建议的设计过程中我做了很多假设。

我将从设计开始,然后解释为什么它可能足以满足系统的假定要求。

需要4个收藏集:

  1. 用户。
  2. 业务。
  3. 包装。
  4. 购买。

首先:用户集合。 仅用于存储用户信息,不包括钱包。

第二个:业务集合 仅用于存储企业信息,不包括包装。

第三:包裹收集 用于存储软件包,其中包含非规范化的业务信息,以便更好地查询。

const packageSchema = new Schema({
     itemInfo: {}, //The item to be sold in the package: (Name, description, ... etc). Try not to include more than one piece of information in a single field, for example: instead of name being: "ITEM_NAME (The big one)", separate them into two fields: name in one and the size in another. 
     businessInfo: {
        //All data of business needed to show the package in the UI, along with the businessId. 
     },
     count: {}, //Number of items 
     //.... Any other data  needed  for the  package, like price, description, ... etc. 
});

第四:购买商品 购买集合代表拥有包裹的用户。

const purchaseSchema = new Schema({
     user: {}, //Id of the user 
     package: {}, //PackageId along with any denormalized data needed about the package to  display it to the user. 
     status: {type: String, required: true, enum: ["pending", "redeemed", "cancelled"], default: "pending"}, //Status of  the package, for the enum, use a constant variable accessible everywhere in the system, so it's easy to make it consistent.      
});

设计依据 这是一个列表,其中包含系统中的假定功能以及使用每个功能的假定频率,对DB的调用次数以及调用的简便性。

  • 管理员。
    • 添加新业务:
      • 频率:低。
      • 对数据库的呼叫数:1.
      • 简单性:对业务集合的简单插入调用。
    • 修改现有业务:
      • 频率:非常低。
      • 呼叫数据库的次数:3
      • 简单性:复杂且效率低下,需要更新:业务,包装和采购货款。
  • 企业。
    • 添加新软件包:
      • 频率:中。
      • 对数据库的呼叫数:1.
      • 简单性:非常简单,一个对Package集合的原子插入调用。 (由于呼叫者是企业本身,因此可以将非规范化的业务数据与呼叫一起发送。
    • 修改现有软件包:
      • 频率:低。
      • 对DB的调用次数:1(因为已经购买的物品不应更改)。
      • 简单性:非常简单,对软件包集合进行一次原子更新调用。
  • 客户。
    • 添加(购买)包装。
      • 频率:非常高。
      • 对数据库的呼叫数:1.
      • 简单性:非常简单,一个对Purchases集合的原子插入调用。
    • 兑换包裹。
      • 频率:非常高。
      • 对数据库的呼叫数:1.
      • 简单性:非常简单,对购买集合进行一次原子更新调用(更改状态,按状态=“待处理”和userId进行过滤)。
    • 从钱包中取出物品。
      • 频率:非常高。
      • 对数据库的呼叫数:1.
      • 简单性:非常简单,一个对购买集合的原子查找调用。
    • 通过排序和过滤显示所有可用的软件包。
      • 频率:非常高。
      • 对数据库的呼叫数:1.
      • 简单性:非常简单,一个原子的find调用即可收集包,所有数据都在那里。

最后,该设计还使获取数据统计信息变得非常容易,因为以下所有内容仅需对数据库进行一次简单(高效)的调用即可:

  1. 企业数量。
  2. 计数软件包的数量(活动,非活动等)。
  3. 已兑换的总金额。
  4. 每笔业务的总金额。
  5. 每位用户支付的平均金额。
  6. 为用户支付的总金额。

还有更多。