Redis学习笔记---数据类型

RedisREmote DIctionary Server(远程字典服务器)的缩写,它以字典结构存储数据。现在我们来学习它的五种键值数据类型。学习之前先来了解几个基础命令。

先开启Redis服务:

$ redis-server


接着开启Redis客户端:

$ redis-cli

获取所有键:

127.0.0.1:6379> KEYS *

Redis不区分大小写

判断一个键是否存在,1 表示存在,0 表示不存在:

127.0.0.1:6379> EXISTS key

删除键,可以删除一个或多个键,返回值是删除键的个数:

127.0.0.1:6379> DEL key1 key2 key3

获取键的类型:

127.0.0.1:6379> TYPE key

字符串类型

它能存储任何类型的字符串,包括二进制数据。一个字符串类型键允许存储的数据的最大容量是512MB。

赋值与取值

当键不存在时,会返回空结果

127.0.0.1:6379> set key hello
OK

127.0.0.1:6379> get key
"hello"

127.0.0.1:6379> get name
(nil)

递增数字

当要操作的键不存在时会默认键值为0,所以第一次递增后的结果是1,当键值不是整数时 Redis会提示错误:

127.0.0.1:6379> set age 23
OK

127.0.0.1:6379> incr age
(integer) 24

127.0.0.1:6379> incr num
(integer) 1

127.0.0.1:6379> incr num
(integer) 2

127.0.0.1:6379> set foo lorem
OK

127.0.0.1:6379> incr foo
(error) ERR value is not an integer or out of range

增加指定的整数

127.0.0.1:6379> incrby age 10
(integer) 34

减少指定的整数

127.0.0.1:6379> decr age 
(integer) 33

127.0.0.1:6379> decrby age 6
(integer) 27

增加指定浮点数

127.0.0.1:6379> incrbyfloat score 2.7
"2.7"

127.0.0.1:6379> incrbyfloat score 5E+4
"50002.69999999999999929"

向尾部增加值

APPEND作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,返回值是追加后字符串的总长度。

127.0.0.1:6379> append name 'jenkin'
(integer) 6

127.0.0.1:6379> append name ' wang'
(integer) 11

127.0.0.1:6379> get name 
"jenkin wang"

获取字符串长度

STRLEN命令返回键值的长度,如果键不存在则返回0。UTF-8编码的每个中文汉字的长度都是3,本例中则会返回 6.

127.0.0.1:6379> strlen name
(integer) 11

127.0.0.1:6379> strlen ping
(integer) 0

127.0.0.1:6379> set key 你好
OK

127.0.0.1:6379> strlen key
(integer) 6

同时获得/设置多个键值

127.0.0.1:6379> mset name 'jenkin' age 24 email 'mark94@live.cn'
OK

127.0.0.1:6379> mget name age email
1) "jenkin"
2) "24"
3) "mark94@live.cn"

位操作

GETBIT key offset:获得一个字符串类型键指定位置的二进制位的值(0或1),索引从0开始,如果获取的二进制位的索引超出了键值的二进制实际长度,则默认位值是0
SETBIT key offset value:设置字符串类型建指定位值的二进制位的值,返回的是该位置的旧值
BITCOUNT key [start] [end]:获得字符串类型键中值是1的二进制位个数,可通过参数来限制统计的字节范围
BITOP operation destkey key [key ...]:可以对多个字符串类型键进行位运算,并将结果存储在destkey参数指定的键中,BITOP支持的运算操作有 ANDORXORNOT

​ b a r

ASCII 98 97 114

二进制 01100010 01100001 01110010

​ a a r

ASCII 98 97 114

二进制 01100001 01100001 01110010

127.0.0.1:6379> set foo bar
OK

127.0.0.1:6379> getbit foo 0
(integer) 0

127.0.0.1:6379> getbit foo 6
(integer) 1

127.0.0.1:6379> getbit foo 1000
(integer) 0
127.0.0.1:6379> setbit foo 2 0
(integer) 1

127.0.0.1:6379> get foo
"Bar"

如果要设置的位置超过了键值的二进制位的长度,SETBIT会自动将中间的二进制位设置为0,同理设置一个不存在的键的指定二进制位的值会自动将其前面的位赋值为0

127.0.0.1:6379> bitcount foo
(integer) 10

127.0.0.1:6379> bitcount foo 0 1
(integer) 6

127.0.0.1:6379> bitcount foo 1 2
(integer) 7
127.0.0.1:6379> set foo1 bar
OK

127.0.0.1:6379> set foo2 aar
OK

127.0.0.1:6379> bitop or dest foo1 foo2
(integer) 3

127.0.0.1:6379> get dest
"car"

散列类型

散列类型的键值也是一种字典结构,其存储了字段和字段值的映射,但字段值只能是字符串,不支持其他数据类型。散列类型不能嵌套其它的数据类型。一个散列类型键可以包含至多2^32-1个字段。

除了散列类型,Redis的其他数据类型同样不支持数据类型嵌套,比如集合类型的每个元素都只能是字符串,不能是另一个集合或散列表等

赋值与取值

HSET key field value:不区分插入和更新操作,当执行的是插入操作时(即之前字段不存在)HSET命令会返回1,当执行的是更新操作时(即之前字段已经存在)HSET命令会返回0.当键本身不存在时,HSET命令还会自动创建它。
HGET key field:
HMSET key field value [field value ...]:同时设置多个字段的值
HMGET key field [field ...]
HGETALL key: 获取键中所有的字段和字段值。很多语言的Redis客户端会将HGETALL的返回结果封装成编程语言中的对象。

127.0.0.1:6379> hset car price 500
(integer) 1

127.0.0.1:6379> hset car name BMW
(integer) 1

127.0.0.1:6379> hget car name 
"BMW"

127.0.0.1:6379> hmset student name jenkin age 24 score 100
OK

127.0.0.1:6379> hmget student name age score
1) "jenkin"
2) "24"
3) "100"

127.0.0.1:6379> hgetall student
1) "name"
2) "jenkin"
3) "age"
4) "24"
5) "score"
6) "100"

判断字段是否存在

HEXISTS key field:如果存在则返回1,否则返回0(如果键不存在也会返回0)。

127.0.0.1:6379> hexists car price
(integer) 1

127.0.0.1>6379> hexists car brand
(integer) 0

当字段不存在时赋值

HSETNX key field value:如果字段已经存在,HSETNX命令将不执行任何操作。HSETNX命令是原子操作,不用担心竞态条件。

127.0.0.1:6379> hgetall car
1) "price"
2) "500"
3) "name"
4) "BMW"

127.0.0.1:6379> hsetnx car price 1000
(integer) 0

127.0.0.1:6379> hget car price
"500"

127.0.0.1:6379> hsetnx car place China
(integer) 1

127.0.0.1:6379> hgetall car 
1) "price"
2) "500"
3) "name"
4) "BMW"
5) "place"
6) "China"

增加数字

HINCRBY key field increment:返回值是增值后的字段值。如果该键不存在,会自动增加该键。散列类型没有HINCR命令.

127.0.0.1:6379> hincrby car price 200
(integer) 700

删除字段

HDEL key field [field ...]:可以删除一个或多个字段,返回值是被删除的字段个数。

127.0.0.1:6379> hdel car price
(integer) 1

127.0.0.1:6379> hdel car price
(integer) 0

只获取字段名或字段值

127.0.0.1:6379> hkeys car
1) "name"
2) "place"

127.0.0.1:6379> hvals car
1) "BMW"
2) "China"

获取字段数量

127.0.0.1:6379> hlen car 
(integer) 2

列表类型

列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素或者获得列表的某一个片段。列表类型内部是使用双向链表实现的,向列表两端添加元素的时间复杂度为O(1),获取越接近两端的元素越快。一个列表类型键最多能容纳2^32-1个元素。

向列表两端增加元素

LPUSH key value [value …]:向列表左边增加元素,返回值表示增加元素后列表的长度。
RPUSH key value [value …]:向列表右边增加元素,返回值表示增加元素后列表的长度。

127.0.0.1:6379> lpush numbers 1
(integer) 1

127.0.0.1:6379> lpush numbers 2 3
(integer) 4

127.0.0.1:6379> rpush numbers 7 8 9
(integer) 7

向列表两端弹出元素

LPOP key:从列表左边弹出一个元素(将列表左边的元素从列表中移除,并返回被移除的元素值)
RPOP key:从列表右边弹出一个元素(将列表右边的元素从列表中移除,并返回被移除的元素值)

127.0.0.1:6379> lpop numbers
"4"

127.0.0.1:6379> rpop numbers
"9"

获取列表中元素的个数

127.0.0.1:6279> llen numbers
(integer) 5

LLEN命令的功能类似SQL语句 SELELCT COUNT(*) FROM table_name,但LLEN的时间复杂度为O(1)。

获得列表片段

LRANGE key start stop

127.0.0.1:6379> lrange numbers 0 3
1) "3"
2) "2"
3) "1"
4) "7"

127.0.0.1:6379> lrange numbers -2 -1
1) "7"
2) "8"

127.0.0.1:6379> lrange numbers 9 10
(empty list or set)

127.0.0.1:6379> lrange numbers 1 999
1) "2"
2) "1"
3) "7"
4) "8"

如果start的索引位置比stop的索引位置靠后,则会返回空列表;

如果stop大于实际的索引范围,则会返回到列表左右边的元素。

删除列表中指定的值

LREM key count value:删除列表中前count个值为value的元素,返回值是实际删除的元素。
1.当count > 0 时,LREM命令会从列表左边开始删除前count个值为value的元素;
2.当count < 0 时,LREM命令会从列表右边开始删除前|count|个值为value的元素;
3.当count = 0 时,LREM命令会删除所有值为value的元素。

127.0.0.1:6379> lrange numbers 0 -1
1) "3"
2) "2"
3) "1"
4) "7"
5) "8"

127.0.0.1:6379> lrem numbers 3 1
(integer) 1

127.0.0.1:6379> lrem numbers -1 8
(integer) 1

获得/设置指定索引的元素值

LINDEX key index:返回指定索引的元素,索引从0开始,如果index是负数表示从右边开始计算的索引,最右边元素索引是-1。
LSET key index value:将索引为index的元素赋值为value。

127.0.0.1:6379> lrange numbers 0 -1
1) "5"
2) "6"
3) "7"
4) "8"
5) "9"
6) "7"

127.0.0.1:6379> lindex numbers 5
"7"

127.0.0.1:6379> lindex numbers -1
"7"

127.0.0.1:6379> lset numbers -1 10
OK

127.0.0.1:6379> lindex numbers -1
"10"

只保留列表指定片段

LTRIM key start end:删除指定索引范围之外的所有元素。

127.0.0.1:6379> lrange numbers 0 -1
1) "10"
2) "6"
3) "7"
4) "8"
5) "9"
6) "10"

127.0.0.1:6379> ltrim numbers 1 4
OK

127.0.0.1:6379> lrange numbers 0 -1
1) "6"
2) "7"
3) "8"
4) "9"

向列表中插入元素

LINSERT key BEFORE|AFTER pivot value:先在列表中从左到右查找值为pivot的元素,然后根据第二个参数是before还是after来决定将value插入到该元素的前面还是后面。返回值是插入后列表的元素个数。

127.0.0.1:6379> lrange numbers 0 -1
1) "8"
2) "6"
3) "7"
4) "8"
5) "9"

127.0.0.1:6379> linsert numbers after 8 -2
(integer) 6

127.0.0.1:6379> lrange numbers 0 -1
1) "8"
2) "-2"
3) "6"
4) "7"
5) "8"
6) "9"

将元素从一个列表转移到另一个列表

RPOPLPUSH source destination:先执行RPOP命令再执行LPUSH命令。RPOPLPUSH命令会先从source列表类型键的右边弹出一个元素,然后将其加入到destination列表类型键的左边,并返回这个元素的值,整个过程是原子的。

127.0.0.1:6379> rpoplpush numbers new_numbers
"9"

集合类型

集合类型在Redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复杂度都是O(1)。在集合中的每个元素都是不同的,且没有顺序。一个集合类型(Set)键可以存储至多2^32-1个字符串。

增加/删除元素

SADD key member [member …]:向集合增加一个或多个元素,如果键不存在则会自动创建。
SREM key member [member …]:从集合中删除一个或多个元素,并返回删除成功的个数。

127.0.0.1:6379> sadd letters a
(integer) 1

127.0.0.1:6379> sadd letters a b c
(integer) 2

127.0.0.1:6379> srem letters c d
(integer) 1

获得集合中的所有元素

SMEMBERS key:返回集合中的所有元素。

127.0.0.1:6379> smembers letters
1) "b"
2) "a"

判断元素是否在集合中

SISMEMEBER key member:判断一个元素是否在集合中,时间复杂度是O(1)。当值存在时返回1,当值不存在或键不存在时返回0.

127.0.0.1:6379> sismember letters b
(integer) 1

127.0.0.1:6379> sismember letters f
(integer) 0

127.0.0.1:6379> sismember letter b
(integer) 0

集合间运算

SDIFF key [key …]:对多个集合进行差集运算
SINTER key [key ...]:对多个集合执行交集运算
SUNION KEY [KEY …]:对多个集合执行并集运算

127.0.0.1:6379> sadd setA 1 2 3
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
127.0.0.1:6379> sdiff setA setB
1) "1"
127.0.0.1:6379> sdiff setB setA
1) "4"
127.0.0.1:6379> sadd setC 2 3
(integer) 2
127.0.0.1:6379> sdiff setA setB setC
1) "1"

127.0.0.1:6379> sinter setA setB
1) "2"
2) "3"
127.0.0.1:6379> sinter setA setB setC
1) "2"
2) "3"

127.0.0.1:6379> sunion setA setB
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sunion setA setB setC
1) "1"
2) "2"
3) "3"
4) "4"

获取元素中集合个数

SCARD key:获取集合中的元素个数。

127.0.0.1:6379> smembers letters
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> scard letters
(integer) 3

进行集合运算并将结果存储

SDIFFFSTORE destination key [key ...]
SINTERSTORE destination key [key ...]
SUNIONSTORE destination key [key ...]

127.0.0.1:6379> sdiffstore setAB setA setB
(integer) 1
127.0.0.1:6379> smembers setAB
1) "1"

127.0.0.1:6379> sinterstore setAinB setA setB
(integer) 2
127.0.0.1:6379> smembers setAinB
1) "2"
2) "3"

127.0.0.1:6379> sunionstore setAandB setA setB
(integer) 4
127.0.0.1:6379> smembers setAandB
1) "1"
2) "2"
3) "3"
4) "4"

随机获取集合中的元素

SRANDMEMBER key [count]:随机从集合中获取一个元素
1.当count为正数时,SRANDMEMBER 会随机从集合里获得count个不重复的元素。如果count的值大于集合中的元素个数,则返回全部元素。
2.当count为负数时,SRANDMEMBER会随机从集合里获得|count|个的元素,这些元素有可能相同。

127.0.0.1:6379> srandmember letters
"a"

127.0.0.1:6379> srandmember letters 2
1) "a"
2) "b"
127.0.0.1:6379> srandmember letters -2
1) "a"
2) "a"
127.0.0.1:6379>

从集合中弹出一个元素

SPOP key:从集合中随机选择一个元素弹出。

127.0.0.1:6379> spop letters
"c"

有序集合类型

在集合类型的基础上有序集合类型为集合中的每一个元素都关联了一个分数。有序集合类型是使用散列表和跳跃表
实现的,时间复杂度为O(log(n))。有序集合比列表类型更耗费内存。

增加元素

ZADD key score member [score member ...] :向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数(不包含之前已经存在的元素)。分数不仅可以是整数,还可以是双精度浮点数。

127.0.0.1:6379> zadd scoreboard 89 Tom 67 Peter 100 Jenkin
(integer) 3
127.0.0.1:6379> zadd scoreboard 76 Peter
(integer) 0
127.0.0.1:6379> zadd testboard +inf c
(integer) 1
127.0.0.1:6379> zadd testboard -inf d
(integer) 1

+inf 表示正无穷,-inf表示负无穷。

获得元素的分数

ZSCORE key member

127.0.0.1:6379> zscore scoreboard Jenkin
"100"

获取排名在某个范围的元素列表

ZRANGE key start stop [WITHSCORES]:按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。时间复杂度为O(log n+m) (其中n为有序集合的基数,m为返回的元素个数)。如果两个元素的分数相同则会按照字典顺序(0<9<A<Z<a<z)进行排序。ZRANGE与LRANGE命令十分相似。
ZREVRANGE key start stop [WITHSCORES]:按照元素分数从大到小的顺序给出结果。

127.0.0.1:6379> zrange scoreboard 0 2
1) "Peter"
2) "Tom"
3) "Jenkin"

127.0.0.1:6379> zrange scoreboard 1 -1
1) "Tom"
2) "Jenkin"

127.0.0.1:6379> zrange scoreboard 0 -1 withscores
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "Jenkin"
6) "100"

127.0.0.1:6379> zrevrange scoreboard 0 -1 withscores
1) "Jenkin"
2) "100"
3) "Tom"
4) "89"
5) "Peter"
6) "76"

获得指定分数范围的元素

ZRANGEBYSCORE key min max [WITHSCORES][LIMIT offset count]:按照元素分数从小到大的顺序返回分数在min和max之间的元素。LIMIT offset count与SQL中的用法基本相同,即在获得的元素列表的基础上向后偏移offset个元素,并且只获取前count个元素。

27.0.0.1:6379> zrange scoreboard 0 -1 withscores
 1) "Jerry"
 2) "56"
 3) "Danny"
 4) "67"
 5) "Peter"
 6) "76"
 7) "Tom"
 8) "89"
 9) "Wenddy"
10) "92"
11) "Jenkin"
12) "100"

127.0.0.1:6379> zrangebyscore scoreboard 80 100
1) "Tom"
2) "Wenddy"
3) "Jenkin"

127.0.0.1:6379> zrangebyscore scoreboard 80 (100
1) "Tom"
2) "Wenddy"

127.0.0.1:6379> zrangebyscore scoreboard (80 +inf
1) "Tom"
2) "Wenddy"
3) "Jenkin"

127.0.0.1:6379> zrangebyscore scoreboard 60 +inf limit 1 3
1) "Peter"
2) "Tom"
3) "Wenddy"

127.0.0.1:6379> zrevrangebyscore scoreboard 100 0 limit 0 3
1) "Jenkin"
2) "Wenddy"
3) "Tom"

增加某个元素的分数

ZINCRBY key increment member:增加一个元素的分数,返回值是更改后的分数。如果指定的元素不存在,Redis在执行命令前会先建立它并将它的分数赋为0再执行操作。

127.0.0.1:6379> zincrby scoreboard 100 Jenkin
"200"
127.0.0.1:6379> zincrby scoreboard -100 Jenkin
"100"

获取集合中元素的数量

ZCARD key

127.0.0.1:6379> zcard scoreboard
(integer) 6

获得指定分数范围内的元素个数

ZCOUNT key min max

127.0.0.1:6379> zcount scoreboard 80 100
(integer) 3
127.0.0.1:6379> zcount scoreboard 80 (100
(integer) 2

删除一个或多个元素

ZREM key member [member ...]:命令返回值是成功删除的元素数量(不包含本来就不存在的元素)。

127.0.0.1:6379> zrem scoreboard Wenddy
(integer) 1
127.0.0.1:6379> zcard scoreboard
(integer) 5

按照排名范围删除元素

ZREMRANGEBYRANK key start stop:按照元素分数从小到大的顺序删除处在指定排名范围内的所有元素,并返回删除的元素数量。

127.0.0.1:6379> zadd testRem 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:6379> zremrangebyrank testRem 0 2
(integer) 3

127.0.0.1:6379> zrange testRem 0 -1
1) "d"
2) "e"
3) "f"

按照分数范围删除元素

ZREMRANGEBYSCORE key min max:删除指定范围内的所有元素。

127.0.0.1:6379> zremrangebyscore testRem (4 5
(integer) 1
127.0.0.1:6379> zrange testRem 0 -1
1) "d"
2) "f"

获得元素的排名

ZRANK key member:按照元素分数从下到大的顺序获得指定的元素排名
ZREVRANK member:分数最大的元素排名为0.

127.0.0.1:6379> zrange scoreboard 0 -1 withscores
 1) "Jerry"
 2) "56"
 3) "Danny"
 4) "67"
 5) "Peter"
 6) "76"
 7) "Tom"
 8) "89"
 9) "Jenkin"
10) "100"
127.0.0.1:6379> zrank scoreboard Jenkin
(integer) 4
127.0.0.1:6379> zrevrank scoreboard Jenkin
(integer) 0

计算有序集合的交集

ZINTERSTORE destination numkeys key [key ...][WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]:计算多个有序集合的交集并将结果存储在destination键中,返回值为destination键中的元素个数。destination键中元素的分数是由AGGREGATE参数决定的。
1.当AGGREGATESUM时(也就是默认值),destination键中元素的分数是每一个参与计算的集合中该元素分数的
2.当AGGREGATEMIN时,destination键中元素的分数是每一个参与计算的集合中该元素分数的最小值
3.当AGGREGATEMAX时,destination键中元素的分数是每一个参与计算的集合中该元素分数的最大值
ZINTERSTORE还能够通过WEIGHTS参数设置每个集合的权重,每个集合在参与计算时元素的分数会被乘上该集合 的权重。

127.0.0.1:6379> zadd sortedSets1 1 a 2 b
(integer) 2
127.0.0.1:6379> zadd sortedSets2 10 a 20 b
(integer) 2

127.0.0.1:6379> zinterstore sortedSetsResults 2 sortedSets1 sortedSets2
(integer) 2

127.0.0.1:6379> zrange sortedSetsResults 0 -1 withscores
1) "a"
2) "11"
3) "b"
4) "22"

127.0.0.1:6379> zinterstore sortedSetsResult 2 sortedSets1 sortedSets2 aggregate min
(integer) 2

127.0.0.1:6379> zrange sortedSetsResult 0 -1 withscores
1) "a"
2) "1"
3) "b"
4) "2"

127.0.0.1:6379> zinterstore sortedSetsResult 2 sortedSets1 sortedSets2 aggregate max
(integer) 2
127.0.0.1:6379> zrange sortedSetsResult 0 -1 withscores
1) "a"
2) "10"
3) "b"
4) "20"

127.0.0.1:6379> zinterstore sortedSetsResults 2 sortedSets1 sortedSets2 weights 1 0.1
(integer) 2
127.0.0.1:6379> zrange sortedSetsResults 0 -1 withscores
1) "a"
2) "2"
3) "b"
4) "4"

个人博客:https://jenkinwang.github.io/

参考书籍:《Redis入门指南(第二版)》李子骅 编著

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

推荐阅读更多精彩内容