mongodb與mysql命令詳細對比
傳統的關係資料庫一般由資料庫(database)、表(table)、記錄(record)三個層次概念組成,MongoDB是由資料庫(database)、集合(collection)、文件物件(document)三個層次組成。MongoDB對於關係型資料庫裡的表,但是集合中沒有列、行和關係概念,這體現了模式自由的特點。
MySQL |
MongoDB |
說明 |
mysqld |
mongod |
伺服器守護程序 |
mysql |
mongo |
客戶端工具 |
mysqldump |
mongodump |
邏輯備份工具 |
mysql |
mongorestore |
邏輯恢復工具 |
db.repairDatabase() |
修復資料庫 |
|
mysqldump |
mongoexport |
資料匯出工具 |
source |
mongoimport |
資料匯入工具 |
grant * privileges on *.* to … |
Db.addUser() Db.auth() |
新建使用者並許可權 |
show databases |
show dbs |
顯示庫列表 |
Show tables |
Show collections |
顯示錶列表 |
Show slave status |
Rs.status |
查詢主從狀態 |
Create table users(a int, b int) |
db.createCollection("mycoll", {capped:true, size:100000}) 另:可隱式建立表。 |
建立表 |
Create INDEX idxname ON users(name) |
db.users.ensureIndex({name:1}) |
建立索引 |
Create INDEX idxname ON users(name,ts DESC) |
db.users.ensureIndex({name:1,ts:-1}) |
建立索引 |
Insert into users values(1, 1) |
db.users.insert({a:1, b:1}) |
插入記錄 |
Select a, b from users |
db.users.find({},{a:1, b:1}) |
查詢表 |
Select * from users |
db.users.find() |
查詢表 |
Select * from users where age=33 |
db.users.find({age:33}) |
條件查詢 |
Select a, b from users where age=33 |
db.users.find({age:33},{a:1, b:1}) |
條件查詢 |
select * from users where age<33 |
db.users.find({'age':{$lt:33}}) |
條件查詢 |
select * from users where age>33 and age<=40 |
db.users.find({'age':{$gt:33,$lte:40}}) |
條件查詢 |
select * from users where a=1 and b='q' |
db.users.find({a:1,b:'q'}) |
條件查詢 |
select * from users where a=1 or b=2 |
db.users.find( { $or : [ { a : 1 } , { b : 2 } ] } ) |
條件查詢 |
select * from users limit 1 |
db.users.findOne() |
條件查詢 |
select * from users where name like "%Joe%" |
db.users.find({name:/Joe/}) |
模糊查詢 |
select * from users where name like "Joe%" |
db.users.find({name:/^Joe/}) |
模糊查詢 |
select count(1) from users |
Db.users.count() |
獲取表記錄數 |
select count(1) from users where age>30 |
db.users.find({age: {'$gt': 30}}).count() |
獲取表記錄數 |
select DISTINCT last_name from users |
db.users.distinct('last_name') |
去掉重複值 |
select * from users ORDER BY name |
db.users.find().sort({name:-1}) |
排序 |
select * from users ORDER BY name DESC |
db.users.find().sort({name:-1}) |
排序 |
EXPLAIN select * from users where z=3 |
db.users.find({z:3}).explain() |
獲取儲存路徑 |
update users set a=1 where b='q' |
db.users.update({b:'q'}, {$set:{a:1}}, false, true) |
更新記錄 |
update users set a=a+2 where b='q' |
db.users.update({b:'q'}, {$inc:{a:2}}, false, true) |
更新記錄 |
delete from users where z="abc" |
db.users.remove({z:'abc'}) |
刪除記錄 |
db. users.remove() |
刪除所有的記錄 |
|
drop database IF EXISTS test; |
use test db.dropDatabase() |
刪除資料庫 |
drop table IF EXISTS test; |
db.mytable.drop() |
刪除表/collection |
db.addUser(‘test', 'test') |
新增使用者 readOnly-->false |
|
db.addUser(‘test', 'test', true) |
新增使用者 readOnly-->true |
|
db.addUser("test","test222") |
更改密碼 |
|
db.system.users.remove({user:"test"}) 或者db.removeUser('test') |
刪除使用者 |
|
use admin |
超級使用者 |
|
db.auth(‘test', ‘test') |
使用者授權 |
|
db.system.users.find() |
檢視使用者列表 |
|
show users |
檢視所有使用者 |
|
db.printCollectionStats() |
檢視各collection的狀態 |
|
db.printReplicationInfo() |
檢視主從複製狀態 |
|
show profile |
檢視profiling |
|
db.copyDatabase('mail_addr','mail_addr_tmp') |
拷貝資料庫 |
|
db.users.dataSize() |
檢視collection資料的大小 |
|
db. users.totalIndexSize() |
查詢索引的大小 |
mongodb語法
MongoDB的好處挺多的,比如多列索引,查詢時可以用一些統計函式,支援多條件查詢,但是目前多表查詢是不支援的,可以想辦法通過資料冗餘來解決多表查詢的問題。
MongoDB對資料的操作很豐富,下面做一些舉例說明,內容大部分來自官方文件,另外有部分為自己理解。
查詢colls所有資料
db.colls.find() //select * from colls
通過指定條件查詢
db.colls.find({‘last_name': ‘Smith'});//select * from colls where last_name='Smith'
指定多條件查詢
db.colls.find( { x : 3, y : “foo” } );//select * from colls where x=3 and y='foo'
指定條件範圍查詢
db.colls.find({j: {$ne: 3}, k: {$gt: 10} });//select * from colls where j!=3 and k>10
查詢不包括某內容
db.colls.find({}, {a:0});//查詢除a為0外的所有資料
支援<, <=, >, >=查詢,需用符號替代分別為$lt,$lte,$gt,$gte
db.colls.find({ “field” : { $gt: value } } );
db.colls.find({ “field” : { $lt: value } } );
db.colls.find({ “field” : { $gte: value } } );
db.colls.find({ “field” : { $lte: value } } );
也可對某一欄位做範圍查詢
db.colls.find({ “field” : { $gt: value1, $lt: value2 } } );
不等於查詢用字元$ne
db.colls.find( { x : { $ne : 3 } } );
in查詢用字元$in
db.colls.find( { “field” : { $in : array } } );
db.colls.find({j:{$in: [2,4,6]}});
not in查詢用字元$nin
db.colls.find({j:{$nin: [2,4,6]}});
取模查詢用字元$mod
db.colls.find( { a : { $mod : [ 10 , 1 ] } } )// where a % 10 == 1
$all查詢
db.colls.find( { a: { $all: [ 2, 3 ] } } );//指定a滿足陣列中任意值時
$size查詢
db.colls.find( { a : { $size: 1 } } );//對物件的數量查詢,此查詢查詢a的子物件數目為1的記錄
$exists查詢
db.colls.find( { a : { $exists : true } } ); // 存在a物件的資料
db.colls.find( { a : { $exists : false } } ); // 不存在a物件的資料
$type查詢$type值為bsonhttp://bsonspec.org/數 據的型別值
db.colls.find( { a : { $type : 2 } } ); // 匹配a為string型別資料
db.colls.find( { a : { $type : 16 } } ); // 匹配a為int型別資料
使用正則表示式匹配
db.colls.find( { name : /acme.*corp/i } );//類似於SQL中like
內嵌物件查詢
db.colls.find( { “author.name” : “joe” } );
1.3.3版本及更高版本包含$not查詢
db.colls.find( { name : { $not : /acme.*corp/i } } );
db.colls.find( { a : { $not : { $mod : [ 10 , 1 ] } } } );
sort()排序
db.colls.find().sort( { ts : -1 } );//1為升序2為降序
limit()對限制查詢資料返回個數
db.colls.find().limit(10)
skip()跳過某些資料
db.colls.find().skip(10)
snapshot()快照保證沒有重複資料返回或物件丟失
count()統計查詢物件個數
db.students.find({‘address.state' : ‘CA'}).count();//效率較高
db.students.find({‘address.state' : ‘CA'}).toArray().length;//效率很低
group()對查詢結果分組和SQL中group by函式類似
distinct()返回不重複值
==========
由於公司系統使用MongoDB,雖然之前瞭解,但並沒有深入學習MongoDB。見此機會,參考《MongoDB 權威指南》深入學習,結合對比MySQL,加深對兩種不同資料庫的理解。特把學習過程記錄和大家分享。
一、 表結構對比
表結構對比 | MongoDB | MySQL |
---|---|---|
表 | collections | tables |
行 | documents | rows |
主鍵 | _id | id 與業務無關的值作為主鍵。如果沒有顯式地在表定義時指定主鍵,InnoDB儲存引擎會為每一行生成一個6位元組的ROWID |
主鍵生成策略 | 24位的字串(time + machine + pid + inc),自己指定 | UUID, 自增 |
面向Documents資料庫 | T | F |
面向行資料庫 | F | T |
約束 | 無 | 主鍵約束,外來鍵約束 |
二、 資料型別對比
資料型別對比 | MongoDB | MySQL |
---|---|---|
整形 | NumberInt("3"),NumberLong("3") | TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT |
浮點 | 預設使用64位浮點型數值 | FLOAT, DOUBLE, DECIMAL |
字元 | utf8 字串 | VARCHAR, CHAR |
日期/時間 | new Date(), 自新紀元依賴經過的毫秒數,不儲存時區 | DATE, DATETIME, TIMESTAMP |
NULL | null | 不支援(null與null不相等) |
布林型別 | true/false | 不支援 |
正則表示式 | 支援 { "x" : /foobar/i } | 不支援 |
陣列 | 支援 { "x" : ["a", "b", "c"]} | 不支援 |
二進位制資料 | 支援 GridFS | BLOB, TEXT |
程式碼片段 | { "x" : function() { /... / } } | 不支援 |
三、 SHELL終端對比
對比項 | MongoDB | MySQL |
---|---|---|
啟動 | mongo | mysql -u root -p |
檢視庫 | show dbs | show databases |
使用庫 | use test | use test |
查看錶 | show collections | show tables |
四、 查詢對比
查詢對比 | MongoDB | MySQL |
---|---|---|
檢索單列 | db.users.find({ "age" : 27 }) | SELECT * FROM users WHERE age = 27; |
檢索多列 | db.users.find({ "age" : 27, "username" : "joe" }) | SELECT * FROM users WHERE age = 27 and username = 'joe'; |
指定需要返回的鍵 | db.users.find({}, { "username" : 1, "email" : 1 }) | SELECT username, email FROM users; |
範圍檢索 | db.users.find({"age" : { "$gte" : 18, "$lte" : 30 }}) $lt, $lte, $gt, $gte 分別對應 <, <=, >, >= | SELECT * FROM users WHERE age >= 18 AND age <=30; |
不匹配檢索 | db.users.find({ "username" : { "$ne" : "joe" } }) | SELECT * FROM users WHERE username <> 'joe'; |
IN 操作符 | db.raffle.find({ "ticket_no" : { "$in" : [725, 542, 390] } }) $in非常靈活,可以指定不同型別 的條件和值。 例如在逐步將使用者的ID號遷移成使用者名稱的過程中, 查詢時需要同時匹配ID和使用者名稱 | SELECT ticket_no FROM raffles WHERE ticket_no IN (725, 542, 390); |
NOT IN 操作符 | db.raffle.find({ "ticket_no" : { "$nin" : [725, 542, 390] } }) | SELECT * FROM raffles WHERE ticket_no not in (725, 542, 390); |
OR 操作符 | db.raffle.find({ "$or" : [{ "ticket_no" : 725 }, { "winner" : true }] }) | SELECT * FROM raffles WHERE ticket_no = 725 OR winner = 'true'; |
空值檢查 | db.c.find({"y" : null}) null不僅會匹配某個鍵的值為null的文件 ,而且還會匹配不包含這個鍵的文件。 所以,這種匹配還會返回缺少這個鍵的所有文件。 如果 僅想要匹配鍵值為null的文件, 既要檢查改建的值是否為null, 還要通過 $exists 條件 判定鍵值已經存在 db.c.find({ "z" : { "$in" : [null], "$exists" : true }}) | SELECT * FROM cs WHERE z is null; |
多列排序 | db.c.find().sort({ username : 1, age: -1 }) | SELECT * FROM cs ORDER BY username ASC, age DESC; |
AND操作符 | db.users.find({ "$and" : [{ "x" : { "$lt" : 1 }, { "x" : 4 } }] }) 由於查詢優化器不會對 $and進行優化, 所以可以改寫成下面的 db.users.find({ "x" : { "$lt" : 1, "$in" : [4] } }) | SELECT * FROM users WHERE x > 1 AND x IN (4); |
NOT 操作符 | db.users.find({ "id_num" : { "$not" : { "$mod" : [5,1] } } }) | SELECT * FROM users WHERE id_num NOT IN (5,1); |
LIKE 操作符(正則匹配) | db.blogs.find( { "title" : /post?/i } ) MongoDB 使用Perl相容的正則表示式(PCRE) 庫來匹配正則表示式, 任何PCRE支援表示式的正則表示式語法都能被MongoDB接受 | SELECT * FROM blogs WHERE title LIKE "post%"; |
五、 函式對比
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2 } { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1 } { "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5 } { "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10 } { "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10 }
函式對比 | MongoDB | MySQL |
---|---|---|
COUNT | db.foo.count() | SELECT COUNT(id) FROM foo; |
DISTINCT | db.runCommand({ "distinct": "people", "key": "age" }) | SELECT DISTINCT(age) FROM people; |
MIN | db.sales.aggregate( [ { $group: { _id: {}, minQuantity: { $min: "$quantity" } } } ]); 結果: { "_id" : { }, "minQuantity" : 1 } | SELECT MIN(quantity) FROM sales; |
MAX | db.sales.aggregate( [ { $group: { _id: {}, maxQuantity: { $max: "$quantity" } } } ]); | SELECT MAX(quantity) FROM sales; |
AVG | db.sales.aggregate( [ { $group: { _id: {}, avgQuantity: { $avg: "$quantity" } } } ]); | SELECT AVG(quantity) FROM sales; |
SUM | db.sales.aggregate( [ { $group: { _id: {}, totalPrice: { $sum: "$price" } } } ]); | SELECT SUM(price) FROM sales; |
六、 CURD 對比
CURD 對比 | MongoDB | MySQL |
---|---|---|
插入資料 | post = {"title" : "My Blog Post", "content" : "Here`s my blog post"}; db.blog.insert(post) 如果blog 這個集合不存在,則會建立 | INSERT INTO blogs(title , blog_content ) VALUES ('My Blog Post', 'Here`s my blog post.') |
批量插入 | db.blog.batchInsert([{ "title" : "AAA", "content" : "AAA---" }, { "title" : "BBB", "content" : "JJJJ--" }]) 當前版本的MongoDB能接受最大訊息長度48MB, 所以在一次批量插入中能插入的文件是有限制的。 並且在執行批量插入的過程中,有一個文件插入失敗, 那麼在這個文件之前的所有文件都會成功插入到集合中, 而這個文件以及之後的所有文件全部插入失敗。 | INSERT INTO blogs(title , blog_content ) VALUES('AAA', 'AAA---'), ('BBB', 'BBB---'); |
查詢資料 | db.blog.find(); db.blog.findOne(); | SELECT * FROM blogs; SELECT * FROM blogs LIMIT 1; |
更新舊資料 | post.blog_content = "十一"; db.blog.update({title: "My Blog Post"}, post) | UPDATE set blog_content = "十一" WHERE title = "My Blog Post"; |
更新新增COLUMN | post.comments = "very good"; db.blog.update({title : "My Blog Post"}, post) | ALTER table blogs ADD COLUMN comments varchar(200); UPDATE blogs set comments = "very good" WHERE title = 'My Blog Post'; |
刪除資料 | db.blog.remove({ title : "My Blog Post" }) | DELETE FROM blogs WHERE title = 'My Blog Post' |
校驗 | post.blog_visit = 123; db.blog.update({title : "My Blog Post"}, post); post.blog_visit = "asd.123aaa"; db.blog.update({title : "My Blog Post"}, post) 插入的時候,檢查大小。所有的文件都必須小於16MB。 這樣做的目的是為了防止不良的模式設計,並且保持效能一直。由於MongoDB只進行最基本的檢查,所以插入非法的資料很容易。 | 型別校驗,長度校驗。 ALTER table blogs ADD COLUMN blog_visit INT(10); UPDATE blogs SET blog_visit = "asdasd" WHERE id = 1; ERROR 1366 (HY000): Incorrect integer value: 'asdasd' for column 'blog_visit' at row 1 |
刪除表 | db.blog.remove({}), db.blog.drop() | DELETE from blogs; drop table blogs; |