Redis - SET перезаписывает другие типы

Следующий пример кода будет выполнен/написан с помощью Python REPL и redis-cli.

Сервер Redis v=2.8.4

Предыстория: сохранение долговременного ключа (хэша) в хранилище ключей-значений redis, а затем попытка сохранить другой ключ (с тем же именем, но другим типом — строкой) в том же хранилище ключей-значений.

Сначала будет код, затем вопросы:

>>> import redis

>>> db = redis.Redis(
...     host='127.0.0.1',
...     port=6379, 
...     password='',
...     db=3)

>>> db.hset("123456", "field1", True)
1

>>> db.type("123456")
b'hash'

>>> db.hgetall("123456")
{b'field1': b'True'}

>>> db.set("123456", "new-value")
True

>>> db.type("123456")
b'string'

>>> db.get("123456")
b'new-value'

Сначала вы заметите, что опция SET перезаписывает HSET. Теперь, когда я пытаюсь перезаписать SET с помощью:

>>> db.lset("123456", "list1",  "list1value")
Traceback (most recent call last):
  ...
redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value
WRONGTYPE Operation against a key holding the wrong kind of value

ИЛИ заменив SET на тот же HSET:

>>> db.hset("123456", "field1", True)
Traceback (most recent call last):
  ...
redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value
WRONGTYPE Operation against a key holding the wrong kind of value

Чтобы убедиться, что это не ошибка redis-py, я проверил в redis-cli:

127.0.0.1:6379> HSET 12345 "field" "value1"
(integer) 0
127.0.0.1:6379> TYPE 12345
hash
127.0.0.1:6379> SET 12345 "newvalue"
OK
127.0.0.1:6379> TYPE 12345
string
127.0.0.1:6379> HSET 12345 "field" "value1"
(error) WRONGTYPE Operation against a key holding the wrong kind of value

Вопросы:

1) Является ли это недостатком Redis или так оно и должно работать?

2) Если это "как это должно работать", почему я не могу перезаписать тип SET другими?

** Редактировать: Как человек, отвечающий на вопрос, не понял 3).. Редактирую.

3) Какой другой тип, кроме SET, я могу использовать для хранения STRING в структуре (KEY, VALUE), где я также могу иметь HASH как (KEY, FIELD, VALUE) - где ключ тот же, но другого ТИПА ( с)?

Например. Я хочу сделать:

127.0.0.1:6379> HSET 12345 "field" "value1"
(integer) 0
127.0.0.1:6379> TYPE 12345
hash
127.0.0.1:6379> SOME-COMMAND 12345 "newvalue"
OK

Чтобы у меня был 1 хэш и 1 "другой" тип того же "ключа" 12345


person coolpy    schedule 23.12.2016    source источник
comment
Хорошо, почему бы вам не выдать DEL перед установкой ключа?   -  person Niloct    schedule 23.12.2016


Ответы (1)


  1. Это разработанное поведение, второе предложение в документации SET.

Если ключ уже содержит значение, оно перезаписывается независимо от его типа.

  1. Нет, такой силой обладает только SET, другие команды выдадут ошибку, если будут представлены значения неправильного типа.

  2. Извините, не слежу за вами.

person Itamar Haber    schedule 23.12.2016
comment
Ключ может иметь только один тип значения: строка, хэш, список, набор. Если вы хотите зарядить базовую структуру данных, сначала DEL введите ключ, а затем сохраните в нем новое значение. - person Itamar Haber; 23.12.2016
comment
@experiment пожалуйста, не звоните мне, сэр, сэр. У меня нет ответа, но я попытался помочь с комментарием. - person Itamar Haber; 04.10.2018