MongoDB datamodel and basicconcepts

深入UnderstandMongoDB documentationstructure, dataclass型 and relationships建模techniques

datamodelIntroduction

MongoDBusingdocumentationmodelstoredata, and 传统 relationships型datalibrary 表structure has 很 big 不同. in MongoDBin, data以BSON (Binary JSON) 格式store, 这 is aclass似JSON 二进制格式, support更 many dataclass型.

documentationmodel 优势

  • flexible性: documentation可以package含不同structure data, 无需固定模式
  • 嵌套structure: support complex datastructure, such as嵌套documentation and array
  • performance: for 于某些query场景, documentationmodel可以reducing连接operation
  • readable 性: BSON格式 and JSONclass似, 易于understanding and processing

提示: 虽然MongoDB is 无模式 , 但 in practicalapplicationin, for 了保持dataconsistency and queryperformance, 建议 for collection定义一个合理 structure模式.

documentationstructuredesign

basicdocumentationstructure

MongoDBdocumentation is 一组键值 for , class似于JSONobject. 以 under is a 典型 MongoDBdocumentationexample:

{"_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c"),"name": "张三","age": 30,"email": "zhangsan@example.com","address": {    "street": "北京市海淀区in关村 big 街",    "city": "北京",    "zipcode": "100080"},"hobbies": ["读书", "旅游", "programming"],"createdAt": ISODate("2020-10-19T08:00:00Z"),"isActive": true}

_id字段

每个MongoDBdocumentation都必须package含一个_id字段, 它 in collectionin必须 is 唯一 . such as果插入documentation时没 has 指定_id, MongoDB会自动生成一个ObjectIdclass型 值serving as_id.

注意: ObjectId is 12字节 唯一标识符, package含时间戳, 机器ID, processID and 计数器, ensured in distributedenvironmentin 唯一性.

dataclass型

MongoDBsupport dataclass型

dataclass型 describes example
String string "name": "张三"
Number 数值class型, including整数 and 浮点数 "age": 30, "score": 95.5
Boolean boolean值 "isActive": true
Array array "hobbies": ["读书", "旅游"]
Object 嵌套documentation "address": {"city": "北京"}
ObjectId documentationID "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c")
Date 日期时间 "createdAt": ISODate("2020-10-19T08:00:00Z")
Null null "middleName": null
Binary Data 二进制data 用于storegraph片, fileetc.二进制data
Regular Expression 正则表达式 "pattern": /^test/
JavaScript JavaScriptcode 用于storefunctionetc.

dataclass型 using场景

  • String: store文本data, such as名称, describesetc.
  • Number: store数值data, such as年龄, 价格, 数量etc.
  • Boolean: storestatusdata, such as is 否激活, is 否completionetc.
  • Array: storelistdata, such as爱 good , tag, 订单商品etc.
  • Object: store关联data, such as地址, 联系informationetc.
  • Date: store时间相关data, such ascreation时间, update时间etc.

relationships建模

relationshipsclass型

in MongoDBin, has 几种common relationships建模method:

1. 嵌入relationships (Embedded)

将相关data直接嵌入 to 主documentationin, 适合一 for 一 or 一 for many relationships, 其in" many " 一方data量不 big .

// 嵌入relationshipsexample (user and 地址) 
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c"),
    "name": "张三",
    "address": {
        "street": "北京市海淀区in关村 big 街",
        "city": "北京",
        "zipcode": "100080"
    }
}

2. 引用relationships (Referenced)

through引用otherdocumentation _id来建立relationships, 适合data量较 big or 需要独立query 场景.

// 引用relationshipsexample (user and 订单) 
// userdocumentation
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c"),
    "name": "张三"
}

// 订单documentation
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8d"),
    "userId": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c"),
    "products": [...]
}

3. array引用

in documentationinusingarraystore for otherdocumentation 引用, 适合 many for many relationships.

// array引用example (user and role) 
// userdocumentation
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c"),
    "name": "张三",
    "roleIds": [
        ObjectId("5f8d0f9a9b2c3d4e5f6a7b8e"),
        ObjectId("5f8d0f9a9b2c3d4e5f6a7b8f")
    ]
}

// roledocumentation
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8e"),
    "name": "management员"
}
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8f"),
    "name": "user"
}

relationships建模best practices

  • 考虑data访问模式: 根据query and update 频率选择合适 建模方式
  • 避免过度嵌入: 嵌入过 many data会导致documentation过 big , 影响performance
  • 避免过 many 引用: 过 many 引用会增加query complex 性
  • 平衡读写performance: 嵌入可以improving读取performance, 但可能影响写入performance
  • 考虑dataconsistency: 引用relationships需要额 out operation来保持dataconsistency

datamodelbest practices

1. documentation big small 限制

MongoDB单个documentation big small 限制 for 16MB, 超过此限制会导致插入失败.

注意: for 于 big 型data, such asgraph片, 视频etc., 应考虑usingGridFSstore, or 只storefilepath, practicalfilestore in filesystemin.

2. 字段命名规范

  • using small 写字母 and under 划线, 避免using驼峰命名法
  • 避免using特殊字符, such as点(.), 美元符号($)etc.
  • 字段名应简洁明了, 反映字段 含义
  • 避免using过 long 字段名, 以reducingstore空间

3. index策略

  • for 常用query字段creationindex
  • 考虑复合index以optimization complex query
  • 避免creation过 many index, 因 for 会影响写入performance
  • 定期check and optimizationindex

4. datashard考虑

  • 选择合适 shard键, 确保data均匀分布
  • 考虑query模式, 避免跨shardquery
  • monitorshardcluster performance and healthystatus

实践case

case: 电商systemdatamodeldesign

for 电商systemdesignMongoDBdatamodel, includinguser, 商品, 订单etc.实体.

1. usermodel (User)
// usermodel
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c"),
    "username": "zhangsan",
    "password": "hashed_password",
    "email": "zhangsan@example.com",
    "name": "张三",
    "addresses": [
        {
            "street": "北京市海淀区in关村 big 街",
            "city": "北京",
            "zipcode": "100080",
            "isDefault": true
        }
    ],
    "createdAt": ISODate("2020-10-19T08:00:00Z"),
    "updatedAt": ISODate("2020-10-19T08:00:00Z")
}
2. 商品model (Product)
// 商品model
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8d"),
    "name": "iPhone 12",
    "description": "苹果手机",
    "price": 6999,
    "stock": 100,
    "category": "手机",
    "tags": ["苹果", "智能手机"],
    "images": ["image1.jpg", "image2.jpg"],
    "createdAt": ISODate("2020-10-19T08:00:00Z"),
    "updatedAt": ISODate("2020-10-19T08:00:00Z")
}
3. 订单model (Order)
// 订单model
{
    "_id": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8e"),
    "userId": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8c"),
    "orderDate": ISODate("2020-10-19T08:00:00Z"),
    "totalAmount": 6999,
    "status": "已付款",
    "shippingAddress": {
        "street": "北京市海淀区in关村 big 街",
        "city": "北京",
        "zipcode": "100080"
    },
    "items": [
        {
            "productId": ObjectId("5f8d0f9a9b2c3d4e5f6a7b8d"),
            "quantity": 1,
            "price": 6999
        }
    ],
    "paymentInfo": {
        "method": "支付宝",
        "transactionId": "2020101900000001"
    }
}

互动练习

练习1: design博客systemdatamodel

design一个博客system datamodel, includinguser, 博客文章 and 评论. 考虑合适 relationships建模方式.

referencedesign:

// usermodel
{
    "_id": ObjectId(...),
    "username": "user1",
    "name": "user1",
    "email": "user1@example.com"
}

// 博客文章model (嵌入评论) 
{
    "_id": ObjectId(...),
    "title": "MongoDBdatamodeldesign",
    "content": "...",
    "authorId": ObjectId(...),
    "createdAt": ISODate(...),
    "tags": ["MongoDB", "datamodel"],
    "comments": [
        {
            "userId": ObjectId(...),
            "content": "很棒 文章",
            "createdAt": ISODate(...)
        }
    ]
}

练习2: 识别relationshipsclass型

for 于以 under 场景, 选择合适 relationships建模方式: 1. 学生 and 课程 relationships ( many for many ) 2. 文章 and 作者 relationships ( many for 一) 3. 产品 and 规格 relationships (一 for many )

答案:

  1. 学生 and 课程 ( many for many ) : using引用relationships, throughin间collection or array引用来implementation
  2. 文章 and 作者 ( many for 一) : in 文章in引用作者ID
  3. 产品 and 规格 (一 for many ) : such as果规格数量不 many , 可using嵌入relationships; such as果规格 complex or 数量 many , using引用relationships