和MySQL数据库关系表的设计不同 <这篇文章是网上已有的加以总结>
用户登录系统
记录用户登录信息表
- MySQL
1mysql>select* from login;2+---------+----------------+-------------+---------------------+3| user_id | name | login_times | last_login_time |4+---------+----------------+-------------+---------------------+5| 1 | fk | 5 | 2013-09-26 00:00:00 |6| 2 | zhangsan | 1 | 2013-09-25 00:00:00 |7| 3 | zhaokuangyin | 2 | 2013-09-01 00:00:00 |8+---------+----------------+-------------+---------------------
其中:user_id->主键(可自增), login_times->每次登录自增, last_login_time->当前时间
- Redis
key <表名:主键名:列名> # 一般用冒号作为分隔符
value <列值>
这样, 知道主键 user_id后就可以get到所有内容了, ***但是一般是通过name访问, 所以需要name到主键的映射.01SET login:1:login_times 502SET login:2:login_times 103SET login:3:login_times 20405SET login:1:last_login_time 2013-09-2606SET login:2:last_login_time 2013-09-2507SET login:3:last_login_time 2013-09-010809SET login:1:name"fk"10SET login:2:name"zhangsan"11SET login:3:name"zhaokuangyin"
这样, 知道name就可以get到所有内容了.1SET"login:fk:id"12SET"login:zhangsan:id"23SET"login:zhaokuangyin:id"3
(1)用户登录操作如下:(2)查看最近登陆的10个用户01# -*- coding: utf-8 -*-0203fromredisimportclient04importtime0506r=client.Redis()# 默认07# r = client.Redis(self, host='localhost', port=6379, db=0, password=None, socket_timeout=None, connection_pool=None, charset='utf-8', errors='strict', decode_responses=False, unix_socket_path=None)08# r = client.StrictRedis.from_url("redis://127.0.0.1:6381")0910name="fk"1112# 根据name获取user_id13uid=r.get("login:%s:id"%name)14# 自增用户登录次数15ret=r.incr("login:%s:login_times"%uid)16# 更新最后登录时间17ret |=r.set("login:%s:last_login_time"%uid, time.strftime("%Y-%m-%d %H:%M:%S"))
①MySQL
如果当表很大时, 可以在last_login_time上建个索引, 当需要查看登录次数最多的用户, 又要在login_tines上建索引...关系数据库不灵活性出现.1select*fromloginorderbylast_login_timedesclimit 10
②Redis
***使用sorted set类型更适合01"""查看最近登录用户(显示最近xx条评论用这个比较合适)02"""03N=1004# 把当前登录人添加到链表里(登录时就要操作)05ret=r.lpush("login:last_login_times", uid)06# 保持链表只有N位07ret |=r.ltrim("login:last_login_times",0, N-1)# ltrim (l表示list, trim 一个list,从索引 0到N-1)0809# 获得最新登录人的id10last_login_list=r.lrange("login:last_login_times",0, N-1)01"""获取登录次数最多用户02使用sorted set类型更适合03"""04# 把用户和登录次数统一存储在一个sorted set里05# ZADD key 权值 member,python中zadd(key, score, member)06r.zadd("login:login_times",1,5)07r.zadd("login:login_times",2,1)08r.zadd("login:login_times",3,2)09# 某个用户登录,需要额外维护一个sorted set10# 对该用户的登录次数自增111# ret = r.zincrby("login:login_times", 1, uid) <-- 错误, 修正如下12ret=r.zincrby("login:login_times", uid,1)# ***和redis官网命令的参数顺序是不一样的, zincrby(key, value, Δscore)13# 获取登录次数最多的用户, 逆序排列取的排名第N的用户即可14login_times_list=r.zrevrange("login:login_times",0, N-1)
- ing
Tag系统
tag信息 存储设计
- MySQL
两张表,一张book的明细,一张tag表,表示每本的tag,一本书存在多个tag。假如要查找即是web又是ruby的书籍, 关系型sql语句是:01mysql>select* from book;02+------+-------------------------------+----------------+03|id| name | author |04+------+-------------------------------+----------------+05| 1 | The Ruby Programming Language | Mark Pilgrim |06| 1 | Ruby on rail | David Flanagan |07| 1 | Programming Erlang | Joe Armstrong |08+------+-------------------------------+----------------+0910mysql>select* from tag;11+---------+---------+12| tagname | book_id |13+---------+---------+14| ruby | 1 |15| ruby | 2 |16| web | 2 |17| erlang | 3 |18+---------+---------+
关系型数据库不太适合集合操作1selectb.name, b.authorfromtagast1, tagast2, bookasbwheret1.tagname ='web'andt2.tagname ='ruby'andt1.book_id = t2.book_idandb.id = t1.book_id
- Redis
book表用普通kv存储tag表用集合存储(因为要进行集合操作)1SET book:1:name"The Ruby Programming Language"2SET book:2:name"Ruby on rail"3SET book:3:name"Programming Erlang"45SET book:1:author"Mark Pilgrim"6SET book:2:author"David Flanagan"7SET book:3:author"Joe Armstrong"相关操作(与,或,差 对应python set的&, |, - )1SADD tag:ruby 12SADD tag:ruby 23SADD tag:web 24SADD tag:erlang 31# 既属于ruby,又属于web的书2ruby_and_web_list=r.sinter("tag:ruby","tag:web")3# 属于ruby,但不属于web的书4ruby_not_web_list=r.sdiff("tag:ruby","tag:web")5# 属于ruby, 或属于web的书6ruby_or_web_list=r.sunion("tag:ruby","tag:web")
转贴:http://my.oschina.net/1123581321/blog/164288

928

被折叠的 条评论
为什么被折叠?



