Что-то не так с созданием представлений Couch DB с нулевыми значениями?
В последнее время я довольно много работал с 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 ответ
Во-первых, вы, безусловно, можете поместить логику представления в код приложения - все, что вам нужно, - это соответствующая система сборки или развертывания, которая извлекает представления из приложения и добавляет их в проектный документ. Чего не хватает, так это возможности генерировать новые запросы на лету.
Ваш 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, и вы получите два разных документа с одинаковым адресом электронной почты.
Опять же, единственный способ выполнить транзакционную операцию "проверьте, существует ли она, создайте, если она не существует", состоит в том, чтобы все клиенты изменили один документ.