2015-05-11 48 views
1

有幾個關於SO關於典型BLOB與文件系統問題的出色答案的問題。但是,他們中沒有一個似乎代表我的情況,所以我問這個。將圖像存儲在文件系統與數據庫中的問題

假設有一個社交網絡(當然是一種假想的場景),用戶可以隨意更改任何人的個人資料圖片。而每個用戶的配置文件存儲在一個MySQL表使用下面的模式:

ID [unsigned int, primary] 
USERNAME [varchar(20)] 
PROFILENAME [varchar(60)] 
PROFILEPIC [blob] 

現在,這裏的東西:如果我想輪廓圖像存儲爲服務器,而不是在數據庫中的BLOB上的文件?我可以理解,必須有某種命名約定才能確保所有文件具有唯一名稱,該名稱也將其映射到表格上的主鍵以便於訪問。所以說,主鍵是存儲在磁盤上的相應圖像的文件名。但在我的情況下,可能會同時讀取/寫入,而且其中很多。 MySQL通常會在沒有問題的情況下處理它,因爲它在更新時會鎖定該行。但是,如何處理文件系統模型中的這種情況呢?

回答

1

在您的應用程序層,您可以鎖定執行數據庫事務和文件IO的塊以緩解併發問題()。

在此塊中,在事務中運行插入/更新/刪除。按照添加/替換/刪除磁盤上的照片。我們來寫一些僞代碼:

lock (obj) 
{ 
    connection.StartTransaction(); 

    connection.PerformAction(); 
    if failed, return false; 

    photoMgmt.PerformAction(); 
    if failed, return false; 

    connection.CommitTransaction(); 
} 

對PHP應用類似的技術;另外使用flock來執行文件鎖定。

換句話說,在提交給文件系統後提交給DB。如果數據庫或文件系統操作失敗,請執行清理,以免保存更改。

我會使用bigint ID作爲磁盤上的主鍵和GUID文件名。如果用戶喜歡應用程序保存他們提供的名稱,我會創建一個名爲user_filename的字段來存儲用戶提供的文件名,並且爲了所有其他目的,我會使用GUID。

希望這會提供一些方向。

+0

我會看看flock()...是一個PHP noob,從來沒有聽說過它,但聽起來很有希望。一些問題:除了預期表中最終有比INT更多的行可以限定的情況之外,還有什麼特別的原因可以使BIGINT優於INT?他們說,與INT相比,BIGINT呈現查詢和索引較慢。另一個問題,GUID。爲什麼你更喜歡簡單地使用主鍵作爲文件名的GUID?只是想更好地理解你。 – TheLearner

+0

此外,考慮到每個圖像文件將小於20kB,你會看到任何優點,只是廢除所有的應用程序層開銷,只是將它們存儲爲BLOB? – TheLearner

+0

BIGINT對於大量記錄會有好處 - 您是對的。 INT是4個字節,BIGINT是8個字節。所以從技術上來說,使用INT會稍微提高速度,但不是很糟糕,我不這麼認爲。您可以在測試數據庫上運行場景,我相信速度差異可以忽略不計。我會在另一條評論中寫關於GUID的內容。 – zedfoxus

相關問題