python 之redis
redis是一个key-value存储系统,与memcached类似,它支持存储到value类型相对更多,包括string(字符串),list(列表),set(集合),zset(sorted set --有序集合)和hash(哈希类型),这些数据类型都支持push/pop,add/remove及取交集和并集和差集及更丰富的操作,而且这些操作都是原子性的,在此基础上,redis支持各种不同方式的排序,与memcached一样,为了保证效率,数据都是缓存在内存中,区别是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的纪录文件,并且在此基础上,实现了master-slave主从同步
1.启动客户端
redis默认端口6379
通过shell命令redis-cli
- 127.0.0.1:> set name hello
- OK
- 127.0.0.1:> get name
- "hello"
通过python操作
pip install redis
- import redis
- r = redis.Redis(host="127.0.0.1", port=6379)
- r.set("user", "zengchunyun")
- user = r.get("user") # 获取KEY为user的值
- print(user) # python3获取的是bytes类型数据,使用时需要准换成UTF8类型
上面这种方式每次操作redis都需要进行一次连接操作,资源浪费严重,所以一般操作时都采取连接池方式
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立释放连接的开销,默认,每个redis实例都会维护一个自己的连接池,可以直接建立一个连接池,然后作为参数redis,这样可以实现多个redis实例共享一个连接池
- pool = redis.ConnectionPool(host="127.0.0.1", port=6379)
- r = redis.Redis(connection_pool=pool)
- r.set("user", "python")
- user = r.get("user")
- print(user)
- # b'python'
2.操作
string操作,redis中的string在内存中按照一个name对应一个value来存储
- SET key value [EX seconds] [PX milliseconds] [NX|XX]
- summary: Set the string value of a key
- since: 1.0.
- group: string
- r.set(name="user", value="zengchunyun", ex=100, px=None, nx=True, xx=False)
- user = r.get("user")
- print(user)
- # 当nx为True时,则只有不存在name时,set操作才会执行
- r.set(name="user", value="zengchunyun", ex=100, px=None, nx=False, xx=True)
- user = r.get("user")
- print(user)
- # 当 xx为True时,只有name存在时,set操作才会执行
- r.set(name="pwd", value="zengchunyun", ex=100, px=None, nx=True, xx=True)
- user = r.get("pwd")
- print(user)
- # 当nx,xx同时为True时,结果为None
setnx
- r.setnx(name="age", value=10)
- age = r.get("age")
- print(age) # 打印10
- r.setnx(name="age", value=100)
- age = r.get("age")
- print(age) # 打印10
- # setnx只有name不存在时,才执行操作
setex
- import datetime
- date = datetime.timedelta(seconds=100)
- print(date)
- r.setex(name="user", value=111, time=date)
- print(r.get("user"))
psetex
- date = datetime.timedelta(milliseconds=100)
- r.psetex(name="user", time_ms=date, value=121)
- print(r.get("user"))
mset
- r.mset(k1=110, k2=119) # 设置多个值
- r.mset({"k1": 120, "k2": 121})
- print(r.mget("k2")) # 取单个值
- print(r.mget("k1", "k2")) # 取多个值,返回的都是列表类型
- print(r.mget(["k1", "k2"]))
getset
- r.set(name="user", value="zcy")
- print(r.get("user")) # 获取键值
- print(r.getset(name="user", value="newzcy")) # 设置新值,并获取原来的值,不存在则为none
- print(r.get("user")) # 打印新值
- # b'zcy'
- # b'zcy'
- # b'newzcy'
getrange
- user = r.getrange(key="user", start=0, end=-1)
- print(user)
- user = r.getrange(key="user", start=0, end=-2)
- print(user)
- user = r.getrange(key="user", start=1, end=-1)
- print(user) # 从第1位,也就是下标为1的元素,结束为最后一位
- user = r.getrange(key="user", start=0, end=1)
- print(user) # 包括开始位置,以及结束位置
- # b'newzcy'
- # b'newzc'
- # b'ewzcy'
- # b'ne'
setrange
- print(r.get("user"))
- r.setrange(name="user", offset=1, value=22) # 从下标1开始修改user的值,
- print(r.get("user"))
- # b'n22zcy'
- # b'n22zcy'
- print(r.get("user"))
- r.setrange(name="user", offset=1, value="我") # 从下标1开始修改user的值,如果是汉字,泽占三个字节
- print(r.get("user"))
- # b'n222222'
- # b'n\xe6\x88\x91222'
setbit
- r.set(name="user", value="") # 字符串表示法
- user = r.get("user") # 打印字符串内容为110
- print(user)
- user_li = list(map(lambda x: ord(x), str(user, "utf8")))
- print(user_li) # 打印每个字符在计算机中实际的十进制数值 [49, 49, 48]
- print(list(map(lambda x: bin(x), user_li))) # 打印每个字符在计算机中代表的实际二进制位 ['0b110001', '0b110001', '0b110000']
- print("-" * 20)
- print(r.getbit(name="user", offset=9)) # 查看第二个字节对第二位,也就是下标为1的位,这位显示为0
- r.setbit(name="user", offset=9, value=1) # 计算机中每个字符范围-127~127,\
- # 即11111111~01111111,最高位也就是下标为0的位代表一个数的正负符号,为1则代表负数,为0则为正数\
- # 故而如果修改一个二进制数的最高位则表示去修改他的正负符号位,字符串是没有符号的,只有整数才有符号之分\
- # ,所以如果使用符号方式,是不能进行将一个负的二进制转换成字符
- print("\xb1") # 表示+-符号
- user = r.get("user") # 这里我们修改第二个字节的第二位也就是下标为1,原来这位为0,也就是这位现在的十进制由49变成了\
- # ,64+49=113,第二位二进制表示的十进制数为64,十进制的113对应的字符为q
- print(user) # 所以这里打印的是1q0
- user_li = list(map(lambda x: ord(x), str(user, "utf8")))
- print(user_li) # [49, 113, 48]
- print("-" * 20)
- print(list(map(lambda x: bin(x), user_li))) # ['0b110001', '0b1110001', '0b110000']
- print(r.getbit(name="user", offset=9)) # 查看第二个字节对第二位,也就是下标为1的位,也就是我们刚才设置的位由0变成了1
bitcount
- r.setbit(name="count", offset=1, value=1)
- r.setbit(name="count", offset=2, value=1)
- r.setbit(name="count", offset=3, value=1)
- print(r.bitcount(key="count")) # 统计一个二进制数有多少位是1
strlen
- r.set(name="user", value="曾")
- print(r.strlen(name="user"))
- r.set(name="user", value="")
- print(r.strlen(name="user"))
- r.set(name="user", value=12)
- print(r.strlen(name="user"))
incr
- r.set(name="user", value=1)
- r.incr(name="user", amount=1)
- print(r.get("user"))
- r.incr(name="user", amount=1)
- print(r.get("user"))
- r.incr(name="user", amount=1)
- print(r.get("user"))
- # b'2'
- # b'3'
- # b'4'
incrbyfloat
- r.set(name="user", value=1.1)
- r.incrbyfloat(name="user", amount=1.2)
- print(r.get("user"))
- r.incrbyfloat(name="user", amount=1)
- print(r.get("user"))
- r.incrbyfloat(name="user", amount=1)
- print(r.get("user"))
- # b'2.3'
- # b'3.3'
- # b'4.3'
decr
- r.set(name="user", value=3)
- r.decr(name="user", amount=1)
- print(r.get("user"))
- r.decr(name="user", amount=1)
- print(r.get("user"))
- r.decr(name="user", amount=1)
- print(r.get("user"))
- # b'2'
- # b'1'
- # b'0'
append
- r.set(name="user", value="")
- r.append(key="user", value="") # 将21追加到到键值
- print(r.get("user"))
hset
- r.hset(name="info", key="name", value="zengchunyun")
- print(r.hget(name="info", key="name"))
- r.hmset(name="info",mapping={"k1": 1, "k2": 23})
- print(r.hmget(name="info", keys="k1"))
- print(r.hmget("info", ["k1", "k2", "k3"]))
- print(r.hgetall(name="info"))
- print(r.hlen(name="info"))
- print(r.hkeys("info"))
- print(r.hvals("info"))
- print(r.exists("hello"))
- print(r.exists("info"))
- print(r.hdel("info","k3")) # 删除指定键
- print(r.hkeys("info"))
- print(r.hincrby(name="info", key="count", amount=1))
- print(r.hincrby(name="info", key="count", amount=1))
- print(r.hincrbyfloat(name="info", key="count_f", amount=1.1))
- print(r.hincrbyfloat(name="info", key="count_f", amount=1.1))
- print(r.hincrbyfloat(name="info", key="count_f", amount=1.1))
- print(r.hscan(name="info"))
- print(r.hscan(name="info", count=2, match="k2"))
- # b'zengchunyun'
- # [b'1']
- # [b'1', b'23', None]
- # {b'k2': b'23', b'k1': b'1', b'count': b'15', b'count_f': b'19.8', b'name': b'zengchunyun'}
- #
- # [b'name', b'k1', b'k2', b'count', b'count_f']
- # [b'zengchunyun', b'1', b'23', b'15', b'19.8']
- # False
- # True
- #
- # [b'name', b'k1', b'k2', b'count', b'count_f']
- #
- #
- # 20.9
- # 22.0
- # 23.1
- # (0, {b'k2': b'23', b'k1': b'1', b'count': b'17', b'count_f': b'23.1', b'name': b'zengchunyun'})
- # (0, {b'k2': b'23'})
lpush,列表基本操作
- print(r.delete("oo")) # 返回删除的列表个数
- print(r.lpush('oo', 11,22,33)) # 返回的是列表的长度,从右向左添加每个元素,也就是['33', '22', '11']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.lpushx(name="oo", value=44)) # 在对应的列表中添加元素,如果name已经存在,则添加到列表的最左边,[b'44', b'33', b'22', b'11']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.llen(name="oo"))
- print(r.rpush("oo", 55, 66)) # 在列表oo中从左向右添加元素, [b'44', b'33', b'22', b'11', b'55', b'66']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.rpushx(name="oo", value=41)) # 只有name存在时,则在列表从左向右添加数据, [b'44', b'33', b'22', b'11', b'55', b'66', b'41']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.rpushx(name="too", value=41)) # 只有name存在时,则在列表从左向右添加数据
- print(r.lrange(name="too", start=0, end=-1))
- print(r.linsert(name="oo", where="BEFORE", refvalue="", value=12)) # 在列表oo里,如果存在41这个元素,则在第一次找到的41元素前\
- # 插入新元素12,不存在则返回-1, [b'44', b'33', b'22', b'11', b'55', b'66', b'12', b'41']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.linsert(name="oo", where="AFTER", refvalue="", value=12)) # 在列表oo里,如果存在41这个元素,则在第一次找到的41元素后\
- # 插入新元素12,不存在则返回-1, [b'44', b'33', b'22', b'11', b'55', b'66', b'12', b'41', b'12']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.lset(name="oo", index=2, value=13)) # 对列表oo下标为2的元素修改值为13,修改成功为True,否则异常,
- # [b'44', b'33', b'13', b'11', b'55', b'66', b'12', b'41', b'12']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.lrem(name="oo", value=41, num=1)) # 找到列表元素为41的对象,num=0,则删除所有元素为41的对象,num=3,则表示从前到后删除3个元素\
- # num=-3表示从后向前删除3个,返回删除的个数,[b'44', b'33', b'13', b'11', b'55', b'66', b'12', b'12']
- print(r.lrange(name="oo", start=0, end=-1))
- print(r.lpop(name="oo")) # 在列表中,从左侧获取第一个元素从列表移除,返回第一个移除的元素
- print(r.lrange(name="oo", start=0, end=-1)) # [b'33', b'13', b'11', b'55', b'66', b'12', b'12']
- print(r.rpop(name="oo")) # 在列表中,从右侧获取最后一个元素从列表移除,返回最后一个元素
- print(r.lrange(name="oo", start=0, end=-1)) # [b'33', b'13', b'11', b'55', b'66', b'12']
- print(r.lindex(name="oo", index=2)) # 获取列表里下标为2的元素
- print(r.lrange(name="oo", start=0, end=-1)) # [b'33', b'13', b'11', b'55', b'66', b'12']
- print(r.ltrim(name="oo", start=1, end=4)) # 移除下标为1元素之前的元素,不包括下标1,以及移除下标4之后的元素,但不包括下标4
- print(r.lrange(name="oo", start=0, end=-1)) # [b'13', b'11', b'55', b'66']
blpop
- print(r.delete("userli"))
- print(r.delete("newli"))
- print(r.lpush("userli", 11, 22, 33, 44, 33, 22)) # 从右向左添加元素,[b'22', b'33', b'44', b'33', b'22', b'11']
- print(r.lrange(name="userli", start=0, end=-1))
- print(r.lpush("newli", 23))
- print(r.rpoplpush(src="userli", dst="newli")) # 从一个列表移除最右边的元素,添加到另一个列表的最左边,同时返回移除的元素
- print(r.lrange(name="userli", start=0, end=-1)) # [b'22', b'33', b'44', b'33', b'22']
- print(r.lrange(name="newli", start=0, end=-1)) # [b'11', b'23']
- print(r.blpop(keys="userli", timeout=100)) # 删除和获取列表中第一个元素,或阻塞直到有可用, (b'userli', b'22')
- print(r.lrange(name="userli", start=0, end=-1)) # [b'33', b'44', b'33', b'22']
- print(r.brpop(keys="userli", timeout=0)) # 删除并获取列表最后一个元素,或阻塞直到有可用元素,(b'userli', b'22')
- print(r.lrange(name="userli", start=0, end=-1)) # [b'33', b'44', b'33']
- print(r.blpop(keys="userl", timeout=5)) # 删除和获取列表中第一个元素,或阻塞直到有可用, (b'userl', b'33')
- print(r.lrange(name="userl", start=0, end=-1))
- print(r.brpoplpush(src="userli", dst="userl", timeout=0)) # 取出列表最右侧的元素并移除返回,增加到目标列表
- print(r.lrange(name="userli", start=0, end=-1)) # [b'33', b'44']
- print(r.lrange(name="userl", start=0, end=-1)) # [b'33']
- #
- #
- #
- # [b'22', b'33', b'44', b'33', b'22', b'11']
- #
- # b'11'
- # [b'22', b'33', b'44', b'33', b'22']
- # [b'11', b'23']
- # (b'userli', b'22')
- # [b'33', b'44', b'33', b'22']
- # (b'userli', b'22')
- # [b'33', b'44', b'33']
- # (b'userl', b'33')
- # []
- # b'33'
- # [b'33', b'44']
- # [b'33']
集合
- r.delete("s")
- r.delete('s2')
- print(r.sadd("s", "a", 'b')) # 添加数据到集合's'
- print(r.smembers('s')) # 查看集合成员
- print(r.scard('s')) # 判定集合长度,不存在则为0
- print(r.sismember('s', 'a')) # 判定对象是否存在集合里
- print(r.sadd('s2', 'a'))
- print(r.sinter('s', 's2')) # 获取两个集合的交集,{b'a'}
- print(r.sinterstore('s3', 's', 's2')) # 求交集,并把结果付给s3,返回交集个数
- print(r.smembers('s3'))
- print(r.smembers('s')) # {b'b', b'a'}
- print(r.smembers('s2')) # {b'a'}
- print(r.sunion('s', 's2')) # {b'b', b'a'}求并集,返回两个集合的所有元素,不重复
- print(r.sunionstore('s4', 's', 's2')) # 将两个集合的并集赋值给s4
- print(r.smembers('s4'))
- print(r.sdiff('s', 's2')) # 求集合s里有,但是集合s2里没有的元素
- print(r.sdiffstore('s5', 's', 's2')) # 将两个集合的差集赋值给S5
- print(r.smembers('s5'))
- print(r.srandmember('s')) # 取随机元素
- print(r.smove(src='s', dst='s6', value='b')) # 将集合成员b移到另一个集合,成功为True,否则False
- print(r.smembers('s6'))
- print(r.smembers('s'))
- print(r.sadd('s', 11, 33, 44))
- print(r.smembers('s'))
- print(r.spop('s')) # 移除尾部一个成员,并将其返回
- print(r.srem('s', 11)) # 删除集合成员11
- print(r.smembers('s'))
- #
- # {b'a', b'b'}
- #
- # True
- #
- # {b'a'}
- #
- # {b'a'}
- # {b'a', b'b'}
- # {b'a'}
- # {b'a', b'b'}
- #
- # {b'a', b'b'}
- # {b'b'}
- #
- # {b'b'}
- # b'a'
- # True
- # {b'b'}
- # {b'a'}
- #
- # {b'11', b'a', b'44', b'33'}
- # b'44'
- #
- # {b'a', b'33'}
- print(r.sadd('s', 11, 22, 33, 11, 10))
- print(r.sscan(name='s', count=1, match="1*")) # 匹配集合1*的成员
- print(r.sscan_iter('s', match='1*')) # 返回一个迭代器,用于增量分批获取元素,避免内存消耗太大
有序集合
- print(r.delete('zs'))
- print(r.zadd('zs', 'h1', 1, 'h2', 2))
- print(r.zadd('zs', n1=11, n2=22))
- print(r.zcard('zs')) # 获取集合长度,也就是成员个数
- print(r.zcount('zs', 1, 23)) # 获取集合分数在1到23之间,包含1和23的个数
- print(r.zincrby('zs', 11, amount=1)) # 自增集合对应成员的有序集合的对应分数
- print(r.zincrby('zs', 11, amount=1))
- print(r.zrange(name='zs', start=0, end=-1)) # 获取集合范围内的有序集合成员
- # 参数:
- # name,redis的name
- # start,有序集合索引起始位置(非分数)
- # end,有序集合索引结束位置(非分数)
- # desc,排序规则,默认按照分数从小到大排序
- # withscores,是否获取元素的分数,默认只获取元素的值
- # score_cast_func,对分数进行数据转换的函数
- print(r.zrevrange(name='zs', start=0, end=-1)) # 按照分数从大到小排序集合
- print(r.zrangebyscore(name='zs', min=1, max=11)) # 获取集合分数内的成员
- print(r.zrevrangebyscore(name='zs', max=13, min=1)) # 按照分数从大到小排序集合成员
- print(r.zrank(name='zs', value='h2')) # 获取某个成员在集合中的排行
- print(r.zrevrank(name='zs', value='n1')) # 从大到小排序,获取某个成员排行位置
- print(r.zrem('zs', 'n1')) # 删除集合对应的成员
- print(r.zrange('zs', 0, -1))
- print(r.zremrangebyrank(name='zs', min=1, max=2)) # 删除指定排序范围成员,即删除下标1,不包含1,到下标2,包含2
- print(r.zrange('zs', 0, -1))
- print(r.zremrangebyscore(name='zs', min=1, max=20)) # 删除指定分数范围内的集合成员
- print(r.zrange(name='zs', start=0, end=-1))
- print(r.zscore(name='zs', value='n2')) # 返回集合成员对应的分数,浮点数
- r.delete('s2')
- print(r.zadd('s2', n3=222, n2=222))
- print(r.zinterstore(dest='news', keys=['zs', 's2'])) # 求两个有序集合的并集
- print(r.zrange(name='news', start=0, end=-1))
- print(r.zunionstore(dest='nn', keys=['zs', 's2'])) # 求两个集合的并集,如果遇到不同值分数,则按照aggregate进行操作
- # aggregate值为:SUM,MIN,MAX
- print(r.zrange(name='nn', start=0, end=-1))
- print(r.zscan(name='zs', count=1)) # 同字符串类似,新增score_cast_func用来进行对分数进行操作
- print(r.delete('test')) # 删除任意数据类型
- print(r.exists(name="test")) # 判断name是否存在
- print(r.keys(pattern="*")) # 打印所有匹配对KEY
- # KEYS * 匹配数据库中所有 key 。
- # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
- # KEYS h*llo 匹配 hllo 和 heeeeello 等。
- # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
- print(r.expire(name='zs', time=2)) # 为某个name设置超时时间
- print(r.rename(src='zs', dst='ns')) # 重命名某个name
- print(r.move(name='zs', db=2)) # 将某个name移到到指定DB下,前提name存在,否则返回False
- print(r.randomkey()) # 随机获取一个name,不删除
- print(r.type("zs")) # 获取name对应对类型
管道
redis-py默认值执行每次请求都会创建连接池申请连接,和断开连接池一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下,一次pipline是原子性操作
- import redis
- pool = redis.ConnectionPool(host="127.0.0.1", port=6379)
- r = redis.Redis(connection_pool=pool)
- pipe = r.pipeline(transaction=True)
- r.set('name', 'zengchunyun')
- r.set('role', 'master')
- pipe.execute()
发布订阅
创建redis_common.py
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- @author: zengchunyun
- """
- import redis
- class RedisHelper(object):
- def __init__(self):
- self.__conn = redis.Redis(host="127.0.0.1")
- self.chan_pub = 'fm104.5'
- self.chan_sub = 'fm104.5'
- def public(self, msg):
- self.__conn.publish(self.chan_pub, message=msg)
- return True
- def subscribe(self):
- pub = self.__conn.pubsub()
- pub.subscribe(self.chan_sub)
- pub.parse_response()
- return pub
创建发布者redis_pub.py
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- @author: zengchunyun
- """
- from redis_common import RedisHelper
- obj = RedisHelper()
- obj.public('hello') # 发布一条消息到频道fm104.5
创建订阅者redis_sub.py
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- @author: zengchunyun
- """
- from redis_common import RedisHelper
- obj = RedisHelper()
- redis_sub = obj.subscribe()
- while True:
- msg = redis_sub.parse_response() # 此时一直阻塞状态,直到能接收到数据,
- print(msg)
更多信息参考
https://github.com/andymccurdy/redis-py/
http://doc.redisfans.com/
python 之redis的更多相关文章
- python之redis和memcache操作
Redis 教程 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据 ...
- Python—操作redis
Python操作redis 连接方式:点击 1.String 操作 redis中的String在在内存中按照一个name对应一个value来存储 set() #在Redis中设置值,默认不存在则创建, ...
- python——操作Redis
在使用django的websocket的时候,发现web请求和其他当前的django进程的内存是不共享的,猜测django的机制可能是每来一个web请求,就开启一个进程去与web进行交互,一次来达到利 ...
- 【python】Redis介绍及简单使用
一.redis redis是一个key-value存储系统.和 Memcached类似,它支持存储的value类型相对更多,包括string(字符串). list(链表).set(集合).zset(s ...
- python之 Redis
Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...
- Python操作Redis、Memcache、RabbitMQ、SQLAlchemy
Python操作 Redis.Memcache.RabbitMQ.SQLAlchemy redis介绍:redis是一个开源的,先进的KEY-VALUE存储,它通常被称为数据结构服务器,因为键可以包含 ...
- python之redis
Redis简单介绍 如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构 ...
- python+php+redis+shell实现几台redis的同步数据
之所以使用python,是因为python多线程非常简单. 之所以使用shell,是因为写了个服务,可以方便的重启python写的那个脚本. 总体思路:利用redis的发布订阅,php作为生产者,py ...
- 使用 python 操作 redis
1.安装pyredis (1)使用 # easy_install redis (2)直接编译安装 #wget https://pypi.python.org/packages/source/r/red ...
- Python连接Redis连接配置
1. 测试连接: Python 2.7.8 (default, Oct 20 2014, 15:05:19) [GCC 4.9.1] on linux2 Type "help", ...
随机推荐
- Oracle 【IT实验室】数据库备份与恢复之:如何对Oracle数据库文件进行恢复与备份
任何数据库在长期使用过程中,都会存在一定的安全隐患.对于数据库管理员来说不能仅寄希望于计算机操作系统的安全运行,而是要建立一整套的数据库备份与恢复机制.当数据库发生故障后,希望能重新建立一个完整的数据 ...
- 如何控制Java中的线程,总结了3种方法...
问题:利用Java多线程,轮流打印数字,也就是怎么控制线程.... 1:通过synchronized的关键字,对类的static final 成员进行Lock,锁住对象,来实现同步. private ...
- Objective-C编码规范:26个方面解决iOS开发问题(转)
链接
- wpf window set window的owner
[DllImport("user32.dll")] public static extern IntPtr GetAncestor(IntPtr hWnd, int f ...
- 分享Kali Linux 2016.2第47周镜像
分享Kali Linux 2016.2第47周镜像Kali Linux官方于11月20日发布Kali Linux 2016.2的第47周镜像.这次发布仍然包含11个镜像文件.其中,不仅包含Gnome桌 ...
- 分享Kali Linux 2016.2第46周镜像文件
分享Kali Linux 2016.2第46周镜像文件Kali Linux官网在11月13日发布Kali Linux 2016.2的第46周镜像文件.这次还是保持以往的规模,总共提供了11个镜像文件. ...
- EntityFramework Code First 手写代码实现生成数据库
第一步:写实体类 第二步:写一个实体操作类,此类必须继承Dbcontext,此处的属性,将会在初始化时(第一次作,增,删,改的时候),生成相应的表. 第三步:运行程序,会自动建表 注意: 若实体类发生 ...
- ASP.NET MVC3 中整合 NHibernate3.3、Spring.NET2.0 使用AOP执行事务处理
方法1 <object id="ServiceOperation" type="Spring.Aop.Support.SdkRegularExpressionMet ...
- NOIP201103瑞士轮【B002】
[B002]瑞士轮[B级]出自附中OJ————————————————————————————————————————————————————————————————————————————————— ...
- hive streaming 使用shell脚本
一.HIVE streaming 在Hive中,需要实现Hive中的函数无法实现的功能时,就可以用Streaming来实现.其原理可以理解成:用HQL语句之外的语言,如Python.Shell来实现这 ...