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
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型
答案:
- 学生 and 课程 ( many for many ) : using引用relationships, throughin间collection or array引用来implementation
- 文章 and 作者 ( many for 一) : in 文章in引用作者ID
- 产品 and 规格 (一 for many ) : such as果规格数量不 many , 可using嵌入relationships; such as果规格 complex or 数量 many , using引用relationships