mongodb 索引唯一性约束

索引分类.png

1. 唯一索引

创建索引时,制定unique=true可以将其声明为唯一索引,以book为例:

  • 复合索引的唯一性:
    db.collection.ensureIndex({type:1,version:1},{unique:true})
  • 嵌套索引唯一,和普通索引没区别:
    db.collection.ensureIndex({author.name:1},{unique:true})
  • 将整个嵌套文档作为唯一,因为嵌套文档的唯一性约束是严格按照顺序进行比较的,尽管文档内容一致,但由于字段的顺序不一致,mongo会判定为不同文档。
    db.collection.ensureIndex({author:1},{unique:true})
    下面的doc1、doc2被判定为不同文档:
    doc1:{author:{name:"kk",age:20}}
    doc2:{author:{age:20,name:"kk"}}
  • 数组唯一性。
    对数组索引是用唯一性约束,可以保证所有文档不会存在重叠的数组元素。下面的doc2,因为doc1中有t1,所以无法插入:
    db.collection.ensureIndex({tag:1},{unique:true})
    doc1:{tag:['t1','t2','t3']}
    doc2:{tag:['t1','t4']}
    但是数组索引上的唯一性约束,无法保证同一个文档中包含重复的元素,下面的doc可以插入:
    doc:{tag:['t1','t2','t1']}

注意
1) 不支持一个复合索引同时出现多个数组字段。
2) 唯一性索引对于文档中缺失的字段,会使用null值代替,因此不允许存在多个文档确实索引字段的情况(mysql可以插入多条null,唯一性对此没有约束,因为MySQL将NULL值视为不同的值)。
3)对于分片集合,unique不能保证字段的唯一性,因为插入和索引操作对于每个分片都是本地操作。
MongoDB does not support creating new unique indexes in sharded collections and will not allow you to shard collections with unique indexes on fields other than the _id field.

2. 分片上字段唯一性约束

这种情况有三种方法保证唯一字段的唯一性:
1)使用片键。
2)使用第二个集合保证唯一性。
3)使用本身便能保证唯一性的标识符。如ObjectId。

2.1 片键

开启一个集合的分片,之后mongo就可以在分片间分配这个集合的数据。如下,在test.users 分片集合,email有唯一约束。

db.runCommand( { shardCollection : "test.users" , key : { email : 1 } , unique : true } );
field type description
shardCollection string 集合名
key document 索引,必须在shardCollection命令之前被创建,除非集合为空。可以是单子段片键,也可以是复合片键
unique boolean 为true时,保证基础索引强制执行唯一约束

注意
1)单子段片键唯一性可以保证
2)复合片键只有document包含全部片键字段才能保证唯一性(与单库复合索引不同)
3)对 哈希索引 不能有唯一性约束.

2.2 使用第二个集合(代理集合)保证唯一性

创建另一个只包含唯一字段的不分片的集合,每次在写入主集合之前先将唯一字段的数据试图写入这个集合,若写入失败,则表示有冲突.

如果你的数据量比较小,可以不使用分片,就可以创建多个唯一索引了.

注意
1)你的应用必须能够捕获插入代理集合时产生的错误,并保证两个集合之前的一致性.
2)如果代理集合需要分片,必须使用你想要保证唯一性的字段做片键.
3)在对代理集合使用分片的情况下,如果想要保证多个字段的唯一性.必须对 每个保证唯一性的字段 都创建一个代理集合.如果使用一个代理集合用来确保多个字段的唯一性,这个代理集合 不能够 进行分片.

2.3 使用本身可以保证唯一的字段

保证唯一性最好的方法是创建自身可以保证唯一性的标识符(UUID),比如MongoDB的 ObjectId 值.

完结撒花
参考文档:
《MongoDB 进阶与实战:微服务整合、性能优化、架构管理》
https://mongoing.com/docs/tutorial/enforce-unique-keys-for-sharded-collections.html
https://docs.mongodb.com/v4.4/core/sharding-shard-key/

你可能感兴趣的:(mongodb 索引唯一性约束)