Redis key design (reprint)

Reference: https://blog.csdn.net/iloveyin/article/details/7105181

Rich data structure makes redis design is very interesting. Unlike relational database that, DEV DBA needs and depth of communication, review each line of sql statement, unlike memcached as the DBA does not need to participate. redis the DBA needs to be familiar data structures, understand and use scenarios.

Here are some examples of common database for kv to talk about key design and make a comparison with the relational database and found deficiencies relational.

User login system

Record a user login system information, we simplify the business after leaving a table.

Relational Database Design

mysql> select * from login;
+---------+----------------+-------------+---------------------+
| user_id | name           | login_times | last_login_time     |
+---------+----------------+-------------+---------------------+
|       1 | ken thompson   |           5 | 2011-01-01 00:00:00 |
|       2 | dennis ritchie |           1 | 2011-02-01 00:00:00 |
|       3 | Joe Armstrong  |           2 | 2011-03-01 00:00:00 |
+---------+----------------+-------------+---------------------+

User_id primary key table, name represents the user name, login_times represents the number of times the user log in each time users log in, login_times will automatically increase, while last_login_time updated to the current time.

REDIS design

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

key table name: the primary key values: Column Name

value column values

Generally do a colon delimiter, it is an unwritten rule. For example, in php-admin for redis system, colon segmentation is the default, then user: 1 user: 2 and other key will be grouped. Thus the relationship between the above data is converted to data records kv follows:

Set login:1:login_times 5
Set login:2:login_times 1
Set login:3:login_times 2

Set login:1:last_login_time 2011-1-1
Set login:2:last_login_time 2011-2-1
Set login:3:last_login_time 2011-3-1

set login:1:name ”ken thompson“
set login:2:name “dennis ritchie”
set login:3:name ”Joe Armstrong“

In the case of such a known primary key, the get, set you can get or modify user logins and last login time and name.

The average user is not aware of their id, just know your user name, you must also have a mapping from name to the id, where the design is different and above.

set "login:ken thompson:id"      1
set "login:dennis ritchie:id"    2
set "login: Joe Armstrong:id"    3

So each time the user logs on the business logic is as follows (python version), r is redis objects, name is already known user name.

 

If the demand is only known id, update or obtain a user's last login time, login times, and relational database kv no difference what. By a btree pk, through a hash, results are good.

Consider the following requirements and look for N users recently logged in. Developers look, it is quite simple to get a sql.

1 select from login order by last_login_time desc limit N

After the DBA needs to understand, after taking into account if the table is relatively large, so build an index on last_login_time. It plans to begin implementation of access from the rightmost index leafblock of N records, return to the table N times, very good.

Two days later, came a demand, you need to know who the highest number of login. How to deal with the same type of relationship? That simple DEV

1 select from login order by login_times desc limit N

DBA look, but also to build an index on login_time. Do you feel a little problem then, the field has a prime table on each lead.

Inflexible data stored in relational databases is the source of the problem, only one data storage method that heap tables arranged in rows. Unified data structure means that you must use the index to change the access path to quickly access a sql column, and increase the access path in turn means that you have to use statistics to assist, so a lot of problems have emerged.

No index, no statistical plan, no implementation plan, which is kv database.

redis in how to meet these needs? For seeking the latest N pieces of data demands, after the last in a list of features it is very suitable. We added after login code above piece of code, maintain a list of login controls his length so that there is always saved it is the latest N log on the user.

1 #把当前登录人添加到链表里
2 ret = r.lpush("login:last_login_times", uid)
3 #保持链表只有N位
4 ret = redis.ltrim("login:last_login_times"0, N-1)

Such people need to get the latest login id, the following code can be

1 last_login_list = r.lrange("login:last_login_times"0, N-1)

In addition, the number of people seeking up to login, for sorting, standings this kind of demand, sorted set is very suitable, we users and unified logins are stored in a sorted set in.

zadd login:login_times 5 1
zadd login:login_times 1 2
zadd login:login_times 2 3

So if a user logs on, the additional maintain a sorted set, so the code

1 #对该用户的登录次数自增1
2 ret = r.zincrby("login:login_times"1, uid)

So how to get the most number of users log on it, in reverse order of the user to take the N-th ranking to

1 ret = r.zrevrange("login:login_times"0, N-1)

As can be seen, the DEV need to add two lines of code, and DBA need to consider what index.

TAG system

tag especially prevalent in Internet applications, if the traditional relational database design is a bit nondescript. We find an example of the book's look redis advantage in this regard.

Relational Database Design

Two tables, a book's details, a tag table, representing each of this tag, a book there are multiple tag.

mysql> select * from book;
+------+-------------------------------+----------------+
| id   | name                          | author         |
+------+-------------------------------+----------------+
|    1 | The Ruby Programming Language | Mark Pilgrim   |
|    1 | Ruby on rail                  | David Flanagan |
|    1 | Programming Erlang            | Joe Armstrong  |
+------+-------------------------------+----------------+

mysql> select * from tag;
+---------+---------+
| tagname | book_id |
+---------+---------+
| ruby    |       1 |
| ruby    |       2 |
| web     |       2 |
| erlang  |       3 |
+---------+---------+

If there is such a demand, but also a look that is ruby ​​web of books, if the relational database will be how to deal with?
1 select b.name, b.author  from tag t1, tag t2, book b
2 where t1.tagname = 'web' and t2.tagname = 'ruby' and t1.book_id = t2.book_id andb.id = t1.book_id

tag table twice since then associated with the associated book, the sql is quite complicated, if that is required ruby, but not the books web aspect of it?

In fact, relational data collection and is not suitable for these operations.

REDIS design

The first book to be sure the data is stored, the same as above.

set book:1:name    ”The Ruby Programming Language”
Set book:2:name     ”Ruby on rail”
Set book:3:name     ”Programming Erlang”

set book:1:author    ”Mark Pilgrim”
Set book:2:author     ”David Flanagan”
Set book:3:author     ”Joe Armstrong”

tag table we use the collection to store the data, because the collection is good at seeking common ground, and set

sadd tag:ruby 1
sadd tag:ruby 2
sadd tag:web 2
sadd tag:erlang 3

Well, that belongs to the ruby ​​and belongs web book?

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

That belongs to ruby, but the book does not belong to the web?

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

Belonging to the collection and ruby ​​belonging to the web book?

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

A simple to not work.

From the above two examples can be seen in some scenes, the relational database is not suitable, you may be able to design a system to meet the demand, but always feel strange, a kind of rote feeling.

In particular, this example login system, frequent indexing business. In a complex system, ddl (create index) it is possible to change the execution plan. Lead to other sql using different execution plans, business complex old system, this problem is very difficult to estimate in, sql strange. DBA requirements for this system are aware of all the sql, this is too difficult. This problem is particularly acute in the oracle, each DBA estimates have encountered. MySQL for such systems, ddl and inconvenient (although there are now online ddl method). Hit the big table, DBA get up in the morning peak period of low business operation, which is something I have not done less. And this demand into redis in very good treatment, DBA only the capacity can be estimated.

Future OLTP system should be closely integrated and relational kv

Guess you like

Origin www.cnblogs.com/testzcy/p/10960490.html