些数据库并不是关系型的,不支持 SQL。它们用来处理庞大的数据集、支持更加灵活的 数据定义以及定制的数据操作。这些被统称为 NoSQL(not only SQL) 。

dbm family

dbm格式是按照键值对的形式储存,封装在应用程序(例如网页浏览器)中,用来维护各种各样的配置。从以下角度看,dbm 数据库和 Python 字典是类似的:

  • 给一个键赋值,自动保存到磁盘中的数据库
  • 通过键得到对应的值

下面看一个小栗子:
open() 方法的第二个参数 'r' 代表读;'w' 代表写;'c' 表示读和写, 如果文件不存在则创建.

  1. In [1]: import dbm
  2. In [2]: db = dbm.open('definitions','c')
  3. 同字典一样创建键值对,给一个键赋值:
  4. In [3]: db['mustartd'] = 'yellow'
  5. In [4]: db['ketchup'] = 'red'
  6. In [5]: db['pesto'] = 'green'
  7. 查看数据库长度,并通过键值获得数据
  8. In [6]: len(db)
  9. Out[6]: 3
  10.  
  11. In [7]: db['mustartd']
  12. Out[7]: b'yellow'
  13. 关掉数据库,然后重新打开验证它是否被完整保存:
  14. In [8]: db.close()
  15.  
  16. In [9]: db = dbm.open('definitions','r')
  17.  
  18. In [10]: db['mustard']
  19. ---------------------------------------------------------------------------
  20. KeyError Traceback (most recent call last)
  21. <ipython-input-10-8228d50ea548> in <module>()
  22. ----> 1 db['mustard']
  23.  
  24. KeyError: 'mustard'
  25.  
  26. In [11]: db['mustartd']
  27. Out[11]: b'yellow'

键和值都以字节保存,因此不能对数据库对象db进行迭代,但是可以使用函数len()得到键的数目。注意哦:get()和setdefault()函数只能用于字典的方法。


memcached

memcached是一种快速的,内存键值对象的缓存服务器。它一般置于数据库之前,用于存储网页服务器会话数据。如果想要使用,需要一个memcached服务器和Python的驱动程序。
这样的驱动程序很多,能够在Python3中使用的是python3-memcached,可以通过命令安装: pip install python-memcached

连接到一个memcached服务器之后,可以做以下事项:

  • 赋值和取值
  • 其中一个值的自增或者自减
  • 删除其中一个键

数据在memcached并不是持久化保存的,后面的可能会覆盖早些写入的数据,这是它的固有特性,因为它作为一个缓存服务器,通过舍弃旧数据避免程序运行时内存不足的问题。

我们可以同事连接到多个memcached服务器,下面的栗子是连接一个:
注意一点哦:在连接之前,一点要确保memcached服务开启。

  1. In [4]: import memcache
  2.  
  3. In [5]: db = memcache.Client(['127.0.0.1:11211'])
  4.  
  5. In [6]: db.set('marco','polo')
  6. Out[6]: True
  7.  
  8. In [7]: db.set('ducks', 0)
  9. Out[7]: True
  10.  
  11. In [8]: db.get('ducks')
  12. Out[8]: 0
  13.  
  14. In [9]: db.incr('ducks',2)
  15. Out[9]: 2
  16.  
  17. In [10]: db.get('ducks')
  18. Out[10]: 2

Redis

Redis是一种数据结构服务器(data structure server)。和memcached类似,Redis服务器的所有数据都是基于内存的(现在也可以把数据放在磁盘)。不同于memcached,Redis可以实现:

  • 存储数据到磁盘,方便断电重启和提升可靠性
  • 保存旧数据
  • 提供多种数据结构,不限于简单字符串

Redis的数据类型和Python很相似,Redis服务器会是一个或多个Python应用程序之间共享数据的非常有帮助的中间件。

Python的Redis驱动程序redis-py可以使用命令安装: pip install redis

Redis 服务器自身就有好用的文档。如果在本地计算机(网络名为 localhost)安装和启动 了 Redis 服务器,就可以开始尝试下面的程序。

1.字符串

具有单一值的一个键被称作Redis的字符串。简单的Python数据类型可以自动转换成Redis字符串。现在连接到一些主机(默认localhost)以及端口(默认6379)上的服务器:
同样在连接之前,一点要确保memcached服务开启

  1. In [1]: import redis
  2. In [2]: conn = redis.Redis()
  3. redis.Redis(‘localhost’) 或者 redis.Redis('localhost', 6379) 会得到同样的结果。
  4.  
  5. 列出所有的键(目前为空):
  6. In [3]: conn.keys('*')
  7. Out[3]: []
  8.  
  9. 给键 'secret' 赋值一个字符串;给键 'carats' 赋一个整数;给键 'fever' 赋一个浮点数:
  10.  
  11. In [4]: conn.set('secret', 'ni!')
  12. Out[4]: True
  13.  
  14. In [5]: conn.set('carats', 24)
  15. Out[5]: True
  16.  
  17. In [6]: conn.set('fever', '101.5')
  18. Out[6]: True
  19.  
  20. 通过键反过来得到对应的值:
  21.  
  22. In [7]: conn.get('secret')
  23. Out[7]: b'ni!'
  24.  
  25. In [8]:
  26.  
  27. In [8]: conn.get('carats')
  28. Out[8]: b'24'
  29.  
  30. In [9]: conn.get('fever')
  31. Out[9]: b'101.5'
  32.  
  33. 这里的 setnx() 方法只有当键不存在时才设定值:
  34.  
  35. In [10]: conn.setnx('secret', 'icky-icky-icky-ptang-zoop-boing!')
  36. Out[10]: False
  37.  
  38. 方法运行失败,因为之前已经定义了 'secret'
  39. In [11]: conn.get('fever')
  40. Out[11]: b'101.5'
  41.  
  42. In [12]: conn.get('secret')
  43. Out[12]: b'ni!'
  44.  
  45. 方法 getset() 会返回旧的值,同时赋新的值:
  46. In [13]: conn.getset('secret', 'icky-icky-icky-ptang-zoop-boing!')
  47. Out[13]: b'ni!'
  48.  
  49. In [14]: conn.get('secret')
  50. Out[14]: b'icky-icky-icky-ptang-zoop-boing!'
  51.  
  52. 使用函数 getrange() 得到子串(偏移量 offset0 代表开始,-1 代表结束):
  53. In [15]: conn.getrange('secret',-6,-1)
  54. Out[15]: b'boing!'
  55.  
  56. 使用函数 setrange() 替换子串(从开始位置偏移):
  57. In [16]: conn.setrange('secret',0,'ICKY')
  58. Out[16]: 32
  59.  
  60. In [17]: conn.get('secret')
  61. Out[17]: b'ICKY-icky-icky-ptang-zoop-boing!'
  62.  
  63. 接下来使用函数 mset() 一次设置多个键值:
  64. In [18]: conn.mset({'pie':'cherry','cordial':'sherry'})
  65. Out[18]: True
  66.  
  67. 使用函数 mget() 一次取到多个键的值:
  68. In [19]: conn.mget(['pie','fever'])
  69. Out[19]: [b'cherry', b'101.5']
  70.  
  71. 使用函数 delete() 删掉一个键:
  72. In [20]: conn.delete('fever')
  73. Out[20]: 1
  74.  
  75. 使用函数 incr() 或者 incrbyfloat() 增加值,函数 decr() 减少值:
  76. In [21]: conn.incr('carats')
  77. Out[21]: 25
  78.  
  79. In [22]: conn.incr('carats', 10)
  80. Out[22]: 35
  81.  
  82. In [23]: conn.decr('carats')
  83. Out[23]: 34
  84.  
  85. In [24]: conn.decr('carats', 15)
  86. Out[24]: 19
  87.  
  88. In [25]: conn.set('fever', '101.5')
  89. Out[25]: True
  90.  
  91. In [26]: conn.incrbyfloat('fever')
  92. Out[26]: 102.5
  93.  
  94. In [27]: conn.incrbyfloat('fever', 0.5)
  95. Out[27]: 103.0
  96.  
  97. 不存在函数 decrbyfloat(),可以用增加负数代替:
  98. In [28]: conn.incrbyfloat('fever', -2.0)
  99. Out[28]: 101.0

2.列表

Redis的列表仅能包含字符串。当第一次插入数据的时列表被创建。使用函数lpush()在开始处插入:

  1. In [1]: import redis
  2. In [2]: conn = redis.Redis()
  3.  
  4. In [3]: conn.lpush('zoo','bear')
  5. Out[3]: 1
  6.  
  7. 在开始处插入超过一项:
  8. In [4]: conn.lpush('zoo', 'alligator', 'duck')
  9. Out[4]: 3
  10.  
  11. 使用 linsert() 函数在一个值的前或者后插入:
  12. In [5]: conn.linsert('zoo', 'before', 'bear', 'beaver')
  13. Out[5]: 4
  14.  
  15. In [6]: conn.linsert('zoo', 'after', 'bear', 'cassowary')
  16. Out[6]: 5
  17.  
  18. 使用 lset() 函数在偏移量处插入(列表必须已经存在),但是会将原来偏移量的值覆盖:
  19. In [7]: conn.lset('zoo',2,'marmoset')
  20. Out[7]: True
  21.  
  22. 使用 lrange() 函数取到给定偏移量范围(0~-1 代表全部)的所有值:
  23. In [8]: conn.lrange('zoo',0,-1)
  24. Out[8]: [b'duck', b'alligator', b'marmoset', b'bear', b'cassowary']
  25.  
  26. 使用 rpush() 函数在结尾处插入:
  27. In [9]: conn.rpush('zoo', 'yak')
  28. Out[9]: 6
  29.  
  30. 使用 lindex() 函数取到给定偏移量处的值:
  31. In [10]: conn.lindex('zoo', 3)
  32. Out[10]: b'bear'
  33.  
  34. In [11]: conn.lrange('zoo', 0, 2)
  35. Out[11]: [b'duck', b'alligator', b'marmoset']
  36.  
  37. 使用 ltrim() 函数仅保留列表中给定范围的值(截取):
  38. In [12]: conn.ltrim('zoo', 1, 4)
  39. Out[12]: True
  40.  
  41. In [13]: conn.lrange('zoo',0,-1)
  42. Out[13]: [b'alligator', b'marmoset', b'bear', b'cassowary']

3.哈希表

Redis的哈希表类似于Python中的字典,但它仅包含字符串,因此只能有一层结构,不能 进行嵌套。下面的例子创建了一个 Redis 的哈希表 song,并对它进行操作。

  1. 使用函数hmset()在哈希表song设置字段do和字段re的值
  2. In [16]: conn.hmset('song',{'do': 'a deer', 're': 'about a deer'})
  3. Out[16]: True
  4.  
  5. 使用函数hset()设置一个单一字段值
  6. In [17]: conn.hset('song', 'mi', 'a note to follow re')
  7. Out[17]: 1
  8.  
  9. 使用函数 hget() 取到一个字段的值:
  10. In [18]: conn.hget('song', 'mi')
  11. Out[18]: b'a note to follow re'
  12.  
  13. 使用函数 hmget() 取到多个字段的值:
  14. In [19]: conn.hmget('song', 're', 'do')
  15. Out[19]: [b'about a deer', b'a deer']
  16.  
  17. 使用函数 hkeys() 取到所有字段的键:
  18. In [20]: conn.hkeys('song')
  19. Out[20]: [b're', b'do', b'mi']
  20.  
  21. 使用函数 hvals() 取到所有字段的值:
  22. In [21]: conn.hvals('song')
  23. Out[21]: [b'about a deer', b'a deer', b'a note to follow re']
  24.  
  25. 使用函数 hlen() 返回字段的总数:
  26. In [22]: conn.hlen('song')
  27. Out[22]: 3
  28.  
  29. 使用函数 hgetall() 取到所有字段的键和值:
  30. In [23]: conn.hgetall('song')
  31. Out[23]: {b'do': b'a deer', b'mi': b'a note to follow re', b're': b'about a deer'}
  32.  
  33. 使用函数 hsetnx() 对字段中不存在的键赋值:
  34. In [24]: conn.hsetnx('song', 'fa', 'a note that rhymes with la')
  35. Out[24]: 1

4.集合

Redis的集合和Python的集合是完全类似的。

  1. 在集合中添加一个或多个值:
  2. In [35]: conn.sadd('zoo1','duck', 'goat', 'turkey')
  3. Out[35]: 3
  4.  
  5. 取得集合中所有值的数目:
  6. In [36]: conn.scard('zoo1')
  7. Out[36]: 3
  8.  
  9. 返回集合中所有值:
  10. In [37]: conn.smembers('zoo1')
  11. Out[37]: {b'duck', b'goat', b'turkey'}
  12.  
  13. 从集合中删掉一个值:
  14. In [38]: conn.srem('zoo1','turkey')
  15. Out[38]: 1
  16.  
  17. 新建一个集合以展示一些集合间的操作:
  18. In [39]: conn.sadd('zoo2','tiger', 'wolf', 'duck')
  19. Out[39]: 3
  20.  
  21. 返回集合zoo1和集合zoo2的交集
  22. In [40]: conn.sinter('zoo1','zoo2')
  23. Out[40]: {b'duck'}
  24.  
  25. 获得集合zoo1和集合zoo2的交集,并存储到新集合zoo3
  26. In [41]: conn.sinterstore('zoo3','zoo1','zoo2')
  27. Out[41]: 1
  28.  
  29. In [42]: conn.smembers('zoo3')
  30. Out[42]: {b'duck'}
  31.  
  32. 返回集合zoo1和集合zoo2的交集
  33. In [43]: conn.sunion('zoo1','zoo2')
  34. Out[43]: {b'duck', b'goat', b'tiger', b'wolf'}
  35.  
  36. 存储并集结果到集合zoo4
  37. In [44]: conn.sunionstore('zoo4','zoo1','zoo2')
  38. Out[44]: 4
  39.  
  40. 使用函数sdiff()得到它们的差集,得到zoo1包含而zoo2不包含的项:
  41. In [45]: conn.sdiff('zoo1','zoo2')
  42. Out[45]: {b'goat'}
  43.  
  44. 将差集存储到集合zoo5
  45. In [46]: conn.sdiffstore('zoo5','zoo1','zoo2')
  46. Out[46]: 1
  47.  
  48. In [47]: conn.smembers('zoo5')
  49. Out[47]: {b'goat'}

有序集合

Redis中功能最强大的数据类型之一是有序表(sorted set或者zset)。里面的值都是独一无二的,但是每一个值都关联对应浮点值分数(score)。可以通过值或者分数取得每一项。
有序集合有很多用途:

  • 排行榜
  • 二级索引
  • 时间序列(把时间戳作为分数)

下面以时间序列作为一个栗子,通过时间戳跟踪用户的登陆。时间表达式使用Unix的epoch值,它有python的time()函数返回:

  1. In [1]: import redis
  2. In [2]: import time
  3. In [3]: conn = redis.Redis()
  4. In [4]: now = time.time()
  5.  
  6. In [5]: now
  7. Out[5]: 1484735598.2283144
  8. 增加第一个访客:
  9. In [6]: conn.zadd('logins', 'smeagol', now)
  10. Out[6]: 1
  11.  
  12. 五分钟后又一个访客:
  13. In [7]: conn.zadd('logins','sauro',now+(5*60))
  14. Out[7]: 1
  15.  
  16. 两小时后:
  17. In [8]: conn.zadd('logins', 'bilbo', now+(2*60*60))
  18. Out[8]: 1
  19.  
  20. 一天后:
  21. In [9]: conn.zadd('logins', 'treebeard', now+(24*60*60))
  22. Out[9]: 1
  23.  
  24. 查看bilbo的登陆次序:
  25. In [10]: conn.zrank('logins','bilbo')
  26. Out[10]: 2
  27.  
  28. 查看登陆时间:
  29. In [11]: conn.zscore('logins','bilbo')
  30. Out[11]: 1484742798.2283144
  31.  
  32. 按照登陆的顺序查看每一个访客:
  33. In [12]: conn.zrange('logins',0,-1)
  34. Out[12]: [b'smeagol', b'sauro', b'bilbo', b'treebeard']
  35.  
  36. 附带上登陆的时间:
  37. In [13]: conn.zrange('logins',0,-1,withscores=True)
  38. Out[13]:
  39. [(b'smeagol', 1484735598.2283144),
  40. (b'sauro', 1484735898.2283144),
  41. (b'bilbo', 1484742798.2283144),
  42. (b'treebeard', 1484821998.2283144)]

6.位图

位图(bit)是一种非常省空间且快速的处理超大集合数字的方式。假设你有一个很多用户 注册的网站,想要跟踪用户的登录频率、在某一天用户的访问量以及同一用户在固定时间 内的访问频率,等等。当然,你可以使用 Redis 集合,但如果使用递增的用户 ID,位图的 方法更加简洁和快速。
首先为每一天创建一个集合(bitset)。为了测试,我们仅使用3天和部分用户ID:

  1. In [14]: days = ['2017-01-18','2017-01-19','2019-01-20']
  2.  
  3. In [15]: big_spender = 1089
  4.  
  5. In [16]: tire_kicker = 40459
  6.  
  7. In [17]: late_joiner = 550212
  8.  
  9. 每一天是一个单独的键,对应的用户ID设置位,例如第一天(2017-01-18)有来自 big_ spender(ID 1089) tire_kicker(ID 40459) 的访问记录:
  10.  
  11. In [18]: conn.setbit(days[0],big_spender, 1)
  12. Out[18]: 0
  13.  
  14. In [19]: conn.setbit(days[0], tire_kicker, 1)
  15. Out[19]: 0
  16.  
  17. 第二天用户 big_spender 又有访问:
  18. In [20]: conn.setbit(days[1], big_spender, 1)
  19. Out[20]: 0
  20.  
  21. 接下来的一天,big_spender 再次访问,并又有新人 late_joiner 访问:
  22. In [21]: conn.setbit(days[2], big_spender, 1)
  23. Out[21]: 0
  24.  
  25. In [22]: conn.setbit(days[2], late_joiner, 1)
  26. Out[22]: 0
  27.  
  28. 现在统计得到这三天的日访客数:
  29. In [23]: for day in days:
  30. ...: conn.bitcount(day)
  31. ...:
  32.  
  33. 判断tire_kicker用户在第二天是否登陆:
  34. In [24]: conn.getbit(day[1],tire_kicker)
  35. Out[24]: 0
  36. 结果为未登录
  37.  
  38. 查看有多少访客每天都访问?
  39. In [25]: conn.bitop('and','everyday',*days)
  40. Out[25]: 68777
  41.  
  42. In [26]: conn.bitcount('everyday')
  43. Out[26]: 1
  44.  
  45. 判断big_spender是不是每一天都登陆:
  46. In [27]: conn.getbit('everyday',big_spender)
  47. Out[27]: 1
  48.  
  49. 查看三天总共有多少人登陆(不算重复项)
  50. In [28]: conn.bitop('or','allday',*days)
  51. Out[28]: 68777
  52.  
  53. In [29]: conn.bitcount('allday')
  54. Out[29]: 3
  55. 7.缓存和过期
  56. 所有的Redis键都有一个生存期或者过期时间(expiration date),默认情况下,生存期是永久的。也可以使用expire()函数构造Redis键的生存期。下面的设置是以秒为单位数的:
  57.  
  58. In [60]: ks = 'now you see '
  59.  
  60. In [61]: conn.set(ks, 'but not for long')
  61. Out[61]: True
  62.  
  63. In [62]: conn.get(ks)
  64. Out[62]: b'but not for long'
  65.  
  66. In [63]: conn.expire(ks, 15)
  67. Out[63]: True
  68.  
  69. In [64]: conn.ttl(ks)
  70. Out[64]: 8
  71.  
  72. In [65]: conn.get(ks)
  73. Out[65]: b'but not for long'
  74.  
  75. In [66]: conn.get(ks)

expireat()命令给一个键设定过期时间,对于更新缓存是有帮助的,并且可以限制登陆会话。


其他的NoSQL

NoSQL 服务器都要处理远超过内存的数据,并且很多服务器要使用多台计算机。下面 列 出了值得注意的服务器和它们的 Python 库。

NoSQL数据库

  1. Site Python API
  2. Cassandrahttp://cassandra.apache.org/) pycassa(https://github.com/pycassa/pycassa)
  3. CouchDBhttp://couchdb.apache.org/) couchdb-python(https://github.com/djc/couchdb-python)
  4. HBasehttp://hbase.apache.org/) happybase(https://github.com/wbolster/happybase)
  5. Kyoto Cabinethttp://fallabs.com/kyotocabinet/) kyotocabinet(http://fallabs.com/kyotocabinet/pythondoc/)
  6. MongoDBhttp://www.mongodb.org/) mongodb(http://api.mongodb.org/python/current/)
  7. Riakhttp://basho.com/riak/) riak-python-client(https://github.com/basho/riak-pythonclient)

转自:https://www.jianshu.com/p/8890dab85e09

NoSQL数据存储的更多相关文章

  1. BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览

    一.引言 时间到了2019年,数据库也发展到了一个新的拐点,有三个明显的趋势: 越来越多的数据库会做云原生(CloudNative),会不断利用新的硬件及云本身的优势打造CloudNative数据库, ...

  2. MySQL 5.7:非结构化数据存储的新选择

    本文转载自:http://www.innomysql.net/article/23959.html (只作转载, 不代表本站和博主同意文中观点或证实文中信息) 工作10余年,没有一个版本能像MySQL ...

  3. NOSQL数据模型和CAP原理

    NOSQL数据模型和CAP原理 http://blog.sina.com.cn/s/blog_7800d9210100t33v.html 我本来一直觉得NoSQL其实很容易理解的,我本身也已经对NoS ...

  4. Atitit 研发体系建立 数据存储与数据知识点体系知识图谱attilax 总结

    Atitit 研发体系建立 数据存储与数据知识点体系知识图谱attilax 总结 分类具体知识点原理规范具体实现(oracle,mysql,mssql是否可以自己实现说明 数据库理论数据库的类型 数据 ...

  5. NoSQL 数据建模技术(转)

    本文转载自:http://coolshell.cn/articles/7270.html ================================================ 全文译自墙外 ...

  6. 基于 HTML5 的数据存储

    以前想做个静态网页APP.最初的思路是用本地文件存储数据,后来发现在手机上运行时,文件无法找到. 经过了长达几个月的搜索(实际也就几天),没有找到合适的方法. 就在绝望的时候,无意间搜到基于HTML5 ...

  7. node.js基础:数据存储

    无服务器的数据存储 内存存储 var http = require('http'); var count = 0; //服务器访问次数存储在内存中 http.createServer(function ...

  8. NoSQL数据建模技术

    原文来自“NoSQL Data Modeling Techniques”,由酷壳网陈皓编译<NoSQL数据建模技术>.这篇文章看完之后,你可能会对NoSQL的数据结构会有些感觉.我的感觉是 ...

  9. Web前端数据存储

    Cookie 会跟随每次请求附加到请求header上,大小限制4k. 部署对象: document.cookie 构成: Key-Value 有效期:根据expires配置 可选项: ;path=pa ...

随机推荐

  1. django 项目运行时media静态文件不能加载问题处理

    一.检查网页中的加载路径 如果路径不正确,首选调整html路径(当然也可以调整文件路径或修改models中upload_to路径,但是不要轻易改): 二.重点: 如果加载路径和实践路径一致,请按以下步 ...

  2. 用pt-stalk定位MySQL短暂的性能问题

    背景] MySQL出现短暂的3-30秒的性能问题,一般的监控工具较难抓到现场,很难准确定位问题原因. 对于这类需求,我们日常的MySQL分析工具都有些不足的地方: 1. 性能监控工具,目前粒度是分钟级 ...

  3. [转]C++中vector使用详细说明

    一.向量的介绍    向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器. 与string相同, vector 同属于STL(Standard Template ...

  4. iOS技术篇:sizeToFit 和 sizeThatFits 区别

    sizeToFit:会计算出最优的 size 而且会改变自己的size UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , ...

  5. 朴素贝叶斯算法--python实现

    朴素贝叶斯算法要理解一下基础:    [朴素:特征条件独立   贝叶斯:基于贝叶斯定理] 1朴素贝叶斯的概念[联合概率分布.先验概率.条件概率**.全概率公式][条件独立性假设.]   极大似然估计 ...

  6. ABP单元测试

    一.介绍 在本文中,我将介绍如何为基于ASP.NET Boilerplate的项目创建单元测试. 我将使用本文开发的相同的应用程序(使用AngularJs,ASP.NET MVC,Web API和En ...

  7. Home Assistant + 树莓派:强大的智能家居系统 · 设备接入篇

    转载:Home Assistant + 树莓派:强大的智能家居系统 · 设备接入篇 目录 HASS 配置框架 主文件设置 Homebridge 设置 鹬蚌相争? 设备追踪设置 更新日志 作者的话 相信 ...

  8. [POI2013]Usuwanka

    [POI2013]Usuwanka 题目大意: 一排\(n\)个球,有黑白两种颜色.每取走一个球会在原位置放一个水晶球.求构造一种取球方案,满足: 每次取走\(k\)个白球和\(1\)个黑球: 一次取 ...

  9. BZOJ4280 : [ONTAK2015]Stumilowy sad

    线段树每个区间维护上下界以及要整体增加的标记即可,时间复杂度$O(m\log n)$. #include<cstdio> #define inf 1500000000 int n,m,op ...

  10. Maven入门指南② :Maven 常用命令,手动创建第一个 Maven 项目

    1.根据 Maven 的约定,我们在D盘根目录手动创建如下目录及文件结构: 2.打开pom.xml文件,添加如下内容: <project xmlns="http://maven.apa ...