Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the common key-value designs for Redis databases?

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article will explain in detail what the common key-value designs of Redis databases are, and the editor thinks it is very practical, so I share it with you for reference. I hope you can get something after reading this article.

Users log in to the system

A system that records user login information. We simplify the business and leave only one table.

Design of Relational Database

Mysql > select*fromlogin

+-+

| | user_id | name | login_times | last_login_time | |

+-+

| | 1 | kenthompson | 5 | 2011-01-0100 purpur00 |

| | 2 | dennisritchie | 1 | 2011-02-0100 purpur00 |

| | 3 | JoeArmstrong | 2 | 2011-03-0100 purpur00 |

+-+

The primary key of the user_ id table, name represents the user name, and login_times indicates the number of logins of the user. Each time the user logs in, the login_times will increment itself, and the last_login_time will be updated to the current time.

The design of REDIS

To convert relational data into KV database, my method is as follows:

Key table name: primary key value: column name

Value column value

It is an unwritten rule to use colons as separators. For example, in the php-adminforredis system, the default is separated by a colon, so key such as user:1user:2 will be divided into a group. Therefore, the above relational data is converted into kv data and recorded as follows:

Setlogin:1:login_times5

Setlogin:2:login_times1

Setlogin:3:login_times2

Setlogin:1:last_login_time2011-1-1

Setlogin:2:last_login_time2011-2-1

Setlogin:3:last_login_time2011-3-1

Setlogin:1:name "kenthompson"

Setlogin:2:name "dennisritchie"

Setlogin:3:name "JoeArmstrong"

In this way, when the primary key is known, the user's login times and last login time and name can be obtained or modified through get and set.

The average user cannot know his id, only his user name, so there must be a mapping from name to id. The design here is different from the one above.

Set "login:kenthompson:id" 1

Set "login:dennisritchie:id" 2

Set "login:JoeArmstrong:id" 3

So each time the user logs in, the business logic is as follows (python version), r is the redis object, and name is the user name that has been known.

# get the user's id

Uid=r.get ("login:%s:id" name)

# self-increasing the number of logins of users

Ret=r.incr ("login:%s:login_times" uid)

# update the user's last login time

Ret=r.set ("login:%s:last_login_time"% uid,datetime.datetime.now ())

If the requirement is only a known id, there is no difference between updating or getting a user's last login time, number of logins, and relational and kv databases. One through btreepk, the other through hash, the effect is very good.

Suppose you have the following requirements to find the N users who logged in recently. Developers take a look, it is relatively simple, a sql to do.

Select*fromloginorderbylast_login_timedesclimitN

After DBA understands the requirements, considering that the table is larger in the future, it builds an index on last_login_time. The execution plan accesses N records from the far right of the index leafblock and returns to the table N times, with good results.

What are the design of common Redis database key values

After two days, there is another need to know who logs in the most times. How to deal with the same relationship? DEV said simply

Select*fromloginorderbylogin_timesdesclimitN

As soon as DBA takes a look, he wants to build an index on login_time. Do you think there is a problem? there is a prime citation on every field on the table.

The inflexibility of data storage in relational databases is the source of the problem, and there is only one way to store data, that is, stacking tables arranged by rows. A uniform data structure means that you have to use indexes to change the access path of sql to quickly access a column, and the increase in access paths means that you have to use statistics to assist, so a lot of problems arise.

No index, no statistical plan, no execution plan, this is the kv database.

How can the above needs be met in redis? For the demand for the latest N pieces of data, the back-in and back-out characteristics of the linked list are very suitable. We add a piece of code after the login code above to maintain a linked list of logins and control its length so that the nearest N login users are saved forever.

# add the current login to the linked list

Ret=r.lpush ("login:last_login_times", uid)

# keep the linked list with only N bits

Ret=redis.ltrim ("login:last_login_times", 0meme Nmuri 1)

To do this, you need to get the id of the latest login, as shown in the following code

Last_login_list=r.lrange ("login:last_login_times", 0meme Nmuri 1)

In addition, for those who seek the most logins, sortedset is very suitable for requirements such as sorting and scoreboards. We store users and logins in the same sortedset.

Zaddlogin:login_times51

Zaddlogin:login_times12

Zaddlogin:login_times23

So if a user logs in and maintains an extra sortedset, the code is like this

# the number of logins for this user has increased by 1

Ret=r.zincrby ("login:login_times", 1m uid)

So how to get the users with the largest number of logins? the users who rank N in reverse order can do so.

Ret=r.zrevrange ("login:login_times", 0meme Nmuri 1)

As you can see, DEV needs to add two lines of code, and DBA doesn't need to think about indexes.

TAG system

Tag is especially common in Internet applications, and it is a bit irrelevant to use traditional relational databases to design. Let's take a look at the advantages of redis in this respect with the example of finding books.

Design of Relational Database

Two tables, one book details, one tag table, indicates the tag of each book, and there are multiple tag in a book.

Mysql > select*frombook

+-+

| | id | name | author | |

+-+

| | 1 | TheRubyProgrammingLanguage | MarkPilgrim |

| | 1 | Rubyonrail | DavidFlanagan |

| | 1 | ProgrammingErlang | JoeArmstrong |

+-+

Mysql > select*fromtag

+-+ +

| | tagname | book_id |

+-+ +

| | ruby | 1 | |

| | ruby | 2 | |

| | web | 2 | |

| | erlang | 3 | |

+-+ +

If there is such a need, looking up books on both ruby and web, what if you use a relational database?

Selectb.name,b.authorfromtagt1,tagt2,bookb

Wheret1.tagname='web'andt2.tagname='ruby'andt1.book_id=t2.book_idandb.id=t1.book_id

The tag table has been associated twice and then associated with book, and this sql is still quite complicated. What if the requirement is ruby, but not a book on web?

Relational data is not really suitable for these collection operations.

The design of REDIS

First of all, the data of book must be stored, as above.

Setbook:1:name "TheRubyProgrammingLanguage"

Setbook:2:name "Rubyonrail"

Setbook:3:name "ProgrammingErlang"

Setbook:1:author "MarkPilgrim"

Setbook:2:author "DavidFlanagan"

Setbook:3:author "JoeArmstrong"

Tag table We use sets to store data, because sets are good at finding intersection and union.

Saddtag:ruby1

Saddtag:ruby2

Saddtag:web2

Saddtag:erlang3

So, a book that belongs to both ruby and web?

Inter_list=redis.sinter ("tag.web", "tag:ruby")

That is, books that belong to ruby but not to web?

Inter_list=redis.sdiff ("tag.ruby", "tag:web")

A collection of books belonging to ruby and web?

Inter_list=redis.sunion ("tag.ruby", "tag:web")

It's too simple.

From the above two examples, we can see that in some scenarios, relational database is not very suitable, you may be able to design a system to meet the needs, but it always feels strange and mechanically applied.

Especially in the case of logging in to the system, the business is indexed frequently. In a complex system, ddl (creating an index) may change the execution plan. It is difficult to predict the problem that causes other sql to adopt different implementation plans and complex old systems. Sql is strange in all its ways. It is too difficult to require DBA to know all the sql in this system. This problem is particularly serious in oracle, and every DBA probably has encountered it. For systems like MySQL, ddl is also inconvenient (although there is an onlineddl method). When I came across a big watch, DBA got up in the early morning to operate during the business trough, which I have done a lot. This requirement can be easily handled in redis, and DBA can only estimate the capacity.

This is the end of this article on "what are the common key-value designs in Redis databases?". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report