mongodb 兩小時入門

来源:http://www.cnblogs.com/gy-ph/archive/2017/10/24/7725172.html
-Advertisement-
Play Games

傳統的電腦應用大多使用關係型資料庫來存儲數據,比如大家可能熟悉的MySql, Sqlite等等,它的特點是數據以表格(table)的形式儲存起來的。資料庫由一張張排列整齊的表格構成,就好像一個Excel表單一樣,每個表格會有若幹列,比如一個學生信息表,可能包含學號、姓名、性別、入學年份、高考成績、 ...


傳統的電腦應用大多使用關係型資料庫來存儲數據,比如大家可能熟悉的MySql, Sqlite等等,它的特點是數據以表格(table)的形式儲存起來的。資料庫由一張張排列整齊的表格構成,就好像一個Excel表單一樣,每個表格會有若幹列,比如一個學生信息表,可能包含學號、姓名、性別、入學年份、高考成績、籍貫等等。而表格的每一排,則是一個個學生的具體信息。在企業級應用和前互聯網時代,關係型資料庫幾乎是不二選擇。關係型資料庫的特點是有整齊劃一的組織,很方便對數據進行描述、插入、搜索。

想象有一個傳統的網上服裝商店吧,它的主要的數據可能是儲存在一張叫products的表單里,表單可能包含這些列:商品編號(ID)、名稱(Name)、商家(brand)、主目錄(cate)、子目錄(sub-cat)、零售價(price)、是否促銷(promotion)等等。如果有一個用戶想要查找所有價格低於300元的正在促銷的鞋子的編號和名稱,則可以執行類似於以下的SQL語句:

SELECT ID, name FROM products WHERE cate='shoes' AND price<300 and AND promotion=true;

 

SQL具備了強大了的深度查詢能力,能滿足各式各樣的查詢要求。而如果要對數據進行添加和刪除,成本也是非常低的。這些是SQL的優勢之一, 但隨著互聯網的興起以及數據形式的多樣化,四平八穩的SQL表單在一些領域漸漸顯現出它的劣勢。讓我們通過一個例子來說明。考慮一個博客後臺系統,如果我們用關係型資料庫為每篇博客(article)建一個表單的話,這個表單大概會包括以下這些列:

IDTitleDescriptionAuthorContentLikes
A_1 Title1 Political Article Joe Content 1 12
A_2 Title2 Humorous Story Sam Content 2 50

這時候用SQL資料庫來存儲是非常方便的,但假如我們要位每篇文章添加評論功能,會發現每篇文章可能要多篇評論,而且這個數目是動態變化的,而且每篇評論還包括好幾項內容:評論的人、評論的時間、以及評論內容。這時候要將這些內容都塞進上述的那個表,就顯得很困難。通常的做法是為評論(comment)單獨建一個表:

IDAuthorTimeContentArticle
C_1 Anna 2014-12-26 08:23 Really good articles! A_1
C_2 David 2014-12-25 09:30 I like it! A_1

類似地,每篇文章可能會有若幹標簽(tags)。標簽本身又是一個表單:

IDCategoryTagsContentArticle
T_1 Anna 2014-12-26 08:23 Really good articles! A_1
T_2 David 2014-12-25 09:30 I like it! A_2

而博客的表格則要通過foreign key跟這些相關聯的表格聯繫起來(可能還包括作者、出版社等其它表格)。這樣一來,當我們做查詢的時候,比如說,“找出評論數不少於3的標簽為‘政治評論’的作者為Sam的文章”,就會涉及到複雜的跨表查詢,需要大量使用join語句。這種跨表查詢不僅降低了查詢速度,而且這些語句寫起來也不簡單。

那麼,如果用MongoDB資料庫來實現,可以如何設計數據模型呢?很簡單,像下麵這樣:

 _id: POST_ID
   title: TITLE_OF_POST, 
   description: POST_DESCRIPTION,
   author: POST_BY,
   tags: [TAG1, TAG2, TAG3],
   likes: TOTAL_LIKES, 
   comments: [    
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
      },
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
      }
   ]

 

在MongoDB里,每篇博客文章以一個文檔(document)的形式保存起來,而文檔內部包含了很多項目,比如title tags等,每一個項目都是key-value的形式,即有一個項目的名字,比如title,以及它的值TITLE_OF_POST。而重要的是,一個key可以有多個values,他們用[]括起來。

這種“寬鬆”的數據存儲形式非常靈活,MongoDB不限制每個key對應的values的數目。比如有的文章沒有評論,則它的值就是一個空集,完全沒有問題;有的文章評論很多,也可以無限制地插入。更靈活的是,MongoDB不要求同一個集合(collection,相當於SQL的table)裡面的不同document有相同的key,比如除了上述這種文檔組織,有的文檔所代表的文章可能沒有likes這個項目,再比如有的文章可能有更多的項目,比如可能還有dislikes等等。這些不同的文檔都可以靈活地存儲在同一個集合下,而且查詢起來也異常簡單,因為都在一個文檔里,不用進行各種跨文檔查詢。而這種MongoDB式的存儲也方便了數據的維護,對於一篇博客文章來說,所有的相關數據都在這個document裡面,不用去考慮一個數據操作需要involve多少個表格。

當然,除了上述的優點,MongoDB還有不少別的優勢,比如MongoDB的數據是用JSON(Javascript Object Notation)存儲的(就是上面的這種key-value的形式),而幾乎所有的web應用都是基於Javascript的。因此,存儲的數據和應用的數據的格式是高度一致的,不需經過轉換。更多的優點可以查看:[2]

2. 關於這篇文章

這個極簡教程,或者說筆記,並不是一個覆蓋MongoDB方方面面的教程。所謂極簡的意思,就是只選取那些最重要、最常用的內容進行基於實例的介紹,從而讓讀者能夠在最短的時間內快速上手,並且能順利地進行後續的縱深的學習。

具體地說,這個教程的特點是:

  • 不求全面,只求實用。只覆蓋最核心的部分;
  • 以大量例子為導向;
  • 一邊閱讀一邊動手操作的話,大約只需要2小時的時間;

閱讀這篇文章不需要有特別的基礎,但最好知道資料庫的基本概念,如果本身熟悉SQL那就更好啦。

3. 安裝與環境

MongoDB可以在Windows、Linux、Mac OS X等主流平臺運行,而且下載和安裝非常簡單,非常友好。這篇文檔的例子採用MongoDB 2.6版本,均在OS X測試過,有充足的理由相信,在其它平臺也能順利運行。

4. 創建集合和刪除集合

在上一節執行完步驟6後,你會看到命令行里顯示:`connecting to: test`,這裡的`test`是預設的資料庫。這裡我們可以新建一個資料庫。在命令行里打入:

use tutorial

 

這樣就新建了一個叫做tutorial的資料庫。你可以執行

show databases

 

來顯示當前的資料庫。不過這時候由於我們的新資料庫是空的,所以會顯示類似這樣的:

admin  (empty)
local  0.078GB

 

我們試著往我們的資料庫里添加一個集合(collection),MongoDB里的集合和SQL裡面的表格是類似的:

db.createCollection('author')

 

順利的話會顯示:

{ "ok" : 1 }

表示創建成功。

你可以再回頭執行:

show databases

這時候我們的tutorial集合已經位列其中。你可以再執行

show collections

可以看到創建的集合author也在其中。

我們暫時不需要author這個集合,所以我們可以通過執行:

db.author.drop()

來將其刪除。這時候你再執行show collections,就再也看不到我們的author了。

這一節要記住的點主要只有一個:集合(collection)類似於SQL的表格(table),類似於Excel的一個個表格。

5. 插入

想象一個精簡版的“豆瓣電影”。我們需要創建一個資料庫,來存儲每部電影的信息,電影的信息包括:

  • 電影名字
  • 導演
  • 主演(可能多個)
  • 類型標簽(可能多個)
  • 上映日期
  • 喜歡人數
  • 不喜歡人數
  • 用戶評論(可能多個)

顯然我們需要先創建一個叫電影的集合:

db.createCollection('movie')

然後,我們就可以插入數據了:

db.movie.insert(
 {
   title: 'Forrest Gump', 
   directed_by: 'Robert Zemeckis',
   stars: ['Tom Hanks', 'Robin Wright', 'Gary Sinise'],
   tags: ['drama', 'romance'],
   debut: new Date(1994,7,6,0,0),
   likes: 864367,
   dislikes: 30127,
   comments: [    
      {
         user:'user1',
         message: 'My first comment',
         dateCreated: new Date(2013,11,10,2,35),
         like: 0 
      },
      {
         user:'user2',
         message: 'My first comment too!',
         dateCreated: new Date(2013,11,11,6,20),
         like: 0 
      }
   ]
}
)

 

請註意,這裡插入數據之前,我們並不需要先聲明movie這個集合裡面有哪些項目。我們直接插入就可以了~這一點和SQL不一樣,SQL必須先聲明一個table裡面有哪些列,而MongoDB不需要。

把上面的例子複製進命令行應該可以順利運行,但我強烈建議你手動打一下,或者輸入一部你自己喜歡的電影。insert操作有幾點需要註意:

  • 1. 不同key-value需要用逗號隔開,而key:value中間是用冒號;
  • 2. 如果一個key有多個value,value要用[]。哪怕當前只有一個value,也加上[]以備後續的添加;
  • 3. 整個“數據塊”要用{}括起來;

如果你在insert之後看到WriteResult({ "nInserted" : 1 }),說明寫入成功。

這個時候你可以用查詢的方式來返回資料庫中的數據:

db.movie.find().pretty()

這裡find()裡面是空的,說明我們不做限制和篩選,類似於SQL沒有WHERE語句一樣。而pretty()輸出的是經格式美化後的數據,你可以自己試試沒有pretty()會怎麼樣。

仔細觀察find()的結果,你會發現多了一個叫'_id'的東西,這是資料庫自動創建的一個ID號,在同一個資料庫里,每個文檔的ID號都是不同的。

我們也可以同時輸入多個數據:

db.movie.insert([
 {
   title: 'Fight Club', 
   directed_by: 'David Fincher',
   stars: ['Brad Pitt', 'Edward Norton', 'Helena Bonham Carter'],
   tags: 'drama',
   debut: new Date(1999,10,15,0,0),
   likes: 224360,
   dislikes: 40127,
   comments: [    
      {
         user:'user3',
         message: 'My first comment',
         dateCreated: new Date(2008,09,13,2,35),
         like: 0 
      },
      {
         user:'user2',
         message: 'My first comment too!',
         dateCreated: new Date(2003,10,11,6,20),
         like: 14 
      },
      {
         user:'user7',
         message: 'Good Movie!',
         dateCreated: new Date(2009,10,11,6,20),
         like: 2
      }
   ]
},
{
   title: 'Seven', 
   directed_by: 'David Fincher',
   stars: ['Morgan Freeman', 'Brad Pitt',  'Kevin Spacey'],
   tags: ['drama','mystery','thiller'],
   debut: new Date(1995,9,22,0,0),
   likes: 134370,
   dislikes: 1037,
   comments: [    
      {
         user:'user3',
         message: 'Love Kevin Spacey',
         dateCreated: new Date(2002,09,13,2,35),
         like: 0 
      },
      {
         user:'user2',
         message: 'Good works!',
         dateCreated: new Date(2013,10,21,6,20),
         like: 14 
      },
      {
         user:'user7',
         message: 'Good Movie!',
         dateCreated: new Date(2009,10,11,6,20),
         like: 2
      }
   ]
}
])

 

順利的話會顯示:

BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 2,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]

錶面我們成功地插入了兩個數據。註意批量插入的格式是這樣的:db.movie.insert([{ITEM1},{ITEM2}])。幾部電影的外面需要用[]括起來。

請註意,雖然collection的插入不需要先聲明,但表達相同意思的key,名字要一樣,比如,如果我們在一個文檔里用directed_by來表示導演,則在其它文檔也要保持同樣的名字(而不是director之類的)。不同的名字不是不可以,技術上完全可行,但會給查詢和更新帶來困難。

好了,到這裡,我們就有了一個叫tutorial的資料庫,裡面有一個叫movie的集合,而movie裡面有三個記錄。接下來我們就可以對其進行查詢了。

6. 查詢

在上一節我們已經接觸到最簡單的查詢db.movie.find().pretty()。MongoDB支持各種各樣的深度查詢功能。先來一個最簡單的例子,找出大衛芬奇(David Fincher)導演的所有電影:

db.movie.find({'directed_by':'David Fincher'}).pretty()

 

將返回《搏擊俱樂部》和《七宗罪》兩部電影。這種搜索和SQL的WHERE語句是很相似的。

也可以設置多個條件。比如找出大衛芬奇導演的, 摩根弗里曼主演的電影:

db.movie.find({'directed_by':'David Fincher', 'stars':'Morgan Freeman'}).pretty()

 

這裡兩個條件之間,是AND的關係,只有同時滿足兩個條件的電影才會被輸出。同理,可以設置多個的條件,不贅述。

條件之間也可以是或的關係,比如找出羅賓懷特或摩根弗里曼主演的電影:

db.movie.find(
{
  $or: 
     [  {'stars':'Robin Wright'}, 
        {'stars':'Morgan Freeman'}
     ]
}).pretty()

 

註意這裡面稍顯複雜的各種括弧。

還可以設置一個範圍的搜索,比如找出50萬人以上贊的電影:

db.movie.find({'likes':{$gt:500000}}).pretty()

 

同樣要註意略複雜的括弧。註意,在這些查詢里,key的單引號都是可選的,也就是說,上述語句也可以寫成:

db.movie.find({likes:{$gt:500000}}).pretty()

 

類似地,少於二十萬人贊的電影:

db.movie.find({likes:{$lt:200000}}).pretty()

 

類似的運算符還有:$let:小於或等於;$get:大於或等於;$ne:不等於。

註意,對於包含多個值的key,同樣可以用find來查詢。比如:

db.movie.find({'tags':'romance'})

 

將返回《阿甘正傳》,雖然其標簽既有romance,又有drama,但只要符合一個就可以了。

如果你確切地知道返回的結果只有一個,也可以用findOne:

db.movie.findOne({'title':'Forrest Gump'})

 

如果有多個結果,則會按磁碟存儲順序返回第一個。請註意,findOne()自帶pretty模式,所以不能再加pretty(),將報錯。

如果結果很多而你只想顯示其中一部分,可以用limit()skip(),前者指明輸出的個數,後者指明從第二個結果開始數。比如:

db.movie.find().limit(2).skip(1).pretty()

 

則跳過第一部,從第二部開始選取兩部電影。

7. 局部查詢

第五節的時候我們講了find的用法,但對於符合條件的條目,我們都是返回整個JSON文件的。這類似於SQL裡面的SELECT *。有的時候,我們需要的,僅僅是部分數據,這個時候,find的局部查詢的功能就派上用場了。先來看一個例子,返回tags為drama的電影的名字和首映日期。

db.movie.find({'tags':'drama'},{'debut':1,'title':1}).pretty()

資料庫將返回:

{
    "_id" : ObjectId("549cfb42f685c085f1dd47d4"),
    "title" : "Forrest Gump",
    "debut" : ISODate("1994-08-05T16:00:00Z")
}
{
    "_id" : ObjectId("549cff96f685c085f1dd47d6"),
    "title" : "Fight Club",
    "debut" : ISODate("1999-11-14T16:00:00Z")
}
{
    "_id" : ObjectId("549cff96f685c085f1dd47d7"),
    "title" : "Seven",
    "debut" : ISODate("1995-10-21T16:00:00Z")
}

 

這裡find的第二個參數是用來控制輸出的,1表示要返回,而0則表示不返回。預設值是0,但_id是例外,因此如果你不想輸出_id,需要顯式地聲明:

db.movie.find({'tags':'drama'},{'debut':1,'title':1,'_id':0}).pretty()

 

8. 更新

很多情況下你需要更新你的資料庫,比如有人對某部電影點了個贊,那麼你需要更新相應的資料庫。比如有人對《七宗罪》點了個贊,而它本來的贊的個數是134370,那麼你需要更新到134371。可以這樣操作:

db.movie.update({title:'Seven'}, {$set:{likes:134371}})

 

第一個大括弧里表明要選取的對象,第二個表明要改動的數據。請註意上述的操作相當不現實,因為你首先要知道之前的數字是多少,然後加一,但通常你不讀取資料庫的話,是不會知道這個數(134370)的。MongoDB提供了一種簡便的方法,可以對現有條目進行增量操作。假設又有人對《七宗罪》點了兩個贊,則可以:

db.movie.update({title:'Seven'}, {$inc:{likes:2}})

如果你查詢的話,會發現點贊數變為134373了,這裡用的是$inc。除了增量更新,MongoDB還提供了很多靈活的更新選項,具體可以看:http://docs.mongodb.org/manual/reference/operator/update-field/ 。

註意如果有多部符合要求的電影。則預設只會更新第一個。如果要多個同時更新,要設置{multi:true},像下麵這樣:

db.movie.update({}, {$inc:{likes:10}},{multi:true})

所有電影的贊數都多了10.

註意,以上的更新操作會替換掉原來的值,所以如果你是想在原有的值得基礎上增加一個值的話,則應該用$push,比如,為《七宗罪》添加一個popular的tags。

db.movie.update({'title':'Seven'}, {$push:{'tags':'popular'}})

你會發現《七宗罪》現在有四個標簽:

	"tags" : [
		"drama",
		"mystery",
		"thiller",
		"popular"
	],

9. 刪除

刪除的句法和find很相似,比如,要刪除標簽為romance的電影,則:

db.movie.remove({'tags':'romance'})

考慮到我們資料庫條目異常稀少,就不建議你執行這條命令了~

註意,上面的例子會刪除所有標簽包含romance的電影。如果你只想刪除第一個,則

db.movie.remove({'tags':'romance'},1)

如果不加任何限制:

db.movie.remove()

會刪除movie這個集合下的所有文檔。

10. 索引和排序

為文檔中的一些key加上索引(index)可以加快搜索速度。這一點不難理解,假如沒有沒有索引,我們要查找名字為Seven的電影,就必須在所有文檔里逐個搜索。而如果對名字這個key加上索引值,則電影名這個字元串和數字建立了映射,這樣在搜索的時候就會快很多。排序的時候也是如此,不贅述。MongoDB裡面為某個key加上索引的方式很簡單,比如我們要對導演這個key加索引,則可以:

db.movie.ensureIndex({directed_by:1})

這裡的1是升序索引,如果要降序索引,用-1。

MongoDB支持對輸出進行排序,比如按名字排序:

db.movie.find().sort({'title':1}).pretty()

同樣地,1是升序,-1是降序。預設是1。

db.movie.getIndexes()

將返回所有索引,包括其名字。

db.movie.dropIndex('index_name')

將刪除對應的索引。

11. 聚合

MongoDB支持類似於SQL裡面的GROUP BY操作。比如當有一張學生成績的明細表時,我們可以找出每個分數段的學生各有多少。為了實現這個操作,我們需要稍加改動我們的資料庫。執行以下三條命令:

db.movie.update({title:'Seven'},{$set:{grade:1}})
db.movie.update({title:'Forrest Gump'},{$set:{grade:1}})
db.movie.update({title:'Fight Club'},{$set:{grade:2}})

這幾條是給每部電影加一個虛擬的分級,前兩部是歸類是一級,後一部是二級。

這裡你也可以看到MongoDB的強大之處:可以動態地後續添加各種新項目。

我們先通過聚合來找出總共有幾種級別。

db.movie.aggregate([{$group:{_id:'$grade'}}])

輸出:

{ "_id" : 2 }
{ "_id" : 1 }

註意這裡的2和1是指級別,而不是每個級別的電影數。這個例子看得清楚些:

db.movie.aggregate([{$group:{_id:'$directed_by'}}])

這裡按照導演名字進行聚合。輸出:

{ "_id" : "David Fincher" }
{ "_id" : "Robert Zemeckis" }

接著我們要找出,每個導演的電影數分別有多少:

db.movie.aggregate([{$group:{_id:'$directed_by',num_movie:{$sum:1}}}])

將會輸出:

{ "_id" : "David Fincher", "num_movie" : 2 }
{ "_id" : "Robert Zemeckis", "num_movie" : 1 }

註意$sum後面的1表示只是把電影數加起來,但我們也可以統計別的數據,比如兩位導演誰的贊比較多:

 db.movie.aggregate([{$group:{_id:'$directed_by',num_likes:{$sum:'$likes'}}}])

輸出:

{ "_id" : "David Fincher", "num_likes" : 358753 }
{ "_id" : "Robert Zemeckis", "num_likes" : 864377 }

註意這些數據都純屬虛構啊!

除了$sum,還有其它一些操作。比如:

db.movie.aggregate([{$group:{_id:'$directed_by',num_movie:{$avg:'$likes'}}}])

統計平均的贊。

db.movie.aggregate([{$group:{_id:'$directed_by',num_movie:{$first:'$likes'}}}]

返回每個導演的電影中的第一部的贊數。

其它各種操作可以參考:http://docs.mongodb.org/manual/reference/operator/aggregation/group/ 。

12. All or Nothing?

MongoDB支持單個文檔內的原子化操作(atomic operation),這是說,可以將多條關於同一個文檔的指令放到一起,他們要麼一起執行,要麼都不執行。而不會執行到一半。有些場合需要確保多條執行一起順次執行。比如一個場景:一個電商網站,用戶查詢某種商品的剩餘數量,以及用戶購買該種商品,這兩個操作,必須放在一起執行。不然的話,假定我們先執行剩餘數量的查詢,這是假定為1,用戶接著購買,但假如這兩個操作之間還加入了其它操作,比如另一個用戶搶先購買了,那麼原先購買用戶的購買的行為就會造成資料庫的錯誤,因為實際上這種商品以及沒有存貨了。但因為查詢剩餘數量和購買不是在一個“原子化操作”之內,因此會發生這樣的錯誤[2]

MongoDB提供了findAndModify的方法來確保atomic operation。比如這樣的:

db.movie.findAndModify(
			{
			query:{'title':'Forrest Gump'},
			update:{$inc:{likes:10}}
			}
		      )

query是查找出匹配的文檔,和find是一樣的,而update則是更新likes這個項目。註意由於MongoDB只支持單個文檔的atomic operation,因此如果query出多於一個文檔,則只會對第一個文檔進行操作。

findAndModify還支持更多的操作,具體見:http://docs.mongodb.org/manual/reference/command/findAndModify/。

13. 文本搜索

除了前面介紹的各種深度查詢功能,MongoDB還支持文本搜索。對文本搜索之前,我們需要先對要搜索的key建立一個text索引。假定我們要對標題進行文本搜索,我們可以先這樣:

db.movie.ensureIndex({title:'text'})

接著我們就可以對標題進行文本搜索了,比如,查找帶有"Gump"的標題:

db.movie.find({$text:{$search:"Gump"}}).pretty()

註意text和search前面的$符號。

這個例子里,文本搜索作用不是非常明顯。但假設我們要搜索的key是一個長長的文檔,這種text search的方便性就顯現出來了。MongoDB目前支持15種語言的文本搜索。

14. 正則表達式

MongoDB還支持基於正則表達式的查詢。如果不知道正則表達式是什麼,可以參考Wikipedia。這裡簡單舉幾個例子。比如,查找標題以b結尾的電影信息:

db.movie.find({title:{$regex:'.*b$'}}).pretty()

也可以寫成:

db.movie.find({title:/.*b$/}).pretty()

查找含有'Fight'標題的電影:

db.movie.find({title:/Fight/}).pretty()

註意以上匹配都是區分大小寫的,如果你要讓其不區分大小寫,則可以:

db.movie.find({title:{$regex:'fight.*b',$options:'$i'}}).pretty()

$i是insensitive的意思。這樣的話,即使是小寫的fight,也能搜到了。

15. 後記

至此,MongoDB的最基本的內容就介紹得差不多了。如果有什麼遺漏的以後我會補上來。如果你一路看到底完全了這個入門教程,恭喜你,你一定是一個有毅力的人。

把這個文檔過一遍,不會讓你變成一個MongoDB的專家(如果會那就太奇怪了)。但如果它能或多或少減少你上手的時間,或者讓你意識到“咦,MongoDB其實沒那麼複雜”,那麼這個教程的目的也就達到啦。

這個文檔是匆忙寫就的,出錯簡直是一定的。如果您發現了任何錯誤或者有關於本文的任何建議,麻煩發郵件給我(stevenslxie at gmail.com)或者在GitHub上直接交流,不勝感激。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux環境: 壹、首先查看mysql的數據存放路徑:ps -ef|grep mysql 貳、進入上述查出的mysql數據存放路徑:cd var/lib/mysql (數據存放路徑) 叄、導出資料庫用mysqldump命令 1、導出數據和表結構: mysqldump -u 用戶名 -p 資料庫名 ...
  • hive-version2.1.1 DDL操作 Create/Drop/Alter/Use Database 1 //示例 2 create database if not exists testdb; 1 //示例 2 drop database testdb; 說明:restrict不跟參數為默 ...
  • django.db.utils.OperationalError: (1267, "Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='") ...
  • 1.安裝過程沒有什麼說頭 2.下載並安裝SSMS(SQLServer Management Studio),目前已更新到2017.1 3.使用SSMS登陸資料庫 第一次選擇Windows 身份驗證,可免密碼直接登陸。 3.登陸後,創建自己的資料庫 右鍵資料庫文件夾,點擊新建資料庫。 4.作為開發測試 ...
  • 當一張表的數據非常多的時候,比如單個.myd文件都達到10G,必然讀取起來效率降低。這時就可以用mysql自帶的partition(分區功能),可以把表的數據分開在幾張表上,根據不同的區域來查詢數據以達到優化目的。mysql將會根據指定的規則,把數據放在不同的表文件上.相當於在文件上,被拆成了小塊. ...
  • JDBC 基本流程 1. 首先向項目中導入jar包 2. 創建如下代碼 3. 使用方法 載入properties配置文件 將資料庫的信息配置在properties中可以增加代碼的靈活性,修改的時候不需要去改動代碼. 可以將properties文件放在src文件夾下麵,這樣編譯完以後propertie ...
  • 事務的隔離級別: READ UNCOMMITTED(未提交讀) 在這個級別,事務中的修改,即使沒有提交,對其他事務也都是可見的,事務可以讀取未提交的數據。 READ COMMITTED(提交讀) 一個事務開始時,只能“看見”已經提交的事務所做的修改。也就是一個事務從開始知道提交前,所做的任何修改對其 ...
  • 在InnoDB加鎖前,為什麼要先start transaction innodb下鎖的釋放在事務提交/回滾之後,事務一旦提交/回滾之後,就會自動釋放事務中的鎖,innodb預設情況下autocommit=1即開啟自動提交 檢索條件使用索引和不使用索引的鎖區別: 檢索條件有索引的情況下會鎖定特定的一些 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...