Повторити ключові умови іменування?


226

Яка нормальна умова іменування для клавіш у redis? Я бачив значення, розділені, :але я не впевнений, що це нормальна умова, або чому.

Для користувача ви зробите щось на зразок ...

user:00

якщо ідентифікатор користувача був 00

Чи можете ви запитувати лише на початку ключа, щоб повернути всіх користувачів?

В основному я просто сподіваюся уникнути будь-яких майбутніх проблем, досліджуючи способи, які працюють на людей, і чому вони їх обрали.

Відповіді:


205

Яка нормальна умова іменування для клавіш у redis? Я бачив значення, розділені на: але я не впевнений, що це нормальна умова, або чому.

Так, знак двокрапки :- це умовна умова при іменуванні клавіш. У цьому підручнику на веб-сайті redis зазначено: Спробуйте дотримуватися схеми. Наприклад, "type-type: id: field" може бути гарною ідеєю, як, наприклад, у "user: 1000: password". Мені подобається використовувати крапки для полів з декількома словами, як, наприклад, у "коментар: 1234: відповідь.to".

Чи можете ви запитувати лише на початку ключа, щоб повернути всіх користувачів?

Якщо ви маєте на увазі щось, як безпосередньо запит для всіх клавіш, який починається з, для user:цього є команда ключів . Однак цю команду слід використовувати лише для налагодження, оскільки це O (N), оскільки він шукає всі ключі, розміщені в базі даних.

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


1
scanце не варіант @EranH., це найкраща практика ітерації ключів. scanвикористовується для того, щоб поступово повторювати колекцію елементів.
Кішор Павар

2
@ yojimbo87 Отже, буде дві команди, що скажемо, перше - це створити ключ на зразок - user: 808021: password = XYZ, а другий - ввести ключ у реєстр чи індекс (set), але що буде, коли одна команда буде успішно виконана та інше виходить з ладу означає, що ключі були створені, але не входять до реєстру.
LoveToCode

1
@LoveToCode Ви можете використовувати транзакції, які повинні гарантувати, що всі або жодна операція буде виконана.
yojimbo87

2
Я також помітив, що Redis Desktop Manager (клієнтський інструмент Redis) також розглядає двокрапку ":" як роздільник і відображає кілька клавіш, згрупованих разом
Адам Ротару

1
Я вважаю, що унікальне значення має останнє значення. Це полегшує зробити щось на кшталт:$redis->delete($redis->keys('user:password:*'));
Олівці

26

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

logistics:building#23

Яка найкраща угода про ім'я, якщо у вас є більше ключів, як локаль, категорія тощо? {resource}: {key} # {value}, {key} # {value} => тексти: locale # en, категорія # 15? Або у вас є якась інша пропозиція?
fsasvari

1
У моєму прикладі "будівля" - це лише назва "колекції", а 23 - звичайний "id". Якщо у вас є складений ідентифікатор з locale = en та категорія = 15, то фактичний ідентифікатор може бути {en, 15}, тому простір імен: тексти # {en, 15} або бути більш багатослівним: namespace: тексти # {locale = en, категорія = 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-до-ключа може також отримати user/1/password, як зазначають коментатори. Це не повинно бути проблемою, якщо ви використовуєте Redis як загальнодоступний кеш лише для читання.


24
… Зручно і майже огидно небезпечно. Ви благаєте отримати curl http://example.com/api/user/1/password"d" чи подібне. (Просто кажу.)
ELLIOTTCABLE

3
Колони, хеши і коси можна використовувати для позначення різних рівнів вкладення, наприкладUser#23:uploads:my/path/to/file.ext
втілитись

31
Будь ласка, ніколи не приймайте введення користувача як ключ до бази даних.
Lyle

1
Мені подобається, як ти думав, що ти віддаєш перевагу косої риси, тому що ти веб-розробник.
Гектор Ордонез

@ELLIOTTCABLE Спасибі, додано примітку про невпевненість. Чи бачите ви якусь проблему в такому підході, якщо Redis використовується як загальнодоступний кеш лише для читання?
Акселі Пален

6

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

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

Мені буде цікаво побачити, чи формулюються якісь інші думки щодо цього.


0

Що стосується вашої корисної коробки, мені здається, HSET / HGET було б краще підійде. Також є команда HKEYS .

Усі ці команди мають таку ж складність, як GET / SET / KEYS, то чому б не використовувати їх?

Ви могли б мати цю структуру тоді:

  • користувачі> 00> значення
  • користувачі> 01> значення

або:

  • користувачі: ім'я користувача> 00> значення
  • користувачі: ім'я користувача> 01> значення

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.