2008-12-02 202 views
11

需要關於平面文件數據庫優點的知情選項。我正在考慮使用平面文件數據庫方案來管理自定義博客的數據。它將部署在Linux操作系統版本上,並以Java編寫。平面文件數據庫有什麼好處?

對於閱讀和寫作文章和評論的表現有什麼可能的否定或肯定?

文章檢索會因爲它是一個平面文件而不是RDBMS,如果它得到斜槓 - 虛擬出來的呢? (如意)

我不反對使用RDBMS,只是詢問社區對這種軟件架構方案的可行性的看法。

追問: 在這個問題上的情況下,我會看到「平面文件==基於文件系統」例如每個博客條目及其附帶的元數據是在一個文件中。 ,借該文件夾的日期結構(博客\ testblog2 \ 2008 \ 12 \ 01)== 2008年12月1日

+0

請澄清您對「平面文件」和「基於文件系統」數據庫之間區別的理解。否則,這個問題是無法回答的。 – 2008-12-02 02:51:26

+0

優秀點,在這個問題的情況下,我會看到「平面文件==文件系統爲基礎」例如每個博客條目及其隨附的元數據將在一個文件中。根據文件夾的日期結構來組織許多文件(blogs \ testblog2 \ 2008 \ 12 \ 01)== 12/01/2008 – 2008-12-02 03:19:43

回答

16

平面文件數據庫有它們自己的位置,並且對於正確的域很適用。

過去的郵件服務器和NNTP服務器真的推動了你能夠真正承擔這些事情的程度(實際上相當遠 - 文件系統可以有數百萬個文件和目錄)。

平面文件數據庫兩個最大的缺點是索引和原子更新,但如果該域適合這些可能不是問題。

但是,您可以,例如,適當的鎖定,至少在Unix上使用基本文件系統命令進行「原子」索引更新。

一個簡單的情況是讓索引過程在數據中運行,以臨時名稱創建新的索引文件。然後,完成後,只需將新文件重命名(系統調用rename(2)或shell mv命令)舊文件即可。重命名和mv是Unix系統上的原子操作(即它可以工作或不工作,並且在狀態之間永遠不會缺少「)。

與創建新條目相同。基本上將文件完全寫入臨時文件,然後重命名或mv到最後的地方。那麼你從來沒有在「DB」中的「中間」文件。否則,您可能會遇到競爭條件(例如讀取正在寫入的文件的進程,並且在寫入過程完成之前可能會結束 - 比較糟糕的競爭條件)。

如果您的主索引與目錄名稱一起工作良好,那麼工作得很好。例如,您可以使用哈希方案來創建目錄和子目錄以查找新文件。

使用文件名和目錄結構查找文件非常快,因爲現在大多數文件系統都將索引編入目錄。

如果你要將一百萬個文件放在一個目錄中,可能會有一些你想要查找的調整問題,但是出於這個方塊的考慮,大多數文件很容易處理10個。請記住,如果您需要掃描目錄,將會有很多文件需要掃描。通過目錄分區有助於防止這種情況發生。

但是,這一切都取決於您的索引和搜索技術。

實際上,提供靜態內容的現貨供應網絡服務器是一個大型的平面文件數據庫,並且該模型運行良好。最後,當然,你有許多免費的Unix文件系統級別的工具可供你使用,但是它們都有無數的文件(grep 1000000次,在文件中找到某些東西會有性能折衷 - 開銷簡單地加起來)。

如果你的所有文件都在同一個文件系統上,那麼在將相同的文件放在不同的位置(基本上用於索引)方面,硬鏈接也爲你提供了選項(因爲它們也是原子的)。例如,你可以有一個「today」目錄,一個「yesterday」目錄,一個「java」目錄以及實際的消息目錄。因此,可以在「today」目錄,「java」目錄(因爲該帖子標記爲「java」,比如說)以及在它的最後位置(例如/ articles/2008/12)鏈接帖子/01/my_java_post.txt)。然後,在午夜,你運行兩個進程。第一個將「今日」目錄中的所有文件,檢查它們的創建日期以確保它們不是「今天」(因爲該過程可能需要幾秒鐘,並且可能潛入一個新文件),並將這些文件重命名爲「昨天」。接下來,你爲「昨天」目錄做同樣的事情,只是在這裏你只要刪除它們,如果它們過時了。

同時,該文件仍然位於「java」和「.../12/01」目錄中。由於您使用的是Unix文件系統和硬鏈接,因此「文件」只存在一次,這些都只是指向文件的指針。它們都不是「該」文件,它們都是一樣的。

您可以看到,雖然每個單獨的文件移動是原子的,但批量不是。例如,當「today」腳本正在運行時,「yesterday」目錄可以很好地包含「昨天」和「前一天」的文件,因爲「昨天」腳本尚未運行。

在事務性數據庫中,您可以一次完成所有操作。

但是,簡單地說,這是一個久經考驗的方法。特別是,Unix對這個習慣用法非常合適,現代文件系統也可以很好地支持它。

13

(答案複製和修改here

我會組織了許多文件建議不要使用平面文件進行除只讀訪問之外的任何操作,因爲那樣你就必須處理併發問題,例如確保只有一個進程一次寫入文件。相反,我推薦使用SQLite,這是一個存儲在文件中的全功能SQL數據庫。 SQLite已經具有內置的併發性,所以你不必擔心文件鎖定之類的事情,而且讀取的速度非常快。

但是,如果您正在進行大量數據庫更改,最好在transaction內一次完成所有操作。這隻會將更改寫入文件一次,而不是每次發出更改查詢。這大大提高了進行多項更改的速度。

發出更改查詢時,無論它是否在tranasction中,整個數據庫都會被鎖定,直到該查詢結束。這意味着非常大的事務可能會對其他進程的性能產生不利影響,因爲它們必須等待事務完成才能訪問數據庫。在實踐中,我沒有發現這是顯而易見的,但嘗試最大限度地減少發出的數據庫修改查詢的數量總是一個好習慣,並且嘗試使用平面文件的速度肯定更快。

+0

我已經理解了Java人更喜歡HSQLDB而不是SQLite(我不知道爲什麼)。就像一個指向OP的指針。 – 2008-12-02 05:14:07

+0

據說現在H2比HSQLDB好。 – MetroidFan2002 2008-12-02 05:52:02

0

可怕的想法。追加將涉及每次你想添加一些東西時尋找文件的末尾。每次更新都需要重寫整個文件。閱讀涉及一個表掃描(或維護一個單獨的索引,這與編寫/更新會有相同的問題)。只需使用數據庫,當然,除非您重新實現了RDBMS已提供的所有內容,以使您的解決方案具有適度的可擴展性。

+0

注意:我正在談論一個「平面文件」而不是「基於文件系統」的數據庫。後者可能是小規模可行的。 – tvanfosson 2008-12-02 02:24:31

+0

@tvanfosson:你有什麼理由評論你自己的答案嗎?爲什麼不更新你的答案?這個評論讓我感到困惑。 – 2008-12-02 21:59:21

2

使用本機代碼編寫自己的引擎可以勝過通用數據庫。

但是,引擎的質量和功能級別永遠不會接近。所有數據庫爲您提供的核心功能 - 索引,交易,參照完整性 - 您必須自己實施所有這些功能。

沒有什麼比重新發明輪子(畢竟,Linux就是這樣),但要記住你的期望和時間承諾。

0

它們似乎適用於追加新數據的高寫入,低讀取,無更新數據庫。

Web服務器和他們的表兄弟很大程度上依賴於他們的日誌文件。

DBMS軟件也將它們用於日誌。

如果你的設計符合這些限制,你看起來很好。您可能希望將元數據和指針保存在數據庫中,並設置某種快速異步隊列寫入器來緩衝註釋,但文件系統在緩衝和寫入鎖定級別方面已經非常好。

0

平面文件數據庫是可能的,但考慮以下幾點。數據庫需要獲得所有ACID元素(原子性,一致性,隔離性和持久性),如果要確保所有這些都在一個平面文件中完成(特別是在併發訪問時),您基本上已經編寫了一個成熟的DBMS。

那麼爲什麼不首先使用全面的數據庫管理系統呢?

如果您只是選擇其中一種免費選項(SQLite,MySQL,PostgresSQL等),您將節省自己寫作(以及多次重寫,我會保證)的時間和金錢。 。

0

如果它足夠小並且沒有丟失隨機存取,則可以使用fiat文件數據庫。有很多隨機訪問的大文件會很慢。並沒有複雜的查詢。沒有加入,沒有總和,分組等。你也不能期望從平面文件中獲取分層數據。 XML格式對於複雜結構要好得多。

2

我回答這個問題不是爲了回答爲什麼平面文件數據庫好或壞,其他人已經做了充足的工作。

但是,有些人一直指着SQLite,它的工作很好。由於您使用的是Java,所以最好的選擇是使用HSQLDB,它與SQLite完全相同,但是在Java中實現並嵌入到您的應用程序中。

2

大多數時候一個平面文件數據庫就夠了現在。但是如果你用數據庫開始你的項目,你會感謝你年輕的自己。這可能是SQLite,如果您不想設置像PostgreSQL這樣的整個數據庫系統。

-1

查看結果http://jsondb.io開源的基於Java的數據庫有你正在尋找的大部分內容。 將數據保存爲平坦的.json文件,多線程支持,加密支持,ORM支持,原子性支持,基於XPATH的高級查詢支持。

聲明:我創建了這個數據庫。