day40-redis数据库主要语法-及与mysql结合用法示例

2018-12-31  本文已影响0人  barriers

redis数据库详细语法及说明见[http://redisdoc.com/]
下面仅对其常见的五种数据类型的语法进行介绍

1字符串

setex(如果键存在才能设置值)
setnx(如果键不存在才能设置值);
mset(一次设置多个键值对)
mget(一次获取多个键值对);
incr str1 将str1中存储的数字值增1
getset(拿到键之前的值并对其进行新的赋值)
gitbit(取指定位上的比特看是否为0)
setbit(设置或清除指定偏移量上的比特)
setbit ab 128 1设置ab键的第128位为1,其余为0
type 键:可以查看键的数据类型
object encoding 键 :查看底层的数据类型

2哈希表

哈希表:字典里面的值又是一个字典,最适合用来保存对象
hset stu1 stuid 1001
hset stu1 name xiaoming
hset stu1 gender male
hset stu1 birth 1999-12-31
hset stu1 addr chengdu
type stu1 # hash
object encoding stu1 # ziplist
hget stu1 gender # 取一个值
hgetall stu1 #取所有
hvals stu1 # 取所有的值
同时设置多个值
hmset stu2 stuid 1002 name wangdachui addr mianyang gender male
hmget stu2 name gender #同时获取stu2的两个值
hdel stu2 gender #删除stu2的性别(只删除字段)
hexists stu2 gender #判断存在否

hset stu1 fav 100
hset stu2 fav 95.23
hincrby stu1 fav 50 #给学生1增加点赞数50
hincrbyfloat stu2 fav 100.234 #给学生2的点赞数增加100.234
hkeys stu1 # 取stu1的所有键

3列表

列表中的数据结构分为栈和队列两种
经典数据存储结构:

3.1栈

栈(stack) - FILO - 先进后出 - lpush + lpop/rpush + rpop
lpush list1 100 200 300 400 500 600
从左边拿
lpop list1 #600
。。。
lpop list1 #100(先进后出)

3.2队列

队列(queue) - FIFO - 先进先出- lpush + rpop/rpush + lpop
lpush list1 100 200 300 400 500 600
从右边拿
rpop list1 # 100
...
rpop list1 # 600(后进后出)

3.3列表基本语法

lpush list1 100 200 300 400 500 #给列表在左边放了五个数据
lrange list1 0 -1 #查看列表下标为0到-1的数据(500 400 ...)
rpush list2 100 200 300 400 500 #给列表在右边放了五个数据
lrange list1 0 -1 #查看列表下标为0到-1的数据(100 200 ...)

lpop list1#从列表的左边取一个数据(500)
rpop list1 #从列表的右边取一个数据(100)
rpop list1 #从列表的右边取一个数据(200)

lpush list1 100 200 300 400
lindex list13 取出下标为3的元素(100)
llen list1 看列表的长度

lrange list2 0-1 查看list2的两个元素
brpop(阻塞式从右边取元素)
brpop list2 5 5秒内取list2中的元素,如果超过5秒没有取到东西就返回nil和等待时长

4集合

set
集合中不能放重复元素
sadd set1 100 200 100 #创建一个集合
smembers set2 #查看集合中的所有元素
sinter set1 set2 # 求交集
sdiff set1 set2 #求差集
sunion set1 set2 # 求并集
srem set1 100 #删除100这个元素
sismember set1 200 # 查看200是否在集合1中
scard set1 #查看集合中元素的个数
spop set1 #随机取set1中的一个元素并将其删除
srandmember set2 2 随机取随机个数的函数

5有序集合

zset
zadd paihangbang 100 laowang 550 xiaoming 200 sss 500 qqq #创建一个排行榜集合
zrange paihangbang 0 -1#将集合的下标0到-1的元素从小到大排序
zrevrange paihangbang 0 -1 同上,不过是从大到小排序

6读写分离配置:

主机配置:redis-server --requirepass 设置密码 >redis.log 2 > redis-error.log &
从机配置: redis-server --slaveof 主机ip 端口--masterauth 主机设置的密码 > redis.log 2>redis -error.log &
redis-cli (进入从机)
作为从机连接主机
slaveof no one #解除主从配置

history:查看历史命令
! 历史命令前的id(如! 997): 将这个命令在执行一遍

7在python中给mysql查询的文件分页

import pymysql
from pymysql.cursors import DictCursor

con = pymysql.connect(host='localhost', port=3306,
                      database='hrs', charset='utf8',
                      user='root', password='123456', autocommit=True)
class Emp():
    def __init__(self,no,name,job,sal):
        self.no=no
        self.name=name
        self.job=job
        self.sal=sal
    def __str__(self):
        return f'{self.no}-{self.name}-{self.job}-{self.sal}'
def main():
    page=int(input('页码:'))
    size=int(input('页面大小:'))
    try:
        with con.cursor() as cursor: 元祖形式
            cursor.execute('select * from tb_emp limit (%s,%s)',((page-1)*size,size)) #显示从第几页看起,一页显示多少行
            for result in cursor.fetchall():  #返回元祖
                emp=Emp(*result)
                print(emp)
        with con.cursor(DictCursor) as cursor: 字典形式
            cursor.execute('select * from tb_emp limit (%s,%s)', ((page - 1) * size, size))
            for result in cursor.fetchall():  #返回字典
                emp=Emp(**result)
                print(emp)

    finally:
        con.close()

8随机生成验证码并发送短信(用redis控制一个小时只能发送三次)

import io
import json
import time
import random
import requests
import redis

def gen_code(length=6):
    """生成指定长度的验证码"""
    result = io.StringIO()
    for _ in range(length):
        result.write(str(random.randint(0, 9)))
    return result.getvalue()

def send_messag_example(tel, code):
   """发送短信"""
    resp = requests.post(
        url='http://sms-api.luosimao.com/v1/send.json',
        auth=('api', 'e67b65751337d36224b26074ceb8a421'),
        data={
            'mobile': tel,
            'message': f'您的验证码为{code}。【铁壳测试】'
            # 'message': f'猜猜我是谁。【铁壳测试】'
        },
        timeout=3,
        verify=False
    )
    return json.loads(resp.content)

def my_main():
    tel = input('请输入手机号:')
    cli = redis.StrictRedis(host='112.74.61.160', port=6379,
                            password='1qaz2wsx')
    if not cli.exists(tel):
        result = send_messag_example(tel, gen_code())
        print(result)
        if result['error'] == 0:
            print('短信发送成功')
            cli.set(tel, 1, ex=3600)
    elif int(cli.get(tel)) < 3:
        result = send_messag_example(tel, gen_code())
        print(result)
        if result['error'] == 0:
            print('短信发送成功')
            cli.incr(tel)
    else:
        print('请不要频繁发送短信验证码(1小时只能发送3次)')

my_main()

9 python中使用redis

1.连接redis服务器
2.创建连接对象
cli=redis.StrictRedis(ip,端口,redis登陆密码)

def main():
    cli = redis.StrictRedis(host='112.74.61.160', port=6379,
                        password='1qaz2wsx')
    try:
        if cli.ping():
            print('连接成功')
            print(cli.keys('*'))
            print(cli.set('username', 'hellokitty'))
            print(cli.expire('username', 120))
            print(cli.get('username'))
            time.sleep(5)
            print(cli.ttl('username'))
            cli.sadd('set1', '100', '200', '100', '200', '500')
            print(cli.scard('set1'))

    except:
        print('连接出错')
    finally:  #可能有错
        cli.shutdown(save=True)

10redis和mysql结合提高程序效率示例

序列化 - 把对象转换成字符或字节序列 - 串行化/腌咸菜
反序列化 - 把字符或者字节序列还原成对象 - 反串行化
python中要实现对象的序列化和反序列化有三种方案:
-json - load/loads / dump/dumps - 字符序列
-pickle - load / loads /dump/dumps - 字节序列(使用较多)
提高效率原理:redis将数据存放在内存中,mysql存放在硬盘中,从运存中提取数据效率远远高于从硬盘中提取;
取数据时,先用redis去内存中查找是否存在数据,如若存在就直接提取,不存在,就利用mysql从数据库提取;
最后在利用redis将数据存入内存中,从而方便下次查找,提高效率;
可以将常用数据存入redis这样能大大提高效率;
例如选择每个省及其下的县市时,省为常用数据,故常将省存在内存中

import pickle
import time
import pymysql
import redis

class District:
""行政区域"""
    def __init__(self,distid,name):
        self.distid=distid
        self.name=name
    def __str__(self): #打印函数
        return self.name
    def __repr__(self): # 查看函数
        return self.name

def my_dis():
    # 记录程序执行起始时间
    begin=time.time()
    cli=redis.StrictRedis(host='120.77.222.217',
                          port=6379,password='1qaz2wsx')
    # 优先从缓存中读取数据,如果缓存没有所需数据,才连接数据库进行查询
    if cli.exists('provinces'):
        provinces=pickle.loads(cli.get('provinces'))
        # 直接从缓存中通过键获取数据并反序列化成Python中的对象
    else:
        provinces=[]
        con=pymysql.connect(host='localhost', port=3306,
                          database='hhrs', charset='utf8',
                          user='root', password='123456')
        try:
            with con.cursor() as cursor:
                # 从数据库中查询省级行政区域
                cursor.execute('select `distid`,`name` from `tb_district` where `pid` is null')
                # 将查询结果放入列表容器
                for dist_tuple in cursor.fetchall():
                    # 将元祖数据解包生成对象
                    dist=District(*dist_tuple)
                    # 将对象添到列表
                    provinces.append(dist)
                # 将列表序列化(pickle)然后放入redis中缓存
                cli.set('provinces',pickle.dumps(provinces))

        finally:
            con.close()
    # 记录程序执行结束时间
    end=time.time()
    print(f'执行时间:{end-begin}秒')
    print(provinces)
上一篇下一篇

猜你喜欢

热点阅读