![MongoDB进阶与实战:微服务整合、性能优化、架构管理](https://wfqqreader-1252317822.image.myqcloud.com/cover/697/38209697/b_38209697.jpg)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
4.5 唯一性约束
在现实场景中,唯一性是很常见的一种索引约束需求,重复的数据记录会带来许多处理上的麻烦,比如订单的编号、用户的登录名等。通过建立唯一性索引,可以保证集合中文档的指定字段拥有唯一值。
在创建索引时,通过指定unique=true选项可以将其声明为唯一性索引,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_76_1.jpg?sign=1738887784-8SWLeMkDRZpFQQjJnkxtlM9n6Q1PGQ9s-0-e295fb5ddace778e73040b50e21ffcc2)
此后,如果尝试写入两个拥有相同标题的book文档,则将会得到如下错误提示:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_76_2.jpg?sign=1738887784-bBg5eVYAvWTDcSG1O7vVI9oxxtMPiquz-0-4d8a7d20a05b60c58131bec86b2d5772)
对于指定字段已经存在重复记录的集合,如果尝试创建唯一性约束的索引,则会提示如下错误:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_76_3.jpg?sign=1738887784-Gks6y8ABIxyOMBsEMMyPKYvRUNva8YyJ-0-15bc85b48f49722ffa92a8287836b3a6)
1.复合索引的唯一性
除了单字段索引,还可以为复合索引使用唯一性约束。如果只是希望分类下的书籍标题保持唯一性,那么可以建立复合式的唯一性索引,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_76_4.jpg?sign=1738887784-4yMFdOrvWGrM8lBXD5kyXvjmDmfu0r8f-0-21d4d6c73787d8f3226e97051cd9ec15)
2.嵌套文档的唯一性
唯一性约束同样可以用于嵌套文档的某个字段,这和普通索引没有什么区别,比如:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_76_5.jpg?sign=1738887784-XAzSH2hUkfIDhUXWwFHB3WPJfroB8kqp-0-d6135b788703d82d8178b346ccbeae5a)
但如果希望将整个嵌套文档作为唯一性的保证,那么在使用时可能会造成困扰,比如:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_77_1.jpg?sign=1738887784-5PUXtaXEdpJ4WvLIdZiPnSqVFss84XJG-0-5537117231c5a4388d49c06fa6a7d357)
嵌套文档的唯一性约束是严格按照写入顺序进行比较的,如下代码所示,尽管写入的文档内容是一样的,但由于字段的顺序不一致,MongoDB仍然认为这是不同的文档。为了避免产生困扰,建议尽量少用这种做法。
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_77_2.jpg?sign=1738887784-mBJVMNG97zNe26m8gEmXEONQMKBiVAqj-0-3c28b5657e45840191738b1edc805d1a)
3.数组的唯一性
如果对数组索引(multikey index)使用唯一性约束,那么可以保证所有的文档之间不会存在重叠的数组元素,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_77_3.jpg?sign=1738887784-FtW451yZWHVQSC7rcbwfqVhVx2inm5Xo-0-5e63badf0a18edb0798f94aa79be1b2e)
但是,数组索引上的唯一性约束并无法保证同一个文档中包含重复的元素,如下面的语句是可以写入成功的:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_77_4.jpg?sign=1738887784-tc2B5TplrlKG9tdR6SbCv1MaFunOwes7-0-02de41e9c3eee102a6bd5c1e16382b88)
注意,如果数组中的元素是嵌套的文档,那么同样会遇到字段次序的问题。
4.使用约束
● 唯一性索引对于文档中缺失的字段,会使用null值代替,因此不允许存在多个文档缺失索引字段的情况。
● 对于分片的集合,唯一性约束必须匹配分片规则。换句话说,为了保证全局的唯一性,分片键必须作为唯一性索引的前缀字段。