One, foreword

Redis provides five data types: String, Hash, List, Set, and Zset. Understanding the characteristics of each data type is important for the development and operation of Redis.

The original resolution

Set in Redis is a data type we often use and can be used in many scenarios depending on how it is used.

Second, the underlying implementation

The encoding of a collection object can be intSet or HashTable.

The intSet encoded collection object uses the integer set as the underlying implementation, and all elements contained in the collection object are stored in the integer set.

For example, the following code creates an intSet encoding collection object as shown in Figure 8-12:

redis> SADD numbers 1 3 5
(integer) 3
Copy the code

Structure Figure 8-12:

A HashTable encoded collection object, on the other hand, uses a dictionary as its underlying implementation. Each key of the dictionary is a string object, each string object contains a collection element, and the dictionary values are all set to NULL.

For example, the following code creates a HashTable encoded collection object as shown in Figure 8-13:

redis> SADD fruits "apple" "banana" "cherry"
(integer) 3
Copy the code

Structure Figure 8-13:

Three, coding conversion

The intSet encoding is used when a collection object can satisfy both of the following conditions:

1. All elements of the collection object are integer values; 2. The collection object stores a maximum of 512 elements.

Collection objects that do not meet these two criteria need to be encoded using HashTable.

Note: The upper limit of the second condition can be modified, as described in the configuration file for the set-max-intset-entries option. For intSet encoded collection objects, the encoding conversion operation is performed when either of the two conditions required for intset encoding cannot be met: All elements stored in the integer set will be moved and stored in the dictionary, and the encoding of the object will change from intSet to HashTable.

For example, the following code creates a collection object containing only integer elements encoded as intSet:

redis> SADD numbers 1 3 5
(integer) 3

redis> OBJECT ENCODING numbers
"intset"
Copy the code

However, as soon as we add a string element to the collection object, which contains only integer elements, the encoding shift of the collection object will be performed

redis> SADD numbers "seven"
(integer) 1

redis> OBJECT ENCODING numbers
"hashtable"
Copy the code

Otherwise, if we were to create a collection object with 512 integer elements, the object’s encoding would be intSet:

redis> EVAL "for i=1, 512 do redis.call('SADD', KEYS[1], i) end" 1 integers
(nil)

redis> SCARD integers
(integer) 512

redis> OBJECT ENCODING integers
"intset"
Copy the code

However, as soon as we add a new integer element to the set, making the number of elements in the set 513, the object’s encoding conversion will be performed:

redis> SADD integers 10086
(integer) 1

redis> SCARD integers
(integer) 513

redis> OBJECT ENCODING integers
"hashtable"
Copy the code

4. Command implementation

Because the values of collection keys are collection objects, all commands for collection keys are built for collection objects. The following table lists some of these commands and how they are implemented under different encoded collection objects.

The command Intset coding implementation method Implementation method of Hashtable coding
SADD Call intsetAdd to add all new elements to the set of integers. Call dictAdd, add the key-value pair to the dictionary with the new element as the key and NULL as the value.
SCARD Call intsetLen to return the number of elements in the set of integers. This number is the number of elements in the set object. Call the dictSize function to return the number of key-value pairs contained in the dictionary, which is the number of elements contained in the set object.
SISMEMBER IntsetFind is called to look for the given element in the set of integers. If found, the element exists in the set; if not, the element does not exist in the set. Call the dictFind function to search for a given element in the key of the dictionary. If it is found, it indicates that the element exists in the set; if it is not found, it indicates that the element does not exist in the set.
SMEMBERS Iterate over the entire collection of integers, using the intsetGet function to return the collection element. Walk through the dictionary, using the dictGetKey function to return the dictionary key as the set element.
SRANDMEMBER Call intsetRandom to return a random element from the set of integers. Call dictGetRandomKey to return a random dictionary key from the dictionary.
SPOP Call intsetRandom to remove a random element from the set of integers. After returning the random element to the client, call intsetRemove to remove the random element from the set of integers. The dictGetRandomKey function is called to pick out a random dictionary key from the dictionary. After returning the value of the random dictionary key to the client, the dictDelete function is called to delete the key value pair corresponding to the random dictionary key from the dictionary.
SREM The intsetRemove function is called to remove all given elements from the collection of integers. Call dictDelete to delete from the dictionary all key-value pairs whose keys are given elements.

5. Application scenarios

1. Draw

Lucky draw1) User participation lottery: SADD Order1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
    2) Check out all the people who entered the draw: SMEMBERS Order3) Repeat draw two people at a time: SMEMBERS Order2
    4) No repeat draw, third prize3Man, second prize2Man, first prize1People SPOP order3
        SPOP order 2
        SPOP order 1
Copy the code

2. Like, like, tag

Like, like, tag1(SADD like:1 1001 1002 1003 1004 1005
    2) Unlike: SREM like:1 1002
    3SISMEMBER like:1 1002
        SISMEMBER like:1 1005
    4SMEMBERS like:1
    5SCARD like:1
Copy the code

3. Focus on the model

redis> SADD wangwu zhangsan lisi zhaoliu haoba
    (integer) 4
redis> SADD zhangsan lisi wangwu sijiu
    (integer) 3
redis> SADD lisi zhaoliu zhangsan qinshi
    (integer) 3
redis> SINTER wangwu zhangsan
    1) "lisi"
redis> SISMEMBER zhangsan lisi
    (integer) 1
redis> SISMEMBER lisi zhangsan
    (integer) 1
redis> SISMEMBER zhaoliu zhangsan
    (integer) 0
redis> SISMEMBER haoba zhangsan
    (integer) 0
redis> SDIFF zhangsan wangwu
    1) "sijiu"
    2) "wangwu"
redis> SDIFF lisi wangwu
    1) "qinshi"
Copy the code

Summary of main points

(1) The encoding of collection objects can be intSet or Hashtable.

(2) IntSet encoded set object uses integer set as the underlying implementation.

(3) The collection object encoded by HashTable uses a dictionary as the underlying implementation.

(4) The encoding between intset and Hashtable can be converted if conditions are met.

over