- MongoDB官方文档中文版
- MongoDB中文手册说明
- MongoDB简介
- 安装 MongoDB
- The mongo Shell
- MongoDB CRUD 操作
- 聚合
- 数据模型
- 事务
- 索引
- 安全
- 安全检查列表
- 启用访问控制
- 身份验证
- 基于角色的访问控制
- TLS / SSL(传输加密)
- 静态加密
- 客户端字段级加密
- 审计
- 网络和配置强化
- 实现字段级别修订
- 安全参考
- 附录
- 变更流
- 复制
- 分片
- 分片键
- 哈希分片
- 范围分片
- 区
- 管理分片区
- 按位置细分数据
- 用于更改SLA或SLO的分层硬件
- 按应用或客户细分数据
- 仅插入工作负载的分布式本地写入
- 管理分片区
- 使用块进行数据分区
- 在分片集群中拆分数据块
- 管理
- 存储
- 存储引擎
- 日志记录
- 管理日志记录
- GridFS
- FAQ:MongoDB 存储
- 存储引擎
- 参考
- 运算符
- 查询与映射运算符
- 更新运算符
- 聚合管道阶段
- 聚合管道操作符
- $abs (aggregation)
- $acos (aggregation)
- $acosh (aggregation)
- $add (aggregation)
- $addToSet (aggregation)
- $allElementsTrue (aggregation)
- $and (aggregation)
- $anyElementTrue (aggregation)
- $arrayElemAt (aggregation)
- $arrayToObject (aggregation)
- $asin (aggregation)
- $asinh (aggregation)
- $atan (aggregation)
- $atan2 (aggregation)
- $atanh (aggregation)
- $avg (aggregation)
- $ceil (aggregation)
- $cmp (aggregation)
- $concat (aggregation)
- $concatArrays (aggregation)
- $cond (aggregation)
- $convert (aggregation)
- $cos (aggregation)
- $dateFromParts (aggregation)
- $dateToParts (aggregation)
- $dateFromString (aggregation)
- $literal (aggregation)
- 查询修饰符
- 数据库命令
- 聚合命令
- 地理空间命令
- 查询和写操作命令
- 查询计划缓存命令
- 认证命令
- 用户管理命令
- 角色管理命令
- 复制命令
- 分片命令
- 会话命令
- 管理命令
- 诊断命令
- 免费监控命令
- 系统事件审计命令
- mongo Shell 方法
- 集合方法
- db.collection.aggregate()
- db.collection.bulkWrite()
- db.collection.copyTo()
- db.collection.count()
- db.collection.countDocuments()
- db.collection.estimatedDocumentCount()
- db.collection.createIndex()
- db.collection.createIndexes()
- db.collection.dataSize()
- db.collection.deleteOne()
- db.collection.deleteMany()
- db.collection.distinct()
- db.collection.drop()
- db.collection.dropIndex()
- db.collection.dropIndexes()
- db.collection.ensureIndex()
- db.collection.explain()
- db.collection.find()
- db.collection.findAndModify()
- db.collection.findOne()
- db.collection.findOneAndDelete()
- db.collection.findOneAndReplace()
- db.collection.findOneAndUpdate()
- db.collection.getIndexes()
- db.collection.getShardDistribution()
- db.collection.getShardVersion()
- db.collection.insert()
- db.collection.insertOne()
- db.collection.insertMany()
- db.collection.isCapped()
- db.collection.latencyStats()
- db.collection.mapReduce()
- db.collection.reIndex()
- db.collection.remove()
- db.collection.renameCollection()
- db.collection.replaceOne()
- db.collection.save()
- db.collection.stats()
- db.collection.storageSize()
- db.collection.totalIndexSize()
- db.collection.totalSize()
- db.collection.update()
- db.collection.updateOne()
- db.collection.updateMany()
- db.collection.watch()
- db.collection.validate()
- 词汇表
- 默认的MongoDB端口
- 默认的MongoDB读/写关注
- 服务器会话
- MongoDB驱动
- FAQ
- 联系我们
- 更多资料
- [快学Mongo]
- [Mongo问题讨论区]
- [Mongo 驱动使用手册]
- 本书使用 GitBook 发布
唯一索引
唯一索引
在本页面
唯一索引确保索引字段不会存储重复值;例如,强制索引字段的唯一性。默认情况下,MongoDB在创建集合期间在_id字段上创建一个唯一的索引。
新的内部格式
从MongoDB 4.2开始,对于4.2(或更高版本)的featureCompatibilityVersion(fCV),MongoDB使用一种新的内部格式来存储与早期MongoDB版本不兼容的唯一索引。新格式适用于现有的唯一索引以及新创建/重建的唯一索引。
创建唯一索引
要创建一个唯一的索引,使用db.collection.createIndex()
方法,并将unique
选项设置为true
。
db.collection.createIndex( <key and index type specification>, { unique: true } )
单个字段上的唯一索引
例如,要在members
集合的user_id
字段上创建一个唯一的索引,在mongo
shell中使用以下操作:
db.members.createIndex( { "user_id": 1 }, { unique: true } )
独特的复合索引
您还可以在复合索引上强制执行唯一约束。如果您在复合索引上使用唯一约束,那么MongoDB将对索引键值的组合执行惟一性。
例如,要在members
集合的groupNumber
, lastname
和firstname
字段上创建一个唯一的索引,在mongo
shell中使用以下操作:
db.members.createIndex( { groupNumber: 1, lastname: 1, firstname: 1 }, { unique: true } )
创建的索引强制groupNumber
、lastname
和firstname
值的组合的唯一性。
再举一个例子,考虑一个包含以下文档的集合:
{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] }
创建一个独特的复合multikey索引在a.loc
和a.qty
:
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
唯一索引允许将以下文档插入到集合中,因为索引强制a.loc
和a.qty
值组合的唯一性:
db.collection.insert( { _id: 2, a: [ { loc: "A" }, { qty: 5 } ] } )
db.collection.insert( { _id: 3, a: [ { loc: "A", qty: 10 } ] } )
也可以看看:
行为
限制
如果集合已经包含了违反索引的唯一约束的数据,MongoDB不能在指定的索引字段上创建一个唯一索引。
不能在hashed索引上指定唯一的约束。
在复制集和分片集群上建立唯一索引
对于复制集和分片集群,使用滚动过程创建唯一索引需要在过程中停止对集合的所有写操作。如果不能在过程中停止对集合的所有写操作,则不要使用滚动过程。相反,在集合上建立你的唯一索引:
db.collection.createIndex()
在主数据库上发布副本集,db.collection.createIndex()
在分片mongos
群集上发出。
跨不同文档的唯一约束
唯一约束适用于集合中的不同文档。也就是说,唯一索引防止单独的文档对索引键具有相同的值。
因为约束适用于单独的文档,一个独特的多键索引,一个文档可能数组元素,导致重复索引键值,只要文档不重复的索引键值的另一个文档。在本例中,重复索引条目只插入索引一次。
例如,考虑一个包含以下文档的集合:
{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] }
{ _id: 2, a: [ { loc: "A" }, { qty: 5 } ] }
{ _id: 3, a: [ { loc: "A", qty: 10 } ] }
在a.loc
和a.qty
上创建唯一的复合多键索引:
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
如果集合中的其他文档的索引 key value 为{ "a.loc": "B", "a.qty": null }
,则唯一索引允许将以下文档插入到集合中。
db.collection.insert( { _id: 4, a: [ { loc: "B" }, { loc: "B" } ] } )
唯一索引和丢失字段
如果文档在唯一索引中没有索引字段的值,索引将为该文档存储空值。由于唯一的约束,MongoDB将只允许一个没有索引字段的文档。如果有多个文档没有索引字段的值或缺少索引字段,索引构建将失败,并出现重复键错误。
例如,一个集合在x
上有一个唯一的索引:
db.collection.createIndex( { "x": 1 }, { unique: true } )
如果集合中没有包含缺少x
字段的文档,唯一索引允许插入没有x
字段的文档:
db.collection.insert( { y: 1 } )
但是,如果集合中已经包含了一个没有字段x
的文档,则在插入一个没有字段x
的文档时出现唯一的索引错误:
db.collection.insert( { z: 1 } )
由于违反了字段x
值的唯一约束,操作无法插入文档:
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: test.collection.$a.b_1 dup key: { : null }"
}
})
也可以看看:
独特的部分索引
3.2版本新增.
部分索引只索引集合中满足指定筛选器表达式的文档。如果您同时指定了partialFilterExpression和一个unique约束,唯一约束只适用于满足筛选器表达式的文档。
如果文档不满足筛选条件,则具有唯一约束的部分索引不会阻止插入不满足唯一约束的文档。例如,请参阅带有唯一约束的部分索引。
分片集群和唯一索引
您不能在hashed索引上指定唯一的约束。
对于一个范围分片集合,只有以下索引可以是唯一的:
唯一性和
_ID
索引
如果_id
字段不是分片键或分片键的前缀,_id
索引只对每个分片强制唯一性约束,而对各个分片强制而不是。
唯一的索引约束意味着:
- 对于要分片的集合,如果该集合有其他唯一索引,则不能对该集合进行分片。
- 对于已经分片的集合,不能在其他字段上创建唯一索引。
Copyright © 上海锦木信息技术有限公司 all right reserved,由 MongoDB汉化小组 提供技术支持文件修订时间: 2020-10-11 20:53:05