MongoDB 唯一索引

MongoDB支持的索引种类很多,诸如单键索引,复合索引,多键索引,TTL索引,文本索引,空间地理索引等。同时索引的属性可以具有唯一性,即唯一索引。唯一索引用于确保索引字段不存储重复的值,即强制索引字段的唯一性。缺省情况下,MongoDB的_id字段在创建集合的时候会自动创建一个唯一索引。本文主要描述唯一索引的用法。

一、创建唯一索引语法

    //语法
    db.collection.createIndex( <key and index type specification>, { unique: true } )

    语法更多描述可参考:http://blog.csdn.net/leshami/article/details/53541978

二、演示创建唯一索引

1、演示环境

    > db.version()
    3.2.10

    演示集合数据,可以参考:http://blog.csdn.net/leshami/article/details/52672310

    > db.persons.find().limit(1).pretty()
    {
            "_id" : ObjectId("5812cbaaa129eed14b46458d"),
            "name" : "robinson.cheng",
            "age" : 25,
            "email" : "robinson.cheng@qq.com",
            "score" : {
                    "c" : 89,
                    "m" : 96,
                    "e" : 87
            },
            "country" : "USA",
            "books" : [
                    "JS",
                    "C++",
                    "EXTJS",
                    "MONGODB"
            ]
    }

2、单个键(列)上的唯一索引

    > db.persons.createIndex({name:1},{unique:true})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    > db.persons.getIndexes()
    [
            {
                    "v" : 1,
                    "unique" : true,    //此处表示这个索引为唯一索引
                    "key" : {
                            "name" : 1
                    },
                    "name" : "name_1",
                    "ns" : "test.persons"
            }
    ]

3、基于复合键(列)的唯一索引

    > db.persons.createIndex({name:1,email:1},{unique:true})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 2,
            "numIndexesAfter" : 3,
            "ok" : 1
    }
    > db.persons.getIndexes()
    [
             {
                    "v" : 1,
                    "unique" : true,  //此处表示这个索引为唯一索引
                    "key" : {
                            "name" : 1,  //这个是索引对应的键,包括name和email
                            "email" : 1
                    },
                    "name" : "name_1_email_1",
                    "ns" : "test.persons"
            }
    ]

4、创建唯一索引的一些限制

    对于那些已经存在非唯一的列,在其上面创建唯一索引将失败
    不能够基于一个哈希索引指定唯一性

    Unique Constraint Across Separate Documents

    唯一的约束适用于集合中的单独的文档。也就是说,唯一的索引可以防止不同的文档具有相同的索引键值,
    但索引并不能阻止在基于数组或者内嵌文档创建的唯一索引上具有多个相同的值。
    在一个具有重复值的单个文档的情况下,重复的值仅插入到该索引一次。

    假定存在以下集合
    > db.collection.insert( { a: [ { b: 4 }, { b: 4 } ] } )
    WriteResult({ "nInserted" : 1 })

    > db.collection.find()
    { "_id" : ObjectId("58199898ae431a4615ec75ac"), "a" : [ { "b" : 4 }, { "b" : 4 } ] }

    在集合上a.b上创建一个唯一索引
    > db.collection.createIndex( { "a.b": 1 }, { unique: true } )
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }

    如果集合中没有文档上存在a.b为5的值,则唯一索引允许以下文档插入集合
    > db.collection.insert( { a: [ { b: 5 }, { b: 5 } ] } )
    WriteResult({ "nInserted" : 1 })
    > db.collection.insert( { a: [ { b: 5 }, { b: 5 } ] } )   //再次插入则提示错误
    WriteResult({
            "nInserted" : 0,
            "writeError" : {
                    "code" : 11000,
                    "errmsg" : "E11000 duplicate key error collection: test.collection index: a.b_1 dup key: { : 5.0 }"
            }
    })

    > db.collection.insert( { a: [ { b: 5 }] } )  //再次插入则提示错误,即使是该文档仅有一个相同的数组元素
    WriteResult({
            "nInserted" : 0,
            "writeError" : {
                    "code" : 11000,
                    "errmsg" : "E11000 duplicate key error collection: test.collection index: a.b_1 dup key: { : 5.0 }"
            }
    })
    > db.collection.insert( { a: [ { b: 6 }] } )
    WriteResult({ "nInserted" : 1 })

    Unique Index and Missing Field

    如果一个文档在一个唯一索引中没有索引字段的值,则该索引将为该文档存储一个空值。
    由于唯一约束限制,MongoDB只会允许一个文档缺少索引字段。
    对多于一个以上的文档没有索引字段的值或缺少索引字段,索引构建将失败,提示重复键错误。

    假定存在如下集合
    > db.mycol.insert({x:1})
    WriteResult({ "nInserted" : 1 })

    //为集合添加唯一索引
    > db.mycol.createIndex( { "x": 1 }, { unique: true } )
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }

    //再次插入x:1,如下,我们收到了错误提示
    > db.mycol.insert({x:1})
    WriteResult({
            "nInserted" : 0,
            "writeError" : {
                    "code" : 11000,
                    "errmsg" : "E11000 duplicate key error collection: test.mycol index: x_1 dup key: { : 1.0 }"
            }
    })

    //向集合插入文档x:2,y:2
    > db.mycol.insert({x:2,y:2})
    WriteResult({ "nInserted" : 1 })

    //插入一个缺少x键的新文档,如下,可以成功插入
    > db.mycol.insert({y:2})
    WriteResult({ "nInserted" : 1 })

    //再次插入一个缺少x键的新文档,提示重复
    > db.mycol.insert({z:1})
    WriteResult({
            "nInserted" : 0,
            "writeError" : {
                    "code" : 11000,
                    "errmsg" : "E11000 duplicate key error collection: test.mycol index: x_1 dup key: { : null }"
            }
    })

三、更多参考

MongoDB 单键(列)索引
MongoDB 复合索引
MongoDB 多键索引
MongoDB执行计划获取(db.collection.explain())

DBA牛鹏社(SQL/NOSQL/LINUX)

要在MongoDB创建唯一索引,可以使用db.collection.createIndex()方法,并将unique选项设置为true。例如,对于单字段的唯一索引,可以使用以下代码: db.collection.createIndex({ field: 1 }, { unique: true }) 这将在集合中的指定字段上创建一个唯一索引,并确保该字段的值是唯一的。如果尝试插入重复的值,将会引发错误。\[1\] 从MongoDB 4.2开始,对于4.2(或更高版本)的featureCompatibilityVersion(fCV),MongoDB使用一种新的内部格式来存储与早期MongoDB版本不兼容的唯一索引。这个新格式适用于现有的唯一索引以及新创建/重建的唯一索引。\[2\] 关于MongoDB创建唯一索引的更多信息,可以参考MongoDB官方文档中的唯一索引部分。\[3\] #### 引用[.reference_title] - *1* *2* [【MongoDB索引属性 之 唯一索引](https://blog.csdn.net/chechengtao/article/details/106884612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [MongoDB——索引属性之唯一索引(Unique Indexes)](https://blog.csdn.net/li1325169021/article/details/124571388)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风智语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值