Что-то не так с созданием представлений Couch DB с нулевыми значениями? - PullRequest
2 голосов
/ 30 января 2012

В последнее время я довольно много работал с Couch DB в свободное время, и мне очень нравится его использовать.Я считаю, что это гораздо более гибко, чем использование реляционной базы данных, но это не лишено недостатков.

Одним большим недостатком является отсутствие динамических запросов / генерации представлений ... Так что вам нужно сделать немалоработы по планированию и обоснованию ваших представлений, поскольку вы не можете использовать эту логику в коде приложения, как это можно сделать с SQL.

Например, я написал схему входа в систему на основе шаблона документа JSON, который выглядел какпримерно так:

{ 
   "_id": "blah",
   "type": "user",
   "name": "Bob",
   "email": "bob@theaquarium.com",
   "password": "blah",
}

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

emit(doc.name, null) 

Это показалось мне достаточно эффективным.Я думаю, что это намного лучше, чем перетаскивать целый список документов (или даже просто уменьшенное количество полей для каждого документа).Поэтому я сделал то же самое, чтобы создать список адресов электронной почты:

emit(doc.email, null)

Можете ли вы увидеть, куда я иду с этим вопросом?

В реляционной базе данных (с SQL) можно просто сделать два запроса к одной и той же таблице.Будет ли этот метод (приравнивать представление к продукту запроса SQL) чем-то аналогичным?

Тогда возникает проблема производительности / эффективности ... Должны ли эти два представления действительно быть только одним?Или использование представления Couch DB с ключами и никаким связанным значением не является эффективной практикой?Учитывая приведенный выше пример, оба этих представления будут использоваться вне схемы входа в систему ... Если мне когда-нибудь понадобится создать список имен пользователей, я могу получить их без дополнительных затрат.

Что выдумаю

1 Ответ

1 голос
/ 30 января 2012

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

Ваш emit(doc.field,null) подход, конечно, не удивителен или необычен. Фактически это обычный шаблон для запросов «найти документ по полю», когда документ извлекается с использованием include_docs=true. Также нет необходимости смешивать два представления в одно, единственное решение, связанное с производительностью, заключается в том, следует ли размещать два представления в одном и том же проектном документе: все виды в проектном документе обновляются при доступе к любому из них.

Конечно, ваш подход на самом деле не гарантирует, что электронные письма уникальны, даже если ваше приложение очень старается. Представьте себе следующие обстоятельства с двумя клиентскими приложениями A и B:

A: queries view, determines that `test@email.com` does not exist.
B: queries view, determines that `test@email.com` does not exist.
A: creates account with `test@email.com`
B: creates account with `test@email.com`

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

{
  _id: "test@email.com",
  type: "email"
  user: "000000001"
}

{
  _id: "000000001",
  type: "user", 
  email: "test@email.com",
  firstname: "Test", 
  ...
}

РЕДАКТИРОВАТЬ: шаблон резервирования работает только в том случае, если два клиента, пытающихся создать учетную запись для данного электронного письма, будут надежно пытаться получить доступ к тому же документу . Если вы случайно сгенерируете новый идентификатор, то клиент A создаст и зарезервирует документ XXXX, а клиент B создаст и зарезервирует документ YYYY, и вы получите два разных документа с одинаковым адресом электронной почты.

Опять же, единственный способ выполнить транзакционную проверку «если она существует, создать, если она не существует» - это заставить все клиенты изменить один документ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...