mongo unique key 索引可以为空吗

博客访问: 2071039
博文数量: 417
注册时间:
认证徽章:
ORACLE ACE-A,自07年接触ORACLE数据库,拥有7年ORACLE数据库运维经验,ACOUG,SHOUG核心成员,曾先后就职于东软集团股份有限公司、阿里巴巴(中国)网络科技有限公司,现就职于无锡新彩软件有限公司担任数据库架构师、DBA主管,负责公司数据库架构的设计、DB的规模化运维和性能调优。
ITPUB论坛APP
ITPUB论坛APP
APP发帖 享双倍积分
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: NoSQL
wxh:PRIMARY> db.coll.stats()
& & & & "ns" : "test.coll",
& & & & "count" : 4,
& & & & "size" : 144,
& & & & "avgObjSize" : 36,
& & & & "storageSize" : 4096,
& & & & "numExtents" : 1,
& & & & "nindexes" : 3,
& & & & "lastExtentSize" : 4096,
& & & & "paddingFactor" : 1,
& & & & "systemFlags" : 1,
& & & & "userFlags" : 0,
& & & & "totalIndexSize" : 24528,
& & & & "indexSizes" : {
& & & & & & & & "_id_" : 8176,
& & & & & & & & "id2_1" : 8176,
& & & & & & & & "x_1" : 8176
& & & & },
& & & & "ok" : 1
wxh:PRIMARY> db.coll.ensureIndex({x:1} ,{unique:true})
wxh:PRIMARY> db.coll.ensureIndex({x:1} ,{unique:true});db.runCommand({getLastError : 1})
& & & & "n" : 0,
& & & & "lastOp" : Timestamp(, 1),
& & & & "connectionId" : 86,
& & & & "err" : null,
& & & & "ok" : 1
wxh:PRIMARY> db.oplog.rs.find().sort({$natural:-1}).limit(2)
{ "ts" : Timestamp(, 1), "h" : NumberLong("-5236090"), "v" : 2, "op" : "i", "ns" : "test.system.indexes", "o" : { "_id" : ObjectId("52e06fec385d871d833ea696"), "ns" : "test.coll", "key" : { "x" : 1 }, "name" : "x_1", "unique" : true } }
{ "ts" : Timestamp(, 1), "h" : NumberLong("8694332"), "v" : 2, "op" : "i", "ns" : "test.system.indexes", "o" : { "_id" : ObjectId("52e06fcea695"), "ns" : "test.coll", "key" : { "x" : 1 }, "name" : "x_1", "unique" : true } }
MONGODB重复在已经存在索引的列上建立索引不报错,而且OPLOG里也会把这个操作记录进去,但是其实后台发现这个列上已经存在索引,并不会真正的去创建。
阅读(6576) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。MongoDB学习笔记(索引) - Stephen_Liu - 博客园
深入浅出、事半功倍
posts - 180, comments - 756, trackbacks - 0, articles - 0
一、索引基础:&& &MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧。下面是创建索引的命令:&& && db.test.ensureIndex({"username":1})&& &可以通过下面的名称查看索引是否已经成功建立:&& && db.test.getIndexes()&& &删除索引的命令是:&& && db.test.dropIndex({"username":1})&& &在MongoDB中,我们同样可以创建复合索引,如:&& &-- 数字1表示username键的索引按升序存储,-1表示age键的索引按照降序方式存储。&& && db.test.ensureIndex({"username":1, "age":-1})&& &该索引被创建后,基于username和age的查询将会用到该索引,或者是基于username的查询也会用到该索引,但是只是基于age的查询将不会用到该复合索引。因此可以说,如果想用到复合索引,必须在查询条件中包含复合索引中的前N个索引列。然而如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话,MongoDB可以智能的帮助我们调整该顺序,以便使复合索引可以为查询所用。如:&& && db.test.find({"age": 30, "username": "stephen"})&& &对于上面示例中的查询条件,MongoDB在检索之前将会动态的调整查询条件文档的顺序,以使该查询可以用到刚刚创建的复合索引。&& &我们可以为内嵌文档创建索引,其规则和普通文档没有任何差别,如:&& && db.test.ensureIndex({"comments.date":1})&& &对于上面创建的索引,MongoDB都会根据索引的keyname和索引方向为新创建的索引自动分配一个索引名,下面的命令可以在创建索引时为其指定索引名,如:&& && db.test.ensureIndex({"username":1},{"name":"testindex"})&& &&& &随着集合的增长,需要针对查询中大量的排序做索引。如果没有对索引的键调用sort,MongoDB需要将所有数据提取到内存并排序。因此在做无索引排序时,如果数据量过大以致无法在内存中进行排序,此时MongoDB将会报错。&&& 二、唯一索引:&& &在缺省情况下创建的索引均不是唯一索引。下面的示例将创建唯一索引,如:&& && db.test.ensureIndex({"userid":1},{"unique":true})&& &如果再次插入userid重复的文档时,MongoDB将报错,以提示插入重复键,如:&& && db.test.insert({"userid":5})&& && db.test.insert({"userid":5})&& &E11000 duplicate key error index: test.test.$userid_1& dup key: { : 5.0 }&& &&& &如果插入的文档中不包含userid键,那么该文档中该键的值为null,如果多次插入类似的文档,MongoDB将会报出同样的错误,如:&& && db.test.insert({"userid1":5})&& && db.test.insert({"userid1":5})&& &E11000 duplicate key error index: test.test.$userid_1& dup key: { : null }&& &&& &&& &如果在创建唯一索引时已经存在了重复项,我们可以通过下面的命令帮助我们在创建唯一索引时消除重复文档,仅保留发现的第一个文档,如:&& &--先删除刚刚创建的唯一索引。&& && db.test.dropIndex({"userid":1}) && &--插入测试数据,以保证集合中有重复键存在。&& && db.test.remove()&& && db.test.insert({"userid":5})&& && db.test.insert({"userid":5})&& &&& &--创建唯一索引,并消除重复数据。&& && db.test.ensureIndex({"userid":1},{"unique":true,"dropDups":true})&& &&& &--查询结果确认,重复的键确实在创建索引时已经被删除。&& && db.test.find()&& &{ "_id" : ObjectId("4fe823c180144abd15acd52e"), "userid" : 5 }&& &&& &&& &我们同样可以创建复合唯一索引,即保证复合键值唯一即可。如:&& && db.test.ensureIndex({"userid":1,"age":1},{"unique":true})&& &&&& 三、使用explain:&& &explain是非常有用的工具,会帮助你获得查询方面诸多有用的信息。只要对游标调用该方法,就可以得到查询细节。explain会返回一个文档,而不是游标本身。如:&& && db.test.find().explain()&& &{&&&&&&& "cursor" : "BasicCursor",&&&&&&& "nscanned" : 1,&&&&&&& "nscannedObjects" : 1,&&&&&&& "n" : 1,&&&&&&& "millis" : 0,&&&&&&& "nYields" : 0,&&&&&&& "nChunkSkips" : 0,&&&&&&& "isMultiKey" : false,&&&&&&& "indexOnly" : false,&&&&&&& "indexBounds" : {&&&&&&& }&& &&& &}&& &explain会返回查询使用的索引情况,耗时和扫描文档数的统计信息。&& &"cursor":"BasicCursor"表示没有使用索引。&& &"nscanned":1 表示查询了多少个文档。&& &"n":1 表示返回的文档数量。&& &"millis":0 表示整个查询的耗时。&&& 四、索引管理:&& &system.indexes集合中包含了每个索引的详细信息,因此可以通过下面的命令查询已经存在的索引,如:&& && db.system.indexes.find()&& &如果在为已有数据的文档创建索引时,可以执行下面的命令,以使MongoDB在后台创建索引,这样的创建时就不会阻塞其他操作。但是相比而言,以阻塞方式创建索引,会使整个创建过程效率更高,但是在创建时MongoDB将无法接收其他的操作。&& && db.test.ensureIndex({"username":1},{"background":true})你可能喜欢
12345678910
12345678910
关于本站 本站以分享运维技术为主,欢迎大家参与技术分享,同时也欢迎大家吐槽,本站提供以下交流圈:QQ群①:*****(满)QQ群②:6690706 QQ群③: QQ群④:(新) 微信公众号:ttlsacom 商务合作QQ:mongo&常用的命令
mongo&常用的命令
一个mongod服务可以有建立多个数据库,每个数据库可以有多张表,这里的表名叫collection,每个collection可以存放多个文档(document),每个文档都以BSON(binary
json)的形式存放于硬盘中,因此可以存储比较复杂的数据类型。它是以单文档为单位存储的,你可以任意给一个或一批文档新增或删除字段,而不会对其它文档造成影响,这就是所谓的schema-free,这也是文档型数据库最主要的优点。跟一般的key-value数据库不一样的是,它的value中存储了结构信息,所以你又可以像关系型数据库那样对某些域进行读写、统计等操作。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。Mongo还可以解决海量数据的查询效率,根据官方文档,当数据量达到50GB以上数据时,Mongo数据库访问速度是MySQL10
BSON是Binary JSON
的简称,是一个JSON文档对象的二进制编码格式。BSON同JSON一样支持往其它文档对象和数组中再插入文档对象和数组,同时扩展了JSON的数据类型。如:BSON有Date类型和BinDate类型。
BSON被比作二进制的交换格式,如同Protocol
Buffers,但BSON比它更“schema-less”,非常好的灵活性但空间占用稍微大一点。
BSON有以下三个特点:
1.& 轻量级
2.& 跨平台
3.& 效率高
MongoDB存储BSON对象到collections,这一系列的数据库名和collection名被称为一个命名空间。如同:java.util.L用来管理数据库中的数据。
mongodb可以对某个字段建立索引,可以建立组合索引、唯一索引,也可以删除索引,建立索引就意味着增加空间开销。默认情况下每个表都会有一个唯一索引:_id,如果插入数据时没有指定_id,服务会自动生成一个_id,为了充分利用已有索引,减少空间开销,最好是自己指定一个unique的key为_id,通常用对象的ID比较合适,比如商品的ID。
shell操作数据库:
超级用户相关:
1. #进入数据库admin
2. #增加或修改用户密码
db.addUser('name','pwd')
3. #查看用户列表
db.system.users.find()
4. #用户认证
db.auth('name','pwd')
5. #删除用户
db.removeUser('name')
6. #查看所有用户
show users
7. #查看所有数据库
8. #查看所有的collection
show collections
9. #查看各collection的状态
db.printCollectionStats()
10. #查看主从复制状态
db.printReplicationInfo()
11. #修复数据库
db.repairDatabase()
12. #设置记录profiling,0=off 1=slow 2=all
db.setProfilingLevel(1)
13. #查看profiling
show profile
14. #拷贝数据库
db.copyDatabase('mail_addr','mail_addr_tmp')
15. #删除collection
db.mail_addr.drop()
16. #删除当前的数据库
db.dropDatabase()
&& 2. 增删改
1. #存储嵌套的对象
db.foo.save({'name':'ysz','address':{'city':'beijing','post':100096},'phone':[138,139]})
2. #存储数组对象
db.user_addr.save({'Uid':'','Al':['test-','test-']})
3. #根据query条件修改,如果不存在则插入,允许修改多条记录
&&&&&&&&&&&
db.foo.update({'yy':5},{'$set':{'xx':2}},upsert=true,multi=true)
4. #删除yy=5的记录
&&&&&&&&&&&
db.foo.remove({'yy':5})
5. #删除所有的记录
&&&&&&&&&&&
db.foo.remove()
&& 3. 索引
1. #增加索引:1(ascending),-1(descending)
2. db.foo.ensureIndex({firstname: 1, lastname: 1}, {unique:
3. #索引子对象
4. db.user_addr.ensureIndex({'Al.Em': 1})
5. #查看索引信息
6. db.foo.getIndexes()
7. db.foo.getIndexKeys()
8. #根据索引名删除索引
9. db.user_addr.dropIndex('Al.Em_1')
&& 4. 查询
1. #查找所有
2. db.foo.find()
3. #查找一条记录
4. db.foo.findOne()
5. #根据条件检索10条记录
6. db.foo.find({'msg':'Hello 1'}).limit(10)
7. #sort排序
db.deliver_status.find({'From':''}).sort({'Dt',-1})
9. db.deliver_status.find().sort({'Ct':-1}).limit(1)
10. #count操作
11. db.user_addr.count()
12. #distinct操作,查询指定列,去重复
13. db.foo.distinct('msg')
14. #”&=”操作
15. db.foo.find({"timestamp": {"$gte" : 2}})
16. #子对象的查找
17. db.foo.find({'address.city':'beijing'})
&& 5. 管理
1. #查看collection数据的大小
2. db.deliver_status.dataSize()
3. #查看colleciont状态
4. db.deliver_status.stats()
5. #查询所有索引的大小
6. db.deliver_status.totalIndexSize()
5.& advanced queries:高级查询
条件操作符&
$ne : !=、&&&
$nin: not in&
$all: all&
$not: 反匹配(1.3.3及以上版本)
查询 name && "bruce" and age &= 18
db.users.find({name: {$ne: "bruce"}, age: {$gte: 18}});
查询 creation_date & '' and creation_date &=
'' 的数据&
db.users.find({creation_date:{$gt:new Date(), $lte:new
查询 age in (20,22,24,26) 的数据&
db.users.find({age: {$in: [20,22,24,26]}});
查询 age取模10等于0 的数据&
db.users.find('this.age % 10 == 0');&
db.users.find({age : {$mod : [10, 0]}});
db.users.find({favorite_number : {$all : [6,
可以查询出{name: 'David', age: 26, favorite_number: [ 6, 8, 9 ]
可以不查询出{name: 'David', age: 26, favorite_number: [ 6, 7, 9 ] }
查询不匹配name=B*带头的记录&
db.users.find({name: {$not: /^B.*/}});&
查询 age取模10不等于0 的数据&
db.users.find({age : {$not: {$mod : [10, 0]}}});
#返回部分字段&
选择返回age和_id字段(_id字段总是会被返回)&
db.users.find({}, {age:1});&
db.users.find({}, {age:3});&
db.users.find({}, {age:true});&
db.users.find({ name : "bruce" }, {age:1});&
0为false, 非0为true
选择返回age、address和_id字段&
db.users.find({ name : "bruce" }, {age:1, address:1});
排除返回age、address和_id字段&
db.users.find({}, {age:0, address:false});&
db.users.find({ name : "bruce" }, {age:0, address:false});
数组元素个数判断&
对于{name: 'David', age: 26, favorite_number: [ 6, 7, 9 ]
匹配db.users.find({favorite_number: {$size:
不匹配db.users.find({favorite_number: {$size: 2}});
$exists判断字段是否存在&
查询所有存在name字段的记录&
db.users.find({name: {$exists: true}});&
查询所有不存在phone字段的记录&
db.users.find({phone: {$exists: false}});
$type判断字段类型&
查询所有name字段是字符类型的&
db.users.find({name: {$type: 2}});&
查询所有age字段是整型的&
db.users.find({age: {$type: 16}});
对于字符字段,可以使用正则表达式&
查询以字母b或者B带头的所有记录&
db.users.find({name: /^b.*/i});
$elemMatch(1.3.1及以上版本)&
为数组的字段中匹配其中某个元素
Javascript查询和$where查询&
查询 age & 18 的记录,以下查询都一样&
db.users.find({age: {$gt: 18}});&
db.users.find({$where: "this.age &
db.users.find("this.age & 18");&
f = function() {return this.age & 18} db.users.find(f);
排序sort()&
以年龄升序asc&
db.users.find().sort({age: 1});&
以年龄降序desc&
db.users.find().sort({age: -1});
限制返回记录数量limit()&
返回5条记录&
db.users.find().limit(5);&
返回3条记录并打印信息&
db.users.find().limit(3).forEach(function(user) {print('my age is '
+ user.age)});&
my age is 18&
my age is 19&
my age is 20
限制返回记录的开始点skip()&
从第3条记录开始,返回5条记录(limit 3, 5)&
db.users.find().skip(3).limit(5);
查询记录条数count()&
db.users.find().count();&
db.users.find({age:18}).count();&
以下返回的不是5,而是user表中所有的记录数量&
db.users.find().skip(10).limit(5).count();&
如果要返回限制之后的记录数量,要使用count(true)或者count(非0)&
db.users.find().skip(10).limit(5).count(true);
分组group()&
假设test表只有以下一条数据&
{ domain: ""&
, invoked_at: {d:"",
t:"17:14:05"}&
, response_time: 0.05&
, http_action: "GET
/display/DOCS/Aggregation"&
使用group统计test表11月份的数据count:count(*)、total_time:sum(response_time)、avg_time:total_time/&
db.test.group(&
{ cond: {"invoked_at.d": {$gt: "2009-11", $lt:
"2009-12"}}&
, key: {http_action: true}&
, initial: {count: 0, total_time:0}&
, reduce: function(doc, out){ out.count++;
out.total_time+=doc.response_time }&
, finalize: function(out){ out.avg_time = out.total_time /
out.count }&
"http_action" : "GET
/display/DOCS/Aggregation",&
"count" : 1,&
"total_time" : 0.05,&
"avg_time" : 0.05&
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 mysql add unique key 的文章

 

随机推荐