受邀请回答。
我不知道社区是如何做缓存的,但是可以分享一下我用SQLAlchemy和Redis做缓存的做法。
假设有这样的数据库表,简单的博客文章,文章Tag表,按照标准范式表设计,在SQLAlchemy(类似Django的Models范式)设计如下:
- class Blog(Models): __tablename__ = "blog" id = Column(Integer, primary_key=True) blog_text = Text()class BlogTagRel(Models): __tablename__ = "blogtagrel" # id = Column(Integer, primary_key=True) blog_id = Column(Integer) tag_id = Column(Integer)class Tag(Models): __tablename__ = "tag" id = Column(Integer, primary_key=True) tag_text = Text()
复制代码
这个基本是最基本的一对多的范例,那么规划自己的Redis缓存使用的数据类型,规划如下(类似C的伪代码,将就看看,大体理解,轻拍):
Redis缓存的Key大体按照 Table-Name: Primary-Key: Column-Key = Column-Value 这样设计。
- blog:(id): text = [string] textblog:(id):tags = [hashs] [string] tag1 [string] tag2 .......
复制代码
上面是Models的设计和缓存设计,现在设计Backend类,关键的将两者整合起来的后端实现,ORM+缓存。
- class Backend(): # 伪代码,轻拍 # CURD的Create def create_blog(self, blog_text): # 写入数据库 blog = Blog(blog_text=blog_text) sqlalchemy_session.add(blog) sqlalchemy_session.commit() # 写入缓存 redis_conn.set("blog:" + blog.id + ":text", blog_text) # CURD的Read def read_blog(self, id): # 检查缓存是否存在 if redis_conn.exists("blog:" + blog.id + ":text"): return redis_conn.get("blog:" + blog.id + ":text") else: blog = sqlalchemy_session.query(Blog).filter_by(id=id).first() # 写入缓存 redis_conn.set("blog:" + blog.id + ":text", blog.blog_text) return blog
复制代码
使用的时候,直接就是Backend.create_blog()和Backend.read_blog(),这样就可以整合SQLAlchemy和Redis的缓存。
上面的代码还有些问题,比如SQLAlchemy返回的数据是需要和Redis返回的缓存数据是一致的,这样方便外部的逻辑实现调用吧。但是上面的思路就是这样的,ORM + Cache = Backend,外部统一调用Backend的逻辑。ORM你可以写成Raw SQL,Cache可以换任何的Memcached等的缓存,但实现思路是一样的。
很简洁是不是?哈哈。
希望对你有用。
希望社区分享一下Redis的缓存经验,或者是缓存的架构:) |