数据库

NoSQL优点:

  1. 高可扩展性
  2. 分布式计算
  3. 低成本
  4. 架构的灵活性,半结构化数据
  5. 没有复杂的关系

缺点:

  1. 没有标准化
  2. 有限的查询功能
  3. 最终一致是不直观的程序

NoSQL分类:

  1. 列存储:
    顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势
  2. 文档存储:
    文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系散据库的某些功能
  3. Key-value存储:
    可以通过key快速查询到其value,一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能)
  4. 图存储:
    通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据
  5. XML存储:
    高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath
SQL术语 MongoDB术语 解释说明
database database 数据库
table collecion 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接MongoDB不支持
primary key primary key 主键,MongoDB自动将_id设置为主键

文档:
{name:“张三”,age:20,hobby:{“看书”,“旅游”,“唱歌”}}

注意:

  1. 文档中的键/值对是有序的
  2. 文档的键必须是字符串

如果将文档类比成数据库中的行,那么集合就可以类比成数据库的表

在mongodb中的集合是无模式的,也就是说集合中存储的文档的结构可以是不同的,比如下面的两个文档可以同时存入到一个集合中:
{“name”:”hyl”}
{“name”:”hyl”,”age”:1}

Type Number String Notes
Double 1 “double” —–
字符串 2 “string” —–
对象 3 “object” —–
数组 4 “array” —–
二进制数据 5 “binData” —–
未定义 6 “undefined” 已过期
ObjectId 7 “objectId” —–
Boolean 8 “bool” —–
日期 9 “date” —–
10 “null” —–
正则表达式 11 “regex” —–
DBPointer 12 “dbPointer” 已过期
JavaScript(代码) 13 “javascript” 此数据类型用于将JavaScript代码存储到文档中
符号 14 “symbol” 已过期
JavaScript(带范围) 15 “javascriptWithScope” —–
32位整数 16 “int” —–
时间戳 17 “timestamp” —–
64位整数 18 “long” —–
Decimal128 19 “decimal” New in version 3.4
Min key -1 “minKey” —–
Max key 127 “maxKey” —–

操作mongoDB数据库

  1. 创建数据库:
    如果数据库不存在则创建数据库,否则切换到指定的数据库

    1
    use 数据库名
  2. 查看所有数据库:

    1
    show dbs

    注意:刚创建的数据库是不能显示的.必须插入数据库才能显示

  3. 查看当前正在使用的数据库

    1
    db

    或:

    1
    db.getName()
  4. 删除数据库:

    1
    db.dropDatabase()
  5. 插入数据

    1
    db.student.insert({name:"hyl",age:18,gender:1,address:"北京"})
  6. 断开连接:

    1
    exit

操作集合

  1. 查看当前数据库下有哪些集合

    1
    show collections
  2. 创建集合

    1
    db.createCollection("集合名")

    或者:
    创建一个空的集合并添加一个文档

    1
    db.集合名.insert(document)
  3. 删除当前数据库中的集合

    1
    db.集合名.drop(document)

操作文档

  1. 插入文件

    • 使用 insert()方法插入文档

      1
      db.集合名.insert(document)

      eg:

      1
      2
      db.student.insert(
      {name:"hyl",age:18,gender:1,address:"北京"})

      如果要插入多条数据:
      注意要添加中括号:

      1
      2
      3
      db.student.insert(
      [{name:"hyl",age:18,gender:1,address:"北京"},
      {name:"dsz",age:15,gender:0,address:"广州"},])
    • 使用save方法插入文档:

      1
      db.集合名.save(文档)

      如果不指定_id字段,save()方法类似于 Insert()方法.如果指定_id字段,则会更新_id字段的数据.

      1
      2
      db.student.save(
      {name:"hyl",age:18,gender:1,address:"北京"})
      1
      2
      3
      db.student.save(
      {_id:ObjectId(5995096201 723fe2a0d8d17"},name:"poi",age:22,gender:7 address:"石家庄",isDelete:e}
      )
  2. 文档更新:

    • udate()方法用于更新已经存在的文档

      1
      2
      3
      4
      5
      6
      7
      8
      9
      db.集合名.update(
      query,
      update,
      {
      upset:<boolean>,
      multi:<boolean>,
      writeConcern:<document>
      }
      )

      参数说明:

      1. query:
        updata的查询条件,类似于sql里的update语句内where后面的内容.
      2. update:
        update的对象和一些更新的操作符($set,​$inc)等
      3. upset:
        可选.如果不存在update的记录,是否当成新数据插入,true为插入,False为不插入(默认False)
      4. multi:
        可选.如果查找到多条数据,是否更新全部数据,否则只更新一条数据(默认False)
      5. writeConcern:
        可选,抛出异常的级别.
 示例:将李雷的年龄更新为25

 
1
db.student.update({name:"lilei"},{$set:{age:25}})
将所有名字是李雷的人年龄更新为25
1
db.student.update({name:"lilei"},{$set:{age:25}},{mutil:true})
  • save()方法通过传入的文档替换已有文档:

    1
    2
    3
    4
    5
    6
    db.集合名.save(
    document,
    {
    writeConcern:<document>
    }
    )
  1. 文档删除

    • 说明:在执行 removel()函数前,先执行find命令来判断执行的条件是否存在是一个良好习惯

      1
      2
      3
      4
      5
      6
      7
      db.集合名.remove(
      query,
      {
      justOne:<boolean>,
      writeConcern:<document>
      }
      )
      1. query:
        可选,删除文档的条件
      2. justOne:
        可选,如果为tureen或1,则只删除一个文档
      3. writeConcern:
        可选,抛出异常的级别.
    • eg:删除名字为tom的学生

      1
      2
      3
      db.student.remove({name:"tom"})

      db.student.remove({name:"tom"},{justOne:"true"})
  2. 文档查询:

    • find()方法:

      1
      2
      3
      4
      // 查询集合下所有的文档
      db.集合名.find()

      db.student.find()
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      // 查询指定列
      db.集合名.find(
      query,
      {
      <key>:1,
      <key>:1
      }
      )

      // 查看年龄为18的所有人的姓名,性别:
      db.student.find({age:18},{name:1,age:1})

      query:查询条件
      key:要显示的字段,1表示显示

    • pretty()方法以格式化的方式来显示文档

      1
      bd.student.find().pretty()
    • findOne():方法查询匹配结果哦第一条数据

      1
      db.student.findOne({gender:0})
  3. 查询条件操作符:

    • $gt,$gte,$lt,$lte:大于,大于等于,小于,小于等于.

      1
      2
      3
      4
      db.集合名.find(<key>:{$gt:<value>})

      // 查询年龄大于20的学生
      db.student.find({age:{$gt:20}})
      1
      2
      // 查询年龄大于20,小于40的学生
      db.student.find({age:{$gte:20,$lte:40}})
    • 等于使用冒号:

      1
      db.student.findOne({gender:0})
    • 使用id进行查询:

      1
      db.student.find({"_id":ObjectId("59995084b019723fe2a0d8d14")})
    • id查询某个结果集的数据条数

      1
      db.student.find().count()
    • 查询某个字段的值当中是否包含另一个值

      1
      2
      // 查询名字包含yl的学生
      db.student.find({name:/yl/})
    • ObjectId()查询某个字段的值是否以另一个值开头

      1
      2
      // 查询名字以h开头的学生
      db.student.find({name:/^h/})
  4. and,or:

    1
    2
    3
    db.集合名.find(条件1,条件2,条件3....)

    db.student.find({age:{$gt:16},gender:0})
    1
    2
    3
    4
    5
    db.集合名.find({
    $or:[{条件1},{条件2},{条件3}....]
    })

    db.student.find({$or:[{age:{$gt:16}},{gender:0}]})
    1
    2
    3
    4
    5
    db.集合名.find({
    条件1,
    条件2,
    $or:[{条件3},{条件4}]
    })
  5. limit,skip:

    • limit():读取指定数量的数据记录

      1
      db.student.find().limit(2)
    • skip():跳过指定数量的数据

      1
      2
      // 跳过前三条
      db.student.find().skip(3)
    • limit与skip联合使用:
      实现分页功能

      1
      db.student.find().skip(3).limit(2)
  6. 排序:

    1
    db.集合名.find().sort(<key>:1|-1)

    1表示升序,-1表示降序

    1
    db.student.find().sort(age:1)

Redis

终端运行redis:
进入目录,执行redis-cli.exe

  1. redis是key-vaue的数据,所以每个数据都是一个键值对
  2. 键的类型是字符串
  3. 值的类型分为五种:
    • 字符串string
    • 哈希hash
    • 列表list
    • 集合set
    • 有序集合zset
  4. 数据操作的全部命令http://redis.cn/commands.html

字符串string

String是 redis最基本的类型,最大能存储512M的数据.
string类型是二进制安全的,即可以存储任何数据、比如数字,图片、序列化对象等

  1. 设置

    • 设置键值:
      set key value

      1
      set a_key "a_value"
    • 设置值键值及过期时间,以秒为单位
      setex key seconds value

      1
      setex a_key 10 "a_value"
    • 设置多个键值:

      1
      mset key1 value1 key2 value2 key3 value3
  2. 获取:

    • 根据键获取值,如果将不存在者None
      get key
    • 根据多个键获取多个值
      get key1 key2 key3…
  3. 运算

    • 要求:值是字符串类型的数字

    • 将key对应的值加1/减1:

      1
      2
      incr key1
      decr key2
    • 将key对应的值加n/减n:

      1
      2
      incrby key intnum
      decrby key intnum
  4. 其他

    • 追加值(比如给字符串最后加一个标点符号)
      append key value
    • 获取值长度
      strlen key

key

  1. 查找键:
    keys pattern
    (注意:pattern支持正则)

    1
    2
    # 查找全部
    keys *
  2. 判断键是否存在,如果存在返回1,不存在返回0:
    exsits key

  3. 查看键对应的value类型:
    type key

  4. 删除键及对应的值

    del key1 key2 key3…

  5. 设置过期时间(以秒为单位):
    expire key seconds

  6. 查看有效时间(以秒为单位):
    ttl key

哈希hash

  1. 用于存储对象

    1
    {name:"tom",age:18}
  2. 设置:

    • 设置单个值:
      hset key field value

      1
      2
      hset student1 name hyl
      hset student1 age 18
    • 设置多个值:
      hmset key filed1 value1 filed2 value2…

      1
      hmset student1 name hyl age 18
  3. 获取:

    • 获取一个属性的值:
      hget key filed

      1
      hget student1 name
    • 获取多个属性的值:

      1
      hmget student1 name age gander
    • 获取所有属性和值:

      1
      hgetall student1
    • 获取所有的属性:

      1
      hkeys student1
    • 获取所有的值:

      1
      hvals student1
    • 返回包含属性的个数:

      1
      hlen student1
  4. 其他:

    • 判断属性是否存在:

      1
      hexists student1 name
    • 删除属性及值

      1
      2
      3
      hdel key field1 field2...

      hdel student1 name gender
    • 获取指定field的长度:

      1
      hstrlen student1 age

列表list

  1. 概述:
    列表的元素类型为 string,按照插入顺序排序,在列表的头部或尾部添加元素.
    其实就是一个双向队列.

  2. 设置:

    • 在头部插入:

      1
      2
      3
      lpush key value1 value2....

      lpush students hyl
    • 在尾部插入:

      1
      rpush key value
    • 在一个元素的前|后插入新元素:

      1
      linsert key before|after pivot value
      1
      2
      # 在students对应的列表中,在hyl元素的后面添加一个dsl
      linsert students after hyl dsl
    • 设置指定索引的元素值:

      1
      lset key index value
      1
      2
      # 在students对应的列表中,将索引值为2的元素的值改为40
      lset students 2 40
  3. 获取:

    • 弹出key对应的list的第一个元素.

      1
      lpop key
    • 弹出key对应的list的最后一个元素.

      1
      rpop key

      注意:索引值可以是负数,表示偏移量是从另外一边开始

    • 返回存储在key的列表中的指定范围的元素:

      1
      lrange key start end
      1
      2
      # 弹出index0-2的元素
      lrange students 0 2
      1
      2
      # 弹出全部的元素
      lrange students 0 -1
  4. 其他:

    • 裁剪列表:改为原集合的一个子集

      1
      ltrim key start end

      注意包含上下限:
      eg:ltrim students 0 1:获取前两个元素

    • 返回list长度

      1
      llen key
    • 返回列表中索引对应的值

      1
      2
      3
      4
      lindex key index

      # 获取students对应的列表中索引值为20的元素
      lindex students 20

集合set

  1. 无序集合,==元素类型为string类型==.

  2. 设置:

    • 添加元素

      1
      2
      3
      4
      sadd key menber1 menber2... 

      # 添加一个集合,集合元素为hyl,gzr,dsz
      sadd students hyl gzr dsz
    • 获取:

      • 返回key集合中所有元素

        1
        2
        3
        4
        smembers key

        # 返回students对应的集合的所有元素
        sadd students
      • 返回集合元素个数:

        1
        2
        3
        scard key

        scard students
  3. 其他:

    • 交集:

      1
      sinter key1 key2 key3...
    • 差集

      1
      sdiff key1 key2 key3...
    • 合集

      1
      sunion key1 key2 key3...
    • 判断元素是否在集合中

      1
      sismumber key member

有序集合zset

  1. 有序集合,元素类型为 Sting,元素具有唯一性,不能重复
    每个元素都会关联一个double类型的 score(表示权重)通过权重进行大小排序,元素的 score可以相同.

  2. 设置:

    • 添加

      1
      zadd key score1 member1 score2 member2...
    • 获取:

    1. 返回指定范围的元素(第几个元素到第几个元素)

      1
      2
      3
      4
      zrange key start end

      # 查看全部的数据
      zrange students 0 -1
    2. 返回元素个数

      1
      zcard key
    3. 返回有序集合key中,score在min和max之间的元素

      1
      zcount key min max
    4. 返回有序集合key中,成员 member的 score值

      1
      2
      3
      4
      zscore key member

      # 查看students中hyl的权重
      zscore students hyl

redis其实一般是用于缓存的.(因为redis的查询速度很快)

  1. 公司使用MySQL存储全部数据,使用redis存储常用数据(比如说账号密码)
  2. 用户登录时,服务器先去redis查询该用户
    • 如果查询成功,那么直接从redis返回数据(不经过MySQL)
    • 如果查询失败,那么再去MySQL里查询数据.
      然后把查询过来的数据存储到Redis里

redis用作存缓