NoSQL database (2) 03-Redis data type - introduction to list types, commands - add elements to both ends of the list, pop elements from both ends of the list, get the number of elements in the list, delete the specified value in the list

NoSQL database (2) 03-Redis data type - introduction to list types, commands - add elements to both ends of the list, pop elements from both ends of the list, get the number of elements in the list, delete the specified value in the list

list type

introduce

The list type can store an ordered list of strings, and common operations are to add elements to both ends of the list, or to obtain a fragment of the list.

The list type is internally implemented using a double linked list, so the time complexity of adding elements to both ends of the list is O(1), and the closer to the two ends, the faster the speed of obtaining elements. This means that even for a list with tens of millions of elements, getting the head or tail 10 records is extremely fast (and getting the head or tail 10 records from a list with only 20 elements is as fast as the same). However, the cost of using a linked list is that accessing elements through an index is slower.

What is the difference between array and js?

  • Arrays in js are actually objects, dictionaries
  • The list of redis is a linked list

Order

  1. Add elements to both ends of the list

LPUSH key value [value …]

RPUSH key value [value …]

redis> LPUSH numbers 1 
(integer) 1
  1. Pop elements from both ends of the list

LPOP key

RPOP key

  1. Get the number of elements in the list

LLEN key

  1. get list fragment

LRANGE key start stop

LRANGE 0 -1 can get all the elements in the list

  1. deletes the specified value in the list

LREM key count value

The LREM command will delete the first count elements whose value is value in the list, and the return value is the number of elements actually deleted. Depending on the count value, the execution method of the LREM command will be slightly different.

(1) When count > 0, the LREM command will delete the first count elements whose value is value from the left of the list.

(2) When count < 0, the LREM command will delete the first |count| elements whose value is value from the right of the list.

(3) When count = 0, the LREM command will delete all elements whose value is value. For example:

ex: Store the list of article ids

New requirements: The articles we store need to display many articles, how to do paging function.

To solve this, we use the list type key posts:list to record the list of post IDs. When publishing a new article, use the LPUSH command to add the ID of the new article to this list. In addition, when deleting an article, remember to delete the article ID in the list, like this: LREM posts:list 1 The article ID to be deleted

With the list of article IDs, you can use the LRANGE command to realize the paging display of articles. The pseudocode is as follows:

var redis = require('redis');
var client = new redis({
    
    
    // 配置
});

var currentPage = 1;

var listLength = 10;
var start = (currentPage - 1) * listLength;
var end = currentPage * listLength - 1;
var postIdArr = client.lrange(`post:list ${
      
      start} ${
      
      end}`);

postIdArr.forEach(id => {
    
    
    client.hgetall(`post:${
      
      id}`, (data) => {
    
    
        console.log(data)
    });
});

The fly in the ointment is that the hash type does not have a version similar to the MGET command of the string type that can obtain the key-value versions of multiple keys at the same time through one command, so for each article ID, it is necessary to request the database once, which will generate a round-trip time Delay (round-trip delay time) [11], and then we will introduce the use of pipelines and scripts to optimize this problem.

In addition, using the list type key to store the list of article IDs has the following two problems.

(1) It is not easy to modify the publishing time of the article: to modify the publishing time of the article not only needs to modify the time field in the post: article ID, but also needs to rearrange the order of the elements in the posts:list according to the actual publishing time, and this operation is relatively cumbersome.

(2) When the number of articles is large, the performance of accessing the middle page is poor: as mentioned above, the list type is implemented through a linked list, so when there are many list elements, accessing the middle elements is not efficient.

ex: store comment list

Comments on articles can also be stored in a blog using a list type key. Because the blog does not allow visitors to modify their own comments, and considering that all the data of the comments (the name of the commenter, contact information, comment time and comment content) need to be obtained when reading the comments, unlike articles, sometimes only the title of the article is required. Article body is required. Therefore, it is suitable to serialize each element of a comment into a string and store it as an element in a list type key.

var commentsStr = JSON.stringify({
    
    
    author: 'xxx',
    time: 'xxx',
    content: 'xxx',
})

client.lpush('post:id:comment', commentsStr);

command supplement

  1. Get/set the element value at the specified index

    LINDEX key index

    LSET key index value

  2. Only keep the specified fragment of the list

    LTRIMThe command can delete all elements outside the specified index range, and the method of specifying the list range is the same as the LRANGE command. like this:

    redis> LRANGE numbers 0 -1 
    1) "1" 
    2) "2" 
    3) "7" 
    4) "3" 
    redis> LTRIM numbers 1 2 
    OK 
    redis> LRANGE numbers 0 1 
    1) "2"
    2) "7"
    

    The LTRIM command is often used together with the LPUSH command to limit the number of elements in the list. For example, when recording logs, we want to keep only the latest 100 logs. Then call the LTRIM command once each time a new element is added:

    LPUSH logs $newLog 
    LTRIM logs 0 99
    
  3. insert an element into the list

    LINSERT key BEFORE|AFTER pivot value

    The LINSERT command first searches the list for the element whose value is pivot from left to right, and then decides whether to insert the value before or after the element according to whether the second parameter is BEFORE or AFTER.

    The return value of the LINSERT command is the number of elements in the list after insertion. Examples are as follows:

    redis> LRANGE numbers 0 -1 
    1) "2" 
    2) "7"
    3) "0" 
    redis> LINSERT numbers AFTER 7 3 
    (integer) 4 
    redis> LRANGE numbers 0 -1 
    1) "2" 
    2) "7" 
    3) "3" 
    4) "0" 
    redis> LINSERT numbers BEFORE 2 1 
    (integer) 5 
    redis> LRANGE numbers 0 -1 
    1) "1" 
    2) "2" 
    3) "7" 
    4) "3" 
    5) "0"
    
  4. Move elements from one list to another

    RPOPLPUSH source destination

    RPOPLPUSH is a very interesting command, its function can be seen from the name: first execute the RPOP command and then execute the LPUSH command. The RPOPLPUSH command will first pop up an element from the right of the key of the source list type, then add it to the left of the key of the destination list type, and return the value of this element. The whole process is atomic.

    When using a list type as a queue, the RPOPLPUSH command can intuitively pass data across multiple queues. When the source and destination are the same, the RPOPLPUSH command will continuously move the elements at the end of the queue to the head of the queue. With this feature, we can implement a website monitoring system: use a queue to store the URLs that need to be monitored, and then the monitoring program will continuously use the RPOPLPUSH command Loop through a URL to test availability. The advantage of using the RPOPLPUSH command here is that new URLs can still be continuously added to the URL list during program execution, and the whole system is easy to expand, allowing multiple clients to process queues at the same time.

example

list_demo.js

var redis = require('redis');
var client = new redis({
    
    
    // 配置
});

// post:list已经有值  通过lpush

var currentPage = 1;  // 当前页面为1
var listLength = 10;

var start = (currentPage - 1) * listLength;
var end = currentPage * listLength - 1; // 0-9

var postIdArrHash = client.lrange(`post:list ${
      
      start} ${
      
      end}`);  // postIdArr此时还是一个列表 里面 存储的 散列

postIdArrHash.forEach((id) => {
    
    
    client.hgetall(`post:${
      
      id}`, (data) => {
    
    
        console.log(data);
    })
});

// 评论只需要用字符串存储 
var commentStr = JSON.stringify({
    
    
    author: 'xxx',
    time: 'xxx',
    content: 'xxx',
});

// 评论要存到列表中,因为一篇文章会有多个评论
client.lpush(`post:${
      
      id}:comments ${
      
      commentStr}`);

Guess you like

Origin blog.csdn.net/weixin_44867717/article/details/131650902
Recommended