Если ваша база данных достаточно мала, вы можете использовать файловую систему. Преимущество этого подхода состоит в том, что он очень низкотехнологичен и будет работать везде с очень небольшим количеством кода. Если ключи состоят из печатных символов и не содержат их /
, вы можете использовать их в качестве имен файлов:
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
. Другими примерами программ, которые используют семантическое наслоение, являются прокси веб-кэширования Wwwoffle и polipo ; оба хранят кэшированную копию страницы, найденной по URL, в файле с именемwww.example.com/HASH
где HASH - это некоторая кодировка некоторого хэша URL-адреса.
Еще одним источником неэффективности является то, что большинство файловых систем тратит много места при хранении небольших файлов - на типичных файловых системах тратится до 2 КБ на файл, независимо от размера файла.
Если вы решите использовать настоящую базу данных, вам не нужно отказываться от удобства прозрачного доступа к файловой системе. Есть несколько файловых систем FUSE для доступа к базам данных, включая Berkeley DB (с dbfs Джеффа Гарзика ), Oracle (с DBFS Oracle ), MySQL (с mysqlfs ) и т. Д.
¹
Для URL-адреса, например http://unix.stackexchange.com/questions/21943/standard-key-value-datastore-for-unix
, Polipo использует файл unix.stackexchange.com/M0pPbpRufiErf4DLFcWlhw==
с добавленным заголовком внутри файла, указывающим фактический URL-адрес в виде открытого текста; имя файла - это кодировка base64 хеша MD5 (в двоичном формате) URL. Wwwoffle использует файл http/unix.stackexchange.com/DM0pPbpRufiErf4DLFcWlhw
; имя файла является доморощенной кодировкой хэша MD5, а сопутствующий файл http/unix.stackexchange.com/UM0pPbpRufiErf4DLFcWlhw
содержит URL-адрес.