Standardowy magazyn danych klucz / wartość dla unixa


16

Wiem o bibliotekach kluczy / wartości dla unixa ( berkeleydb , gdbm , redis ...). Ale zanim zacznę kodować, zastanawiam się, czy istnieje standardowe narzędzie dla Uniksa, które pozwoliłoby mi na wykonanie następujących operacji:

$ 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...

Dzięki

Odpowiedzi:


10

Nie sądzę, że istnieje do tego standardowe narzędzie. Z wyjątkiem grep/ awk/ seditd. Ale korzystając z tego, musisz zadbać o wiele innych problemów, takich jak blokowanie, format, znaki specjalne itp.

Proponuję użyć sqlite. Zdefiniuj prostą tabelę, a następnie utwórz tool_get()i tool_put()powłoki funkcji. sqlitejest przenośny, szybki.

Otrzymasz dodatkową elastyczność za darmo. Możesz zdefiniować ograniczenia, indeksować, aby ulepszyć skrypt lub użyć tego DB w innych językach.


Dziękuję Ci . Szybko napisałem narzędzie z API sqlite. To działa dobrze.
Pierre,

9

Jeśli baza danych jest wystarczająco mała, możesz użyć systemu plików. Zaletą tego podejścia jest to, że jest bardzo mało zaawansowany technologicznie i będzie działać wszędzie z bardzo małą ilością kodu. Jeśli klucze składają się ze znaków do wydrukowania i nie zawierają /, możesz użyć ich jako nazw plików:

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"; }

Aby pomieścić dowolne klucze, użyj sumy kontrolnej klucza jako nazwy pliku i opcjonalnie przechowuj kopię klucza (chyba że nie jesteś zadowolony z niemożności wypisania kluczy lub podania klucza dla danego wpisu).

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"
}

Zauważ, że powyższe implementacje zabawek nie są całą historią: nie mają żadnych użytecznych właściwości transakcyjnych, takich jak atomowość. Podstawowe operacje na systemie plików, takie jak tworzenie i zmiana nazw plików, są jednak atomowe i możliwe jest zbudowanie atomowych wersji powyższych funkcji.

Te implementacje bezpośredniego systemu plików są odpowiednie dla typowych systemów plików tylko dla małych baz danych, do kilku tysięcy plików. Poza tym większość systemów plików ma trudności z radzeniem sobie z dużymi katalogami. Możesz dostosować schemat do większych baz danych, używając układu warstwowego. Na przykład zamiast przechowywać wszystkie pliki w jednym katalogu, przechowuj je w osobnych podkatalogach na podstawie kilku pierwszych znaków ich nazw. Oto, co robi git , na przykład: jego obiekty, indeksowane skrótami SHA-1, są przechowywane w plikach o nazwie .git/objects/01/2345679abcdef0123456789abcdef01234567. Innymi przykładami programów korzystających z warstw semantycznych są serwery proxy do buforowania stron internetowych Wwwoffle i polipo ; oba przechowują w pamięci podręcznej kopię strony znalezionej pod adresem URL w pliku o nazwiewww.example.com/HASH gdzie HASH to kodowanie jakiegoś skrótu adresu URL.¹

Innym źródłem nieefektywności jest to, że większość systemów plików marnuje dużo miejsca podczas przechowywania małych plików - na typowych systemach plików marnuje się do 2kB na plik, niezależnie od jego wielkości.

Jeśli wybierzesz prawdziwą bazę danych, nie musisz rezygnować z wygody dostępu do przejrzystego systemu plików. Istnieje kilka systemów plików FUSE do uzyskiwania dostępu do baz danych, w tym Berkeley DB (z dbfs Jeffa Garzika ), Oracle (z Oracle DBFS ), MySQL (z mysqlfs ) itp.

¹ W przypadku takiego adresu URL http://unix.stackexchange.com/questions/21943/standard-key-value-datastore-for-unixPolipo używa pliku unix.stackexchange.com/M0pPbpRufiErf4DLFcWlhw==, z dodanym nagłówkiem w pliku wskazującym rzeczywisty adres URL zwykłym tekstem; nazwa pliku to kodowanie base64 skrótu MD5 (binarnie) adresu URL. Wwwoffle używa pliku http/unix.stackexchange.com/DM0pPbpRufiErf4DLFcWlhw; nazwa pliku to domowe kodowanie skrótu MD5, a plik towarzyszący http/unix.stackexchange.com/UM0pPbpRufiErf4DLFcWlhwzawiera adres URL.


7

dbmutilmoże dostać to, czego chcesz. Ma narzędzia powłoki do operacji opisanych w pytaniu. Nie powiedziałbym, że jest to dokładnie standard, ale ma odpowiednie udogodnienia.


5

Odkąd go nazwałeś, standardowy klient redis ma interfejs wiersza poleceń redis-cli. Niektóre przykłady z redis-cli -h:

 cat /etc/passwd | redis-cli -x set mypasswd
 redis-cli get mypasswd
 redis-cli -r 100 lpush mylist x

(A jeśli chcesz uzyskać dostęp do bazy danych przez system plików, możesz używać gniazd -s. Narzędzie, które odczytuje indeks bazy danych bezpośrednio przy każdym wywołaniu, byłoby bardzo nieefektywne.)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.