Database

用於 unix 的標準鍵/值數據儲存

  • March 15, 2020

我知道 unix 的鍵/值庫(berkeleydbgdbmredis …)。但在我開始編碼之前,我想知道是否有一個標準的 unix 工具可以讓我執行以下操作:

$ tool -f datastore.db put "KEY" "VALUE"
$ tool -f datastore.db put -f file_key_values.txt
$ tool -f datastore.db get "KEY"
$ tool -f datastore.db get -f file_keys.txt
$ tool -f datastore.db remove "KEY"
$ etc...

謝謝

我不認為有一個標準的工具。除了grep/ awk/sed等等。但是使用這個你需要關心很多其他的問題,比如鎖定、格式、特殊字元等。

我建議使用sqlite. 定義一個簡單的表,然後創建tool_get()tool_put()shell 函式。sqlite便攜,速度快。

您將免費獲得額外的靈活性。您可以定義約束、索引以調整您的腳本或在某一天以其他語言使用該數據庫。

如果您的數據庫足夠小,那麼您可以使用文件系統。這種方法的優點是它的技術含量很低,並且可以用很少的程式碼在任何地方工作。如果鍵由可列印字元組成且不包含/,則可以將它們用作文件名:

put () { key=$1; value=$2; printf %s "$value" >"datastore.db/$key"; }
get () { key=$1; cat "datastore.db/$key"; }
remove () { key=$1; rm "datastore.db/$key"; }

要容納任意密鑰,請使用密鑰的校驗和作為文件名,並可選擇儲存密鑰的副本(除非您對無法列出密鑰或告訴給定條目的密鑰是什麼感到滿意)。

put () {
 key=$1; value=$2; set $(printf %s "$key" | sha1sum); sum=$1
 printf %s "$key" >"datastore.db/$sum.key"
 printf %s "$value" >"datastore.db/$sum.value"
}
get () {
 key=$1; set $(printf %s "$key" | sha1sum); sum=$1
 cat "datastore.db/$1.value"
}
remove () {
 key=$1; set $(printf %s "$key" | sha1sum); sum=$1
 rm "datastore.db/$1.key" "datastore.db/$1.value"
}

請注意,上面的玩具實現並不是全部:它們沒有任何有用的事務屬性,例如原子性。然而,文件創建和重命名等基本文件系統操作是原子的,並且可以建構上述函式的原子版本。

這些直接到文件系統的實現僅適用於小型數據庫(最多幾千個文件)的典型文件系統。除此之外,大多數文件系統都很難處理大型目錄。您可以使用分層佈局使該方案適應更大的數據庫。例如,不是將所有文件儲存在一個目錄中,而是根據名稱的前幾個字元將它們儲存在單獨的子目錄中。這就是git所做的,例如:它的對象,由 SHA-1 雜湊索引,儲存在名為.git/objects/01/2345679abcdef0123456789abcdef01234567. 其他使用語義分層的程序範例是 Web 記憶體代理Wwwofflepolipo;兩者都將在 URL 中找到的頁面的記憶體副本儲存在名為的文件中www.example.com/HASH其中 HASH 是 URL 的某些雜湊的某種編碼。¹

效率低下的另一個原因是大多數文件系統在儲存小文件時會浪費大量空間——在典型文件系統上每個文件最多會浪費 2kB,與文件大小無關。

如果您選擇使用真正的數據庫,則無需放棄透明文件系統訪問的便利性。有幾種FUSE文件系統可以訪問數據庫,包括 Berkeley DB(使用Jeff Garzik 的 dbfs)、Oracle(使用Oracle DBFS)、MySQL(使用mysqlfs)等。

¹對於類似 的 URL http://unix.stackexchange.com/questions/21943/standard-key-value-datastore-for-unix,Polipo 使用文件unix.stackexchange.com/M0pPbpRufiErf4DLFcWlhw==,並在文件內添加一個標題,以明文形式指示實際 URL;文件名是 URL 的 MD5 雜湊(二進制)的 base64 編碼。Wwwoffle 使用該文件http/unix.stackexchange.com/DM0pPbpRufiErf4DLFcWlhw;文件名是 MD5 雜湊的本地編碼,伴隨文件http/unix.stackexchange.com/UM0pPbpRufiErf4DLFcWlhw包含 URL。

引用自:https://unix.stackexchange.com/questions/21943