Redis基础教程

写在前面,感谢狂神,下面所有的都是来自狂神说Java - B站UP主

redis学习

Redis 是一个开源的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件MQ。它支持字符串、散列、列表、集合、有序集合与范围查询,bitmaps、hyperloglogs和地理空间(geospatial)索引半径查询。Redis内置了复制(replication),LUA脚本,lURU驱动时间,事物和不通级别的磁盘持久化,并通过Redis哨兵和自动分区提供高可用性。

基本命令

# 连接命令
 redis-cli -p 6379  
# 看是否连接成功
127.0.0.1:6379> ping 
PONG
# 清空数据库
127.0.0.1:6379> flushall
OK
# 设置keys
127.0.0.1:6379> set name shd
OK
# 查看当前有哪些key
127.0.0.1:6379> keys *
1) "name"

# 查看key是否存在 1是存在 0 是不存在
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> EXISTS age
(integer) 0

# 设置key的过期时间  expire key sec
127.0.0.1:6379> expire name 10
(integer) 1
# 查看当前key的过期时间 ttl
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> ttl name
(integer) -2
# 根据key 获取value
127.0.0.1:6379> get name
(nil)

# 查看key的类型
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> type name
string
#

五大数据类型

String

127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> append key1 hello  # 追加, 如果不存在则新增一个  set key value
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> strlen key1 # 获取key的长度
(integer) 7
=================================================================
# 自增和自减  incr 自增  decr 自减
127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> incr age
(integer) 2
127.0.0.1:6379> incr age
(integer) 3
127.0.0.1:6379> decr age
(integer) 2
127.0.0.1:6379> decr age
(integer) 1
127.0.0.1:6379> decr age
(integer) 0
127.0.0.1:6379> decr age
(integer) -1
127.0.0.1:6379> decr age
(integer) -2
127.0.0.1:6379> decr age
(integer) -3

# 步长式增加或减少 incrby step    decrby step
127.0.0.1:6379> INCRBY age 100
(integer) 97
127.0.0.1:6379> incrby age 100
(integer) 197
127.0.0.1:6379> decrby age 50
(integer) 147
127.0.0.1:6379> decrby age 50
(integer) 97
=====================================================
# 截取
127.0.0.1:6379> set name shd  # 设置name的值
OK
127.0.0.1:6379> get name   # 获取key
"shd"
127.0.0.1:6379> getrange name 1 2  # 截取1到2,闭区间
"hd"
127.0.0.1:6379> getrange name 1 1
"h"
127.0.0.1:6379> getrange name 0 -1 # 获取所有的
"shd"

#######################################
# 按下标 截取字符串
127.0.0.1:6379> set key1 abcdefgh
OK
127.0.0.1:6379> get key1
"abcdefgh"
127.0.0.1:6379> setrange key1 1 xxx  # 从下标1更改为xxx
(integer) 8
127.0.0.1:6379> get key1
"axxxefgh"
127.0.0.1:6379>

################################################
# setex 设置过期时间
127.0.0.1:6379> setex name 30 ddd
OK
127.0.0.1:6379> get name
"ddd"
127.0.0.1:6379> ttl name
(integer) 23

# setnx 不存在在设置 -- 分布式锁中会用到
127.0.0.1:6379> set name shd  # 首先设置name 为shd
OK
127.0.0.1:6379> setnx name myj # 通过setnx 设置name 为myj
(integer) 0   # 设置失败
127.0.0.1:6379> setnx bb myj  # 设置bb 为myj
(integer) 1     #设置成功
127.0.0.1:6379> get bb
"myj"

################################################
# 批量设置  mset 批量
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"

# 批量获取
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

# setnx 批量设置为原子操作
127.0.0.1:6379> msetnx k1 v1 k4 v4 # 因为k1存在了,所有k4设置失败了
(integer) 0

#######################################################
# 存入对象
127.0.0.1:6379> set user:1 "{name:zhangsan, age:10}"
OK
127.0.0.1:6379> get user:1
"{name:zhangsan, age:10}"

# 批量存放对象 , 设计的key为关键
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 10
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "10"
#######################################################
# 先get在set     
127.0.0.1:6379> keys * # 目前没有一个key
(empty array)
127.0.0.1:6379> getset name shd # 先获取name在设置name为shd
(nil)  # 因为不存在,所以为nil
127.0.0.1:6379> getset name myj # 在来一次,设置name为myj
"shd"  # 获取到了之前设置的shd


String 类型使用场景:value 除了是字符串,还可以是数字

  • 计数器 incr
  • 统计多单位的数量
  • 粉丝数 uid:988123:follow 0
  • 对象缓存存储

List

基本数据类型,列表

所有的list命令都是l开头的

##########################################
127.0.0.1:6379> lpush l one   # 将一个元素放入头部
(integer) 1
127.0.0.1:6379> lpush l two
(integer) 2
127.0.0.1:6379> lpush l three
(integer) 3
127.0.0.1:6379> lrange l 1 -1  # 获取第2个到最后一个元素
1) "two"
2) "one"
127.0.0.1:6379> lrange l 0 -1 # 获取第1个到最后一个元素
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> rpush l four # 将一个元素放入尾部
(integer) 4
127.0.0.1:6379> lrange l 0 -1 # 通过区间获取列表的值
1) "three"
2) "two"
3) "one"
4) "four"
##########################################
# 移除元素
127.0.0.1:6379> lrange l 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
127.0.0.1:6379> lpop l # 移除第一个元素
"three"
127.0.0.1:6379> rpop l # 移除最后一个元素
"four"
##########################################
# 根据下标获取元素
127.0.0.1:6379> lrange l 0 -1
1) "foure"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lindex l 0 # 获取第0位元素
"foure"
## 返回列表的长度
127.0.0.1:6379> llen l 
(integer) 4
##########################################
# 移除指定的值
127.0.0.1:6379> lrange l 0 -1
1) "three"
2) "three"
3) "three"
4) "five"
5) "foure"
6) "two"
7) "one"
127.0.0.1:6379> lrem l  2 three # 移除指定数量的具体元素 
(integer) 2
127.0.0.1:6379> lrange l 0 -1
1) "three"
2) "five"
3) "foure"
4) "two"
5) "one"

##########################################
# 截断
127.0.0.1:6379> lrange l 0 -1
1) "python"
2) "vue"
3) "world"
4) "hello"
127.0.0.1:6379> ltrim l 1 2  # 通过下标截取1到2的元素
OK
127.0.0.1:6379> lrange l 0 -1
1) "vue"
2) "world"
##########################################
# rpoplpush  移除最后一个元素到另一个元素
127.0.0.1:6379> lrange l1 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> RPOPLPUSH l1 l2 # 把l1最后一个元素移动到l2中
"a"
127.0.0.1:6379> lrange l1 0 -1
1) "c"
2) "b"
127.0.0.1:6379> lrange l2 0 -1
1) "a"
########################################
# exists 查看列表是否存在 
#  lset 把已存在的元素通过下标更新为另一个元素
127.0.0.1:6379> exists l
(integer) 0
127.0.0.1:6379> lset l 0 name #如果不存在,则报错
(error) ERR no such key
127.0.0.1:6379> lpush l age
(integer) 1
127.0.0.1:6379> lset l 0 name
OK
127.0.0.1:6379> lindex l 0
"name"

########################################
# 插入值
127.0.0.1:6379> lindex l 0
"name"
127.0.0.1:6379> LINSERT l before name your # name前面插入一个值
(integer) 2
127.0.0.1:6379> lrange l 0 -1
1) "your"
2) "name"
127.0.0.1:6379> linsert l after name is # name后面插入一个值
(integer) 3
127.0.0.1:6379> lrange l 0 -1
1) "name"
2) "your"
3) "name"
4) "is"
127.0.0.1:6379> linsert l before name my # 如果有两个相同的元素,在name前插入,会优先插入下标最小的那个
(integer) 5
127.0.0.1:6379> lrange l 0 -1
1) "my"
2) "name"
3) "your"
4) "name"
5) "is"

  • 它实际上是一个链表,before node after, left,right都可以插值

  • 如果key不存在,创建新的链表

  • 如果key存在,新增内容

  • 如果移除了所有值,空链表,也代表不存在

  • 在两边插入或改动值,效率最高,中间元素,相对来说效率较低

  • 消息排队,消息队列 lpush rpop, 栈 lpush lpop

    Set(集合)

    set中的值是不可以重复的

    #########################################
    127.0.0.1:6379> sadd s name # 新增元素
    (integer) 1
    127.0.0.1:6379> sadd s age
    (integer) 1
    127.0.0.1:6379> smembers s # 获取所有成员
    1) "age"
    2) "name"
    127.0.0.1:6379> sismember s age # 判断元素是否存在
    (integer) 1
    127.0.0.1:6379> sismember s sex
    (integer) 0
    
    #########################################
    127.0.0.1:6379> scard s  # 获取元素个数
    (integer) 2
    
    127.0.0.1:6379> srem s age # 移除指定的元素
    (integer) 1
    127.0.0.1:6379> srem s sex
    (integer) 0
    127.0.0.1:6379> smembers s
    1) "name"
    
    127.0.0.1:6379> smembers s # 获取所有的元素
    1) "age"
    2) "name"
    3) "address"
    4) "sex"
    127.0.0.1:6379> spop s # 随机移除一个元素
    "address"
    127.0.0.1:6379> smembers s
    1) "age"
    2) "name"
    3) "sex"
    #########################################
    127.0.0.1:6379> SRANDMEMBER s 1  # 随机抽选随机个数的元素 srandmember
    1) "sex"
    127.0.0.1:6379> SRANDMEMBER s 1
    1) "name"
    127.0.0.1:6379> SRANDMEMBER s 1
    1) "age"
    127.0.0.1:6379> SRANDMEMBER s 1
    1) "age"
    
    #########################################
    127.0.0.1:6379> sadd s one
    (integer) 1
    127.0.0.1:6379> sadd s two
    (integer) 1
    127.0.0.1:6379> sadd s three
    (integer) 1
    127.0.0.1:6379> sadd s1 aaa
    (integer) 1
    127.0.0.1:6379> smove s s1 one  # 把s中的one 移到s1中
    (integer) 1
    127.0.0.1:6379> smembers s
    1) "two"
    2) "three"
    127.0.0.1:6379> smembers s1
    1) "one"
    2) "aaa"
    
    
    #########################################
     127.0.0.1:6379> sadd s c
    (integer) 1
    127.0.0.1:6379> sadd e c
    (integer) 1
    127.0.0.1:6379> sadd e d
    (integer) 1
    127.0.0.1:6379> sadd e f
    (integer) 1
    127.0.0.1:6379> sdiff s e  # 差集
    1) "a"
    2) "b"
    127.0.0.1:6379> sinter s e # 交集 共同好友
    1) "c"
    127.0.0.1:6379> sunion s e # 并集
    1) "a"
    2) "c"
    3) "f"
    4) "b"
    5) "d"
    
    

    微博,a用户将所有关注的人放一个set集合,将他的粉丝也放到一个集合中!

    Hash

    Map集合

    ####################################################################################
    # 注意hmset 批量设置多个key value 在redis4.0 被废弃
    127.0.0.1:6379> hset my age 10 name shd sex man # 设置多个key 和value
    (integer) 3
    127.0.0.1:6379> hget my age  # 根据指定key 获取 value
    "10"
    127.0.0.1:6379> hmget my age name sex # 根据多个filed 获取value
    1) "10"
    2) "shd"
    3) "man"
    127.0.0.1:6379> hgetall my # 根据key获取所有的 filed 和value
    1) "age"
    2) "10"
    3) "name"
    4) "shd"
    5) "sex"
    6) "man"
    ####################################################################################
    127.0.0.1:6379> hdel my name # 删除指定的field
    (integer) 1
    127.0.0.1:6379> hgetall my
    1) "age"
    2) "10"
    3) "sex"
    4) "man"
    
    
    ####################################################################################
    127.0.0.1:6379> hlen my # 获取hash的长度
    (integer) 2
    
    ####################################################################################
    127.0.0.1:6379> hgetall my
    1) "age"
    2) "10"
    3) "sex"
    4) "man"
    127.0.0.1:6379> hexists my name  # 判断 field 是否存在
    (integer) 0
    127.0.0.1:6379> hexists my age
    (integer) 1
    
    ####################################################################################
    127.0.0.1:6379> hkeys my # 获取所有的fields
    1) "age"
    2) "sex"
    127.0.0.1:6379> hvals my # 获取所有的values
    1) "10"
    2) "man"
    
    ####################################################################################
    127.0.0.1:6379> HINCRBY my age -1 # 指定增量
    (integer) 9
    127.0.0.1:6379> HINCRBY my age -1
    (integer) 8
    127.0.0.1:6379> HINCRBY my age -1
    (integer) 7
    127.0.0.1:6379> HINCRBY my age -1
    (integer) 6
    
    127.0.0.1:6379> hset my age 10
    (integer) 1
    127.0.0.1:6379> hsetnx my age 100
    (integer) 0
    127.0.0.1:6379> hsetnx my name shd # 不存在就创建
    (integer) 1
    

    hash变更的数据user name ,age,尤其是用户信息类的,经常变动的信息!hash更适合与对象的存储,string更适合自字符串的存储

    Zset

    在set的基础上,增加了一个值,set k1 v1 zset v1 score v1

    
    ####################################
    127.0.0.1:6379> zadd myset 1 one  # 添加一个元素
    (integer) 1
    127.0.0.1:6379> zadd myset 1 one 2 two 3 three 4 four # 添加多个元素 
    (integer) 3
    127.0.0.1:6379> zrange myset 0 -1
    1) "one"
    2) "two"
    3) "three"
    4) "four"
    
    ####################################
    # 排序
    127.0.0.1:6379> zadd user 1000 zhangsan
    (integer) 1
    127.0.0.1:6379> zadd user 800 wangwu
    (integer) 1
    127.0.0.1:6379> zadd user 1500 zhaosi
    (integer) 1
    127.0.0.1:6379> zrangebyscore user -inf +inf # 负无穷到 正无穷 排序
    1) "wangwu"
    2) "zhangsan"
    3) "zhaosi"
    127.0.0.1:6379> ZRANGEBYSCORE user -inf +inf  # 升序
    1) "one"
    2) "two"
    3) "three"
    4) "foure"
    5) "five"
    127.0.0.1:6379> ZREVRANGE user 0 -1 # 降序
    1) "five"
    2) "foure"
    3) "three"
    4) "two"
    5) "one"
    
    127.0.0.1:6379> zrangebyscore user 0 800 # 0 到800 的升序排列
    1) "wangwu"
    
    #################################################
    127.0.0.1:6379> zrem user wangwu # 移除元素
    (integer) 1
    127.0.0.1:6379> zcard user # 获取集合中的个数
    (integer) 2
    
    #################################################
    
    127.0.0.1:6379> ZREVRANGE user 0 -1
    1) "five"
    2) "foure"
    3) "three"
    4) "two"
    5) "one"
    127.0.0.1:6379>
    127.0.0.1:6379>
    127.0.0.1:6379> zcount user 2 3 # 获取区间的个数
    (integer) 2
    127.0.0.1:6379> zcount user 2 4 # 获取区间的个数
    (integer) 3
    
    

    案例思路:

    set排序,存储班级成绩表 工资排序标

    普通消息 1 重要消息 2 带权重进行判断

    排行榜应用

三种特殊类型

Geospatial (地理位置)

朋友的定位,附近的人 , 打车距离计算

############################################################
# geoadd
# 两极无法直接添加
127.0.0.1:6379> geoadd china:city 116.397128 39.916527 beijing # 添加一个城市的经纬度
(integer) 1
127.0.0.1:6379> geoadd china:city 121.48941 31.40527 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 113.6401 34.72468 zhengzhou 108.93425 34.23053 xian # 添加多个城市的经纬度
(integer) 2

############################################################
#  geopos  获取指定城市的经纬度
127.0.0.1:6379> GEOPOS china:city beijing # 获取一个城市的 
1) 1) "116.39712899923324585"
   2) "39.91652647362980844"
127.0.0.1:6379> GEOPOS china:city beijing zhengzhou # 获取多个城市的
1) 1) "116.39712899923324585"
   2) "39.91652647362980844"
2) 1) "113.64010244607925415"
   2) "34.72467993544626808"

############################################################
# 获取两人的距离
单位
m 表示米
km 表示千米
mi 表示英里
ft 表示英尺
# 获取两个城市的距离
127.0.0.1:6379> geodist china:city beijing zhengzhou km # 千米
"626.7593" 

############################################################
# 获取附件的人
127.0.0.1:6379> georadius china:city 116 39 1000 km  # 获取中心为经度116 维度 39 1000千米的所有城市 
1) "zhengzhou"
2) "beijing"
3) "chongqing"
4) "xian"

127.0.0.1:6379> georadius china:city 116 39 1000 km  withdist # 获取中心为经度116维度391000千米的所有城市和距离
1) 1) "zhengzhou"
   2) "519.7813"
2) 1) "beijing"
   2) "107.4949"
3) 1) "chongqing"
   2) "980.5655"
4) 1) "xian"
   2) "823.7398"
127.0.0.1:6379> georadius china:city 116 39 1000 km  withcoord # 获取中心为经度116维度391000千米的所有城市和经纬度
1) 1) "zhengzhou"
   2) 1) "113.64010244607925415"
      2) "34.72467993544626808"
2) 1) "beijing"
   2) 1) "116.39712899923324585"
      2) "39.91652647362980844"
3) 1) "chongqing"
   2) 1) "121.48941010236740112"
      2) "31.40526993848380499"
4) 1) "xian"
   2) 1) "108.93425256013870239"
      2) "34.23053097599082406"

127.0.0.1:6379> georadius china:city 116 39 1000 km   count 2 # 获取指定数量的城市
1) "beijing"
2) "zhengzhou"

##################################################
# 找出指定元素周围的元素
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km withcoord
1) 1) "zhengzhou"
   2) 1) "113.64010244607925415"
      2) "34.72467993544626808"
2) 1) "beijing"
   2) 1) "116.39712899923324585"
      2) "39.91652647362980844"
3) 1) "xian"
   2) 1) "108.93425256013870239"
      2) "34.23053097599082406"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km withdist
1) 1) "zhengzhou"
   2) "626.7593"
2) 1) "beijing"
   2) "0.0000"
3) 1) "xian"
   2) "915.0863"

geo底层的实现原理其实就是zset,可以使用zset的命令操作geo

Hyperloglog 基数统计

hyperlogolog优势:

占用内存是固定,2^64不通的元素的技术,只需要废12KB的内存

什么是基数?

A {1,3,5,7,8,7}

B{1,3,5,7, 8}

基数(不重复元素的个数) = 5,可以接受误差

网页的UV (1个人访问一个网站多次,但是还算做一个人)

传统的方式,set保存用户的id,然后就可以统计set中的元素来判断

这个方式如果保存了大量的用户id就会比较麻烦。我们目的是为了计数,而不是保存用户id

##########################################
127.0.0.1:6379> pfadd k1 a b c d # 新增元素
(integer) 1
127.0.0.1:6379> pfadd k2 d e f j k
(integer) 1
127.0.0.1:6379> pfmerge k3 k1 k2  # 合并元素到另一个元素中
OK
127.0.0.1:6379> pfcount k3 # 获取元素个数
(integer) 8

Bitmaps

位存储

统计疫情感染人数

统计用户信息,活跃,不活跃 登录 和未登录, 365打卡。两种状态的都可以使用bitmaps

bitmaps 位图,数据结构! 都是操作二进制位来记录,就只有0和1

##########################################################
# 统计一周内打卡的天数
# 首先是设置每周的打开状态 0 到6 表示 周一到周末
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 1
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0

## 查看某天是否打卡
127.0.0.1:6379> getbit sign 3 # 查看周四是否打卡
(integer) 1
## 查看一周是否全部打卡
127.0.0.1:6379> bitcount sign
(integer) 6
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 夜莺2517阅读 127,709评论 1 9
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,520评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 2,583评论 2 9
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,178评论 4 8