Решил написать этот пост в ответ на вопрос о CouchDB в Google+. Сразу оговорюсь, что специалистом по CouchDB я не являюсь и мой взгляд весьма поверхностный.

Главное отличие CouchDB от многочисленных РСУБД в том, что в CouchDB нет никакой схемы данных. База данных является хранилищем набора произвольных JSON-документов:

{ "type": "book", "title": "Voyna i mir", "author": "Tolstoi" }
{ "type": "movie", "title": "Stalker", "director": "Tarkovsky", "country": "USSR" }
...

Для запросов к этим данным используются заранее подготавливаемые view, состоящие из map/reduce-функций. Эти функции можно писать на JavaScript, Erlang или Java. Насколько я понимаю, можно подключить и другие языки.

На вход функции map подается каждый из документов базы данных, функция должна вернуть пару ключ-значение (или не вернуть, если документ нужно пропустить). Ключ может быть составным.

Например, чтобы выбрать все книги, можно использовать такую функцию:

function(doc) {
  if (doc.type == 'book') {
    emit(doc.title, doc);
  }
}

Её результат хранится как индекс по ключу (в примере выше ключ — это doc.title, значение — весь документ) и рассчитывается однажды при создании view, а затем обновляется при добавлении в БД новых документов.

Таким образом выборка из view производится по ключу или диапазону ключей из готового индекса, а потому работает очень быстро даже на больших объёмах данных.

Функция reduce получает на вход результирующий список ключей и значений. Она может использоваться, например, для группировки и/или как агрегирующая функция.

Логика функций может быть фактически произвольной и таким образом можно обрабатывать данные проще и гибче, чем с помощью SQL.

Join-ы в CouchDB делать можно, но как-то очень замысловато, я с этим пока толком не разобрался. Но с другой стороны, документы могут содержать массивы и вложенную иерархию, что во многих случаях и является смыслом join-ов в РСУБД:

{
  "type": "movie",
  "title": "Stalker",
  "director": "Tarkovsky",
  "country": "USSR",
  "keys": ["key1", "key2", "key3"],
  "attributes": {
     "attr1": "val1",
     "attr2": "val2" }
}

Документы являются неизменяемыми. При редактировании автоматически создаётся новая версия документа, а старая остается в БД. Размер базы может сильно распухать, если периодически не производить чистку. Этот нюанс делает CouchDB не очень пригодной для задач, где много редактируемых данных (этого лишена MongoDB).

Следствием такого подхода является гарантированное отсутствие блокировок. А так же хорошая поддержка master-master репликации (в отличие от MongoDB), т.е. можно иметь несколько серверов с идентичными данными. Это полезно, если надежность критична.

Доступ к данным осуществляется через HTTP (точнее REST-интерфейс). Не самый быстрый способ, но зато очень масштабируемый.