過去我們在使用File System,我們必須自己處理備份、複製、擴充的問題;如今我們可以我們可以使用MongoDB作為File DB,它可以利用Replica和Sharing的機制幫助我們解決備份、複製、動態擴充、分散式儲存、自動平衡、故障回復的問題,且效能優於RDBMS。若真要說MongoDB這類NoSql的缺點就是它不能處理Transaction。
在MongoDB中對大於16MB BSON Document(如:圖片、音頻、影片等)是使用GridFS的方式做儲存。 GridFS是一種在MongoDB中存儲大二進製文件的機制,GridFS 會將文件分割成多個Chunk(預設256 KB),而GridFS使用fs.files和fs.chunks等兩個Collection來存儲檔案資料,其中fs.files負責存放文件的名稱、大小、上傳的時間等資訊,而fs.chunks則是負責存放經過分割後的Chunks,其優點是透過分割儲存的方式能夠快速讀取檔案中任何的片段。
fs.files Collection
{
"_id" : , // 檔案的Unique ID
"filename": data_string, //檔案名稱
"length" : data_number, // 檔案大小
"chunkSize" : data_number, // chunk大小,預設256k
"uploadDate" : data_date, // 儲存時間
"md5" : data_string //檔案的md5值
}
fs.chunks Collection
{
"_id" : , // 檔案chunk的Unique ID
"files_id" : , //對應檔案的Unique ID
"n" : chunk_number, // 檔案chunk的數量
"data" : data_binary, // 以二進為儲存檔案
}
在下面例子,我們將簡單地示範使用.NET MongoDB Driver來存取與操作MongoDB的GridFS。1. 首先,至NuGet安裝MongoDB的相關套件。
<package id="MongoDB.Bson" targetframework="net45" version="2.7.0">
<package id="MongoDB.Driver" targetframework="net45" version="2.7.0">
<package id="MongoDB.Driver.Core" targetframework="net45" version="2.7.0">
<package id="MongoDB.Driver.GridFS" targetframework="net45" version="2.7.0">
2. 接著使用MongoClient和IMongoDatabase連接MongoDB的資料庫。
3. 最後建立GridFSBucket以便操作GridFS,如呼叫UploadFromBytes、DownloadAsBytes等方法,執行檔案上傳與下載的作業。
public class FileInfo
{
public string Name { get; set; }
public byte[] Binary { get; set; }
}
public class MongoDB_FileStorage
{
private MongoClient _Conn =null;
private IMongoDatabase _DB = null;
public MongoDB_FileStorage(string connString, string databaseName) {
this._Conn = new MongoClient(connString);
this._DB = this._Conn.GetDatabase(databaseName);
}
public string UploadFile(FileInfo file)
{
GridFSBucket gridFS = new GridFSBucket(this._DB);
return gridFS.UploadFromBytes(file.Name, file.Binary).ToString();
}
public FileInfo DownloadFile(string fileId)
{
GridFSBucket gridFS = new GridFSBucket(this._DB);
string fileName = gridFS.Find(Builders.Filter.Eq(x => x.Id, new ObjectId(fileId))).FirstOrDefault().Filename;
FileInfo file = new FileInfo
{
Name = fileName,
Binary = gridFS.DownloadAsBytes(new ObjectId(fileId))
};
return file;
}
}
留言
張貼留言