Какую базу данных следует использовать для хранения записей и как ее использовать?

Я разрабатываю приложение, которое будет хранить значительное количество записей. Эти записи будут иметь вид (URL, дата, название, источник, {необязательные данные...})

Поскольку это клиентское приложение, я не хочу использовать сервер базы данных, я просто хочу, чтобы информация хранилась в файлах.

Я хочу, чтобы файлы были доступны для чтения с разных языков (по крайней мере, python и C++), поэтому что-то специфичное для языка, такое как рассол python, не в игре.

Я вижу две возможности: sqlite и BerkeleyDB. Поскольку мой вариант использования явно не реляционный, у меня возникает соблазн использовать BerkeleyDB, однако я действительно не знаю, как мне использовать его для хранения моих записей, поскольку он хранит только пары ключ/значение.

Верны ли мои рассуждения? Если да, то как мне использовать BDB для хранения записей? Можете ли вы связать меня с соответствующей информацией? Или я пропустил лучшее решение?


person static_rtti    schedule 08.11.2009    source источник
comment
Спасибо всем вам, ребята, за ваши очень полезные ответы! Выбрать лучший было очень сложно :-/   -  person static_rtti    schedule 08.11.2009


Ответы (6)


Я вижу две возможности: sqlite и BerkeleyDB. Поскольку мой вариант использования явно не реляционный, у меня возникает соблазн использовать BerkeleyDB, однако я действительно не знаю, как мне использовать его для хранения моих записей, поскольку он хранит только пары ключ/значение.

То, что вы описываете, - это именно то, о чем идет речь, даже если вам нужна только одна таблица. SQLite, вероятно, сделает это очень просто.

EDIT: реляционная модель не имеет ничего общего с отношениями между таблицами. Отношение — это подмножество декартова произведения других множеств. Например, декартово произведение действительных чисел, действительных чисел и действительных чисел (да, все три одинаковы) создают трехмерное координатное пространство, и вы можете определить отношение в этом пространстве с помощью формулы, скажем, x*y = z. каждый возможный набор координат (x0,y0,z0) либо находится в отношении, если они удовлетворяют заданной формуле, либо нет.

Реляционная база данных использует эту концепцию с несколькими дополнительными требованиями. Во-первых, и это наиболее важно, размер отношения должен быть конечным. Приведенное выше отношение произведения не удовлетворяет этому требованию, потому что существует бесконечно много троек, удовлетворяющих формуле. Есть ряд других соображений, которые больше связаны с тем, что практично или полезно на реальных компьютерах, решающих реальные задачи.

Лучший способ осмыслить проблему — подумать о том, где каждый тип механизма сохраняемости работает лучше, чем другой. Вы уже понимаете, что реляционное решение имеет смысл, когда у вас есть много отдельных наборов данных (таблиц), которые должны поддерживать отношения между ними (ограничения внешнего ключа), которые практически невозможно реализовать с помощью хранилища ключей и значений. Еще одно реальное преимущество реляционной модели — это то, как она делает возможными расширенные специальные запросы с использованием правильных индексов. Это является следствием того, что уровень базы данных действительно понимает данные, которые он представляет.

Хранилище ключей-значений имеет свой собственный набор преимуществ. Одним из наиболее важных является способ масштабирования хранилищ ключей и значений. То, что memcached, couchdb, hadoop используют хранилище ключей и значений, потому что это легко для распределения поиска по ключу-значению на нескольких серверах. Еще одна область, в которой хорошо работает хранилище «ключ-значение», — это когда ключ или значение непрозрачны, например, когда сохраненный элемент зашифрован, чтобы его мог прочитать только его владелец.


Чтобы понять, что реляционная база данных работает хорошо, даже если вам просто не нужно более одной таблицы, рассмотрите следующее (не оригинальное):

SELECT t1.actor1 
FROM workswith AS t1, 
     workswith AS t2, 
     workswith AS t3, 
     workswith AS t4, 
     workswith AS t5,
     workswith AS t6
WHERE t1.actor2 = t2.actor1 AND
      t2.actor2 = t3.actor1 AND
      t3.actor2 = t4.actor1 AND
      t4.actor2 = t5.actor1 AND
      t5.actor2 = t6.actor1 AND
      t6.actor2 = "Kevin Bacon";

Что, очевидно, использует одну таблицу: workswith для вычисления каждого актера с номером бекона 6.

person SingleNegationElimination    schedule 08.11.2009
comment
Не могли бы вы уточнить? Для меня реляционная действительно имеет смысл только в том случае, если у вас есть несколько таблиц с отношениями между ними... - person static_rtti; 08.11.2009

BerkeleyDB хорош, также обратите внимание на воплощения *DBM (например, GDBM). Однако большой вопрос: что вам нужно искать? Вам нужно искать по этому URL-адресу, по диапазону URL-адресов или по датам, которые вы указали?

Также вполне возможно хранить группы записей в виде простых файлов в локальной файловой системе, сгруппированных по датам или условиям поиска и т. д.

Ответ на вопрос "поиск" является самым большим началом.

Что касается ключ/значение, вам нужно убедиться, что сам KEY правильно определен для ваших поисков. Если, например, вам нужно иногда искать по датам, а другие по заголовку, вам нужно будет поддерживать строку «запись», а затем, возможно, 2 или более строк «индекса», ссылающихся на исходную запись. Вы можете моделировать практически все в хранилище ключей/значений.

person Jé Queue    schedule 08.11.2009
comment
Вы можете моделировать практически все в хранилище ключей/значений. Не могли бы вы порекомендовать что-нибудь почитать по этому поводу? Я вижу, что эта модель очень общая, но было бы полезно прочитать несколько примеров. - person static_rtti; 08.11.2009
comment
Я вижу, что могу найти, но традиционные основы базового хранилища БД фактически представляют собой хранилище ключей/значений в том или ином механизме. Таблица кучи - это просто строки, записанные в ключ/значение, где строка является значением, а ключ представляет собой своего рода сгенерированный ROWID. Несоставной индекс в такой таблице содержит значения индекса в качестве ключа и ROWID в качестве значения. Конечно, все становится сложнее, но здесь применимо ничего не может быть решено без другого уровня косвенности. Я прокомментирую, если смогу найти несколько статей. - person Jé Queue; 08.11.2009

Лично я бы все равно использовал sqlite. Это всегда работало только для меня (и для других, с которыми я работаю). Когда ваше приложение разрастется и вам вдруг захочется сделать что-то более сложное, вам не придется переписывать его.

С другой стороны, я видел различные комментарии в списке разработчиков Python о Berkely DB, которые предполагают, что это далеко не так замечательно; вы получаете доступ только в стиле dict (что, если вы хотите выбрать определенные диапазоны дат или заголовки вместо URL-адресов); и его нет даже в стандартном наборе библиотек Python 3.

person andrew cooke    schedule 08.11.2009
comment
его даже нет в стандартном наборе библиотек Python 3. Не знал этого, это очень хороший момент, спасибо! - person static_rtti; 08.11.2009
comment
Пожалуйста, проверьте. Я посмотрел и вижу поддержку (g|n)dbm, но я думаю, что это другое, верно? Возможно, обсуждение, которое я помню в списке разработчиков, было связано с его удалением. - person andrew cooke; 08.11.2009

Как насчет MongoDB? Я еще не пробовал, но кажется интересным.

person Bastien Léonard    schedule 08.11.2009
comment
Выглядит интересно... Хотя, похоже, еще не созрел. - person static_rtti; 08.11.2009

Если вы собираетесь использовать только одно поле для поиска записей, хорошим выбором будет простое хранилище ключей и значений. Сохраните это единственное поле (или любой другой уникальный идентификатор) в качестве ключа, сериализуйте каждую запись в виде строки (используя JSON или аналогичный) и сохраните эту строку в качестве значения. Berkeley DB, безусловно, является разумным выбором для хранилища пар "ключ-значение", но есть много альтернатив на выбор: http://en.wikipedia.org/wiki/Dbm

Если вы хотите искать записи по любому из нескольких полей, SQLite может быть проще всего для целей разработки. Вы будете писать запросы на SQL, но вам не нужно будет поддерживать сервер базы данных. Вся многоклавишная техника уже написана за вас.

Если вы действительно хотите избежать использования SQL или максимально эффективно использовать хранилище данных, и вам нужен доступ с несколькими ключами, рассмотрите возможность добавления слоя дополнительной логики поверх хранилища ключей и значений. Поверх хранилищ пар "ключ-значение" можно создать поведение, подобное столбцу, путем сериализации записей и вставки значений "столбца" каждой записи в качестве дополнительных ключей, значения которых содержат "первичный" ключ вашей записи. (Вы эффективно используете хранилище ключей и значений как словарь записей и словарь индексов для поиска этих записей.) Google App Engine делает что-то подобное. Вы можете сделать это самостоятельно или использовать одну из различных баз данных, ориентированных на документы, которая сделает это за вас. Для интересного чтения попробуйте поискать в Google «nosql». http://www.google.com/search?&q=nosql

person ʇsәɹoɈ    schedule 08.11.2009
comment
P.S. Проблема с Berkeley DB в дистрибутиве Python заключается просто в том, что внутренние компоненты библиотеки bdb менялись чаще, чем разработчики Python хотели идти в ногу со временем. Дело не в том, что Berekeley DB был плохим, просто неудобно интегрировать его напрямую в релизы Python. Вы по-прежнему можете получить привязки bdb python в виде отдельного модуля. - person ʇsәɹoɈ; 08.11.2009

Итак, вы говорите, что просто сохраняете данные..? Вам действительно нужна БД только для поиска, поиска, суммирования и т. д. Итак, для хранения просто используйте простые текстовые файлы и добавляйте строки. Сжимайте данные, если нужно, используйте разделители между полями — почти любой язык сможет читать такие файлы. Если вы действительно хотите извлекать, сосредоточьтесь на своих потребностях в поиске, по дате, по ключу, какие ключи и т. д. Если вам нужна простая клиентская сторона, вам нужна простая клиентская БД. SQLite намного проще, чем BDB, но взгляните на такие вещи, как Sybase Advantage (очень быстрый и бесплатный для локальных клиентов, но не с открытым исходным кодом), VistaDB или firebird... но все они потребуют локальной конфигурации/настройки/обслуживания. Если вы используете локальный XML для «значительного» количества записей, это даст вам излишне раздутые размеры файлов..!

person andora    schedule 08.11.2009