Соглашения об именовании ключей Redis?

226

Каковы обычные правила именования ключей в Redis? Я видел значения, разделенные, :но я не уверен, что такое обычное соглашение или почему.

Для пользователя вы бы сделали что-то вроде ...

user:00

если идентификатор пользователя был 00

Вы можете запросить только начало ключа, чтобы вернуть всех пользователей?

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

маскарадный
источник

Ответы:

205

Каковы обычные правила именования ключей в Redis? Я видел значения, разделенные: но я не уверен, что такое обычное соглашение или почему.

Да, знак двоеточия :является соглашением при именовании ключей. В этом уроке на сайте Redis указано: « Старайтесь придерживаться схемы. Например, «object-type: id: field» может быть хорошей идеей, как в «user: 1000: password». Мне нравится использовать точки для полей из нескольких слов, как в "comment: 1234: reply.to".

Вы можете запросить только начало ключа, чтобы вернуть всех пользователей?

Если вы имеете в виду что-то вроде прямого запроса для всех ключей, который начинается с, user:есть команда ключей для этого. Эта команда, однако, должна использоваться только для целей отладки, так как она O (N), потому что она ищет все ключи в базе данных.

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

yojimbo87
источник
1
scanне является опцией @EranH., это лучшая практика для итерации ключей. scanиспользуется для того, чтобы постепенно перебирать коллекцию элементов.
Кишор Павар
2
@ yojimbo87 Итак, будет две команды, скажем, во-первых, это создание ключа, такого как - пользователь: 808021: пароль = XYZ, а во-вторых, чтобы поместить ключ в реестр или индекс (установить), но что произойдет, если одна команда будет выполнена успешно и другой сбой означает, что ключи были созданы, но не получили запись в реестре.
LoveToCode
1
@LoveToCode Вы можете использовать транзакцию, которая должна гарантировать, что все или ни одна из операций не будет выполнена.
yojimbo87
2
Я также заметил, что Redis Desktop Manager (инструмент клиента Redis) также рассматривает двоеточие ':' как разделитель и отображает несколько ключей, сгруппированных вместе
Адам Ротару
1
Я придерживаюсь мнения, что уникальная ценность будет последней. Позволяет легко сделать что-то вроде:$redis->delete($redis->keys('user:password:*'));
Мелки
26

Мы используем двоеточие (:) в качестве разделителя пространства имен и хеш (#) для id-частей ключей, например:

logistics:building#23
Гвоздь
источник
Какое соглашение об именах лучше всего, если у вас есть больше ключей, таких как локаль, категория и т. Д.? {ресурс}: {ключ} # {значение}, {ключ} # {значение} => тексты: локаль # en, категория # 15? Или у вас есть другое предложение?
fsasvari
1
В моем примере «building» - это просто имя «collection», а 23 - это «id». Если у вас есть составной идентификатор с locale = en и category = 15, тогда фактический идентификатор может быть {en, 15}, поэтому пространство имен: тексты # {en, 15} или более подробный: пространство имен: тексты # {локаль = еп, категория = 15}. Но это всего лишь идея, я никогда не использовал это так. Будьте осторожны, чтобы не изменить порядок элементов id, потому что ключ, конечно, не будет найден. На самом деле, вместо того, чтобы кодировать такую ​​сложность в именах ваших ключей, рассмотрите возможность вместо этого использовать структуры данных redis. Взгляните на redis.io/topics/indexes
The Nail
16

Соглашение, кажется, двоеточие (:), но я веб-разработчик, поэтому я лично предпочитаю косую черту (/) для разделителя. Slash уже является настолько важным разделителем в URL-адресах, которые должны быть унифицированными локаторами ресурсов, так что это своего рода ключи для ресурсов. Зачем использовать другой подход с двоеточием (:)? Помогает ли это что-нибудь?

Рассмотрим этот пример:

У нас есть RESTful API для игрушечных объектов. Есть один:

http://example.com/api/toy/234 

Где у нас это хранится? Мы используем Redis и слэши, поэтому ключ очевиден:

toy/234

Это уникальный ключ для игрушки. Теперь ключ можно использовать и на стороне клиента:

{
    key: "toy/234",
    color: "red",
    url: function () {
        return API_BASE_URL + this.key;
    }
}

Пользователь запрашивает объект с ключом toy/666. Как получить его от Redis? Пример, связанный с Node.js:

redis.get(key, function reply_callback(error, toystring) {
    var toy = JSON.parse(toystring);
    ...
}

Не нужно конвертировать косую черту в двоеточие и наоборот. Удобно, тебе не кажется?

Примечание: всегда убедитесь, что пользователь может получить доступ только к тому, что вы хотели. Необработанный подход URL-to-key выше также может быть извлечен user/1/password, как отмечают комментаторы. Это не должно быть проблемой, если вы используете Redis в качестве общедоступного кэша только для чтения.

Аксели Пален
источник
24
… Удобно и почти отвратительно небезопасно. Вы просите, чтобы получить curl http://example.com/api/user/1/password'D, или подобное. (Просто
говорю
3
Двоеточия, хэши и слэши могут использоваться для обозначения различных уровней вложенности, например,User#23:uploads:my/path/to/file.ext
воплощение
31
Пожалуйста, никогда не принимайте пользовательский ввод в качестве ключа в базе данных.
Лайл
1
Мне нравится, как вы думали, что предпочитаете косые черты, потому что вы веб-разработчик.
Гектор Ордонес
@ELLIOTTCABLE Спасибо, добавил примечание о ненадежности. Видите ли вы какие-либо проблемы в этом подходе, если Redis используется в качестве общедоступного кэша только для чтения?
Аксели Пален
6

Я не знаю, есть ли на самом деле широко распространенные "лучшие практики" для именования ключей Redis.

Я экспериментировал с использованием символов ASCII NUL в качестве разделителей (поскольку Redis и Python оба 8-битные чистые). Это выглядит немного уродливо, если вы смотрите на необработанные ключи, но идея в том, чтобы скрыть это за слоем абстракции. Символы двоеточия и пробела являются очевидными альтернативами, если компоненты вашего пространства имен либо гарантированно не будут их использовать, либо вы готовы закодировать каждый компонент при необходимости. Тем не менее, если вы будете их кодировать, вы захотите разработать слой абстракции и в любом случае избегать просмотра необработанных ключей ... что вернуло меня к использованию \ 0 в моих рассуждениях.

Мне было бы интересно узнать, сформулированы ли другие мнения по этому поводу.

Джим Деннис
источник
0

Мне кажется, что для вашего случая лучше подойдет HSET / HGET . Также есть команда HKEYS .

Все эти команды имеют ту же сложность, что и GET / SET / KEYS, так почему бы не использовать их?

Вы могли бы иметь эту структуру тогда:

  • пользователи> 00> значение
  • пользователи> 01> значение

или:

  • пользователи: имя пользователя> 00> значение
  • пользователи: имя пользователя> 01> значение

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

витро
источник