mysql redis mongo + python

1. Mysql 数据库 V3.1

官方文档: https://dev.mysql.com/doc/refman/5.7/en/binary-installation.html

1-1 数据库的基本使用

  • 数据库介绍:关系型数据库

    • 列 — 字段
    • 行 — 记录
    • 唯一标记某个字段 — 主键
  • RDBMS、MySQL介绍

    • RDBMS :Relation Database Management System
      通过表来表示关系型
      oracle:、
      mysql:、
      ms sql server:微软、
      sqlite:轻量级,移动应用

      RDBMS-client <—SQL----> RDBMS-server === 数据库1/数据库1/数据库1

      SQl : 结构化的查询语言;不区分大小写

      • DQL 数据查询语言
      • DML 数据操作语言
      • DCL
      • DDL
      • CCL
    • Mysql 官网

      Sun 公司,斯坦福大学毕业的学生
      特点:

      1. c和c++编写,可以移植
      2. 支持多种操作系统
      3. 为多种语言提供API
      4. 支持多线程,充分利用CPU资源
      5. 优化的SQL查询算法
      6. 提供多语言支持,常见编码GB2312、BIG5、UTF8
      7. 提供TCP/IP、ODBC和JDBC等多种数据库链接途径
      8. 提供用于管理、检查、优化数据库操作的管理工具
      9. 大型的数据库,可以处理拥有上千万条记录的大型数据库
      10. 支持多种存储引擎
      11. mysql 软件采用了双授权政策,它分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择> 12. MYsql 使用标准的SQL数据语言形式
      12. Mysql 是可以定制的,采用了GPL协议,你可以修改源码来开发自己的Mysql系统
      13. 在线 DDL 更改功能
      14. 复制全局事务标识
      15. 复制无奔溃从机
      16. 复制多线程从机
  • MySQL服务器、客户端安装以及使用

    • 服务器:ubuntu 安装
      sudo apt-get install mysql-server
      sudo service mysql start 
      ps ajx|grep mysql / ps -aux|grep "mysql"
      sudo service mysql stop
      sudo service mysql restart
    
    • 配置
      • 配置文件目录:/etc/mysql/mysql.cnf
        include
      • 进入 conf.d 目录,打开 mysql.cnf,发现并没有配置
      • 进入 mysql.conf.d 目录,打开 mysql.cnf,可以看到配置项
      • 主要配置项如下
        bind-address:表示服务器绑定的ip,默认是127.0.0.1
        port:表示端口,默认为3306
        datadir:表示数据库目录,默认为 /var/lib/mysql
        general_log_file:表示普通日志,默认为 /var/log/mysql/mysql.log
        log_error表示错误日志,默认为/var/log/mysql/error.log 
        
    • 客户端
        sudo apt-get install mysql-client
      
        mysql -h127.0.0.1 -uroot -p123456
        
        Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
        
        mysql> select version();
        +------------+
        | version()  |
        +------------+
        | 5.7.32-log |
        +------------+
      
  • 通过navicat操作数据库

    数据库的编码设置成什么,在数据库中创建数据表默认的是数据库的编码

  • 数据类型、约束

    • 数据完整性
      • 一个数据库就是一个完整的业务但愿,可以包含多张表,数据存储在表中
      • 在表中为了更准确的获取数据,保证数据的正确有效,可以在创建表的时候,为表添加一些强制的验证,包括字段的类型和约束
    • 数据类型:够用就行,尽量使用取值范围小的,而不用大的,这样可以更多的节省空间
      • 整数 : int
      • 小数 : decimal
      • 字符串 : varchar/char
      • 日期时间 : date,time,datetime
      • 枚举类型(enum)
      • 特别说明的类型如下:
      - decimal 表示浮点数,如 decimal(5,2)表示共存5位数,小数占2位
      - char表示固定长度的字符串,如char(3),如果填充'ab'时会补一个空格为'ab '
      - varchar表示可变长度的字符串,如varchar(3),如果填充'ab'时会存储'ab'
      - 字符串 text 表示存储大文本,当字符大于4000时推荐使用
      - 对于图片、音频、视频等文件,不存储在数据库中,而是上传到某个服务器上,然后在表中存储这个文件的路径
      
    • 约束
    - 主键 primary key : 物理上存储的顺序
    - 非空 not null: 此字段不允许填写空值
    - 唯一 unique:此字段的值不允许重复
    - 默认 default:当不填写此值时会使用默认值,如果填写时以填写为准
    - 外键 foregin key:对关系字段进行约束,当为关系字段填写值时,会到关联的表中查询此值是否存在,如果存在则填写成功,如果不存在则填写失败并抛出异常
    - 说明:虽然外键约束可以保证数据的有效性,但是在进行数据的crud(增🏠、修改、删除、查询)时,都会降低数据库的性能,所以不推荐使用,那么数据的有效性如何保证?答:可以在逻辑层近行控制
    

    数值类型(常用)

    类型字节大小有符号范围(Signed)无符号范围(UnSigned)

    字符串

    类型字节大小有符号范围(Signed)

    int最大为2145483647,手机号码应该用bigint
    1bit位 1字节=8bit 1k=1024字节 1兆=1024K 1G=1024M 1T=1024G

  • (重点)-数据库的操作

    • 注释 : -- 注释
    • 链接数据库:mysql -uroot -p
    • 退出:ctrl+d / quit / exit
    • 查看所有数据库:show databases;
    • 显示当前数据库时间:select now();
    • 显示当前数据库版本:select version();
    • 数据库操作:
      • show databases;
      • create database dbname [charset=utf8];
      • show create database dbname;
      • drop database dbname;
      • use dbname;
  • (重点)-数据表的操作

    • 数据表
      • desc table_name;
      • show tables;
      • create table student(
        id int unsigned not null auto_increment primary key,
        name varchar(30),
        age tinyint unsigned default 0,
        high decimal(5,2),
        gender enum(“男”,“女”,“中性”,“保密”),
        cls_id int unsigned
        )engine=InnoDB auto_increment=2 default charset=utf8;
        • auto_increment 自增
        • nut null
        • primary key 主键
        • default 默认值
        • create table 表名(字段名 类型 约束[,字段名 类型 约束])
      • show create table 表名字;
      • 修改表
        • 添加字段:alter table 表名 add 列名 类型;
        • 修改字段:alter table 表名 change 原列名 新列名 类型 默认值;
        • 删除字段:alter table 表名 drop 列名;
  • (重重点)-数据的增删改查 curd

    • 插入数据:insert into 数据表 values()[,()];
      insert into student values
      • (0,“小红”,20,“男”,1,“1990-10-01”),
      • (null,“小红1”,20,“男”,1,“1990-10-01”),
      • (default,“小红”,20,“男”,1,“1990-10-01”);
      • 枚举中的下标从 1 开始
      • (0,“小红”,20,“1”,1,“1990-10-01”),
      • (null,“小红1”,20,“2”,1,“1990-10-01”),
      • (default,“小红”,20,“3”,1,“1990-10-01”);
    • 部分插入
      insert into students(name,gender)value(“大桥”,4);
    • 修改数据:update table_name set 列=value1[,列=value,列=value where 条件];
    • 查询:select * from table where xxx;
    • 删除(不轻易使用):delete from table where xxx;
      truncate table table_name;
      alter table add is_delete bit default 0;
  • 物理删除和逻辑删除

1-2 数据库查询

  • 准备工作
mysql> -- 创建一个数据库
mysql> create database python_test charset=utf8;
Query OK, 1 row affected (0.00 sec)

mysql> -- 使用数据库
mysql> use python_test;
Database changed
mysql> select database();
+-------------+
| database()  |
+-------------+
| python_test |
+-------------+
1 row in set (0.00 sec)

mysql> -- 创建一个数据表
mysql> -- students
mysql> create table students(
        id int unsigned auto_increment primary key not null,
        name varchar(30),
        age tinyint unsigned default 0,
        heigh decimal(5,2),
        gender enum("男","女","中性","保密") default "保密",
        cls_id int unsigned default 0,
        is_delete bit default 0
);

mysql> -- classes
mysql> create table classes(
        id int unsigned auto_increment primary key not null,
        name varchar(30) not null
);
mysql> -- 向students表中插入数据
insert into students values
(0,"小明",18,180.00,2,1,0),
(0,"小明2",18,185.00,2,2,0),
(0,"小明3",29,175.00,1,1,0),
(0,"小明4",29,160.00,2,1,0),
(0,"小明5",59,150.00,4,2,1),
(0,"小明6",38,172.00,2,1,0),
(0,"小明7",28,null,2,1,0),
(0,"小明8",18,181.00,1,1,0),
(0,"小明9",36,166.00,1,2,0),
(0,"小明10",27,162.00,2,2,0),
(0,"小明11",25,180.00,3,3,0),
(0,"小明12",33,170.00,1,4,0),
(0,"小明13",34,176.00,2,5,0);
mysql>-- 向class中插入数据
insert into classes values(0,"python_01期"),(0,"python_02期"),(0,"python_04期");
  • 基本的查询
    select * from students;
    select * from classes;
    select id, name from classes;
    select name,age from students;
    select name as “姓名”,age as “年龄” from students;
    select distinct gender from students;
  • 条件查询
    • =/>/</!=[<>]
    • and/or/not
    • like[%/_]/rlike 正则
  • 范围查询、null
    • 非连续的范围:in/not…in…
    • 连续的范围,包含两边的值:between…and…/not between…and…
    • 判断空:is null
  • 排序:默认按照主键排序
    • order by 支持多字段排序;第一个排完后,按照第二个字段,
  • 聚合、分组
    • 聚合函数:count/max/min/avg/sum/round/ group_concat()
    • 分组和聚合一起使用:group by
      mysql> select gender,group_concat(name,"_",age," ","id") from students group by gender;
      +--------+----------------------------------------------------------------------------------------------------+
      | gender | group_concat(name,"_",age,"_","id")                                                                |
      +--------+----------------------------------------------------------------------------------------------------+
      | 男     | 小明3_29_id,小明8_18_id,小明9_36_id,小明12_33_id                                                   |
      | 女     | 小明_18_id,小明2_18_id,小明4_29_id,小明6_38_id,小明7_28_id,小明10_27_id,小明13_34_id               |
      | 中性   | 小明11_25_id                                                                                       |
      | 保密   | 小明5_59_id                                                                                        |
      +--------+----------------------------------------------------------------------------------------------------+
      
      • having : 对分组后的结果进行过滤
      mysql> select gender,group_concat(name,"_",age,"_","id"),avg(age) from students group by gender having avg(age)>30;
      +--------+-------------------------------------+
      | gender | group_concat(name,"_",age,"_","id") |
      +--------+-------------------------------------+
      | 保密   | 小明5_59_id                         |
      +--------+-------------------------------------+
      

      where 对原表的判断;having 对查询结果的筛查;

  • 分页:page 页码,num 每页的个数
    • limit start,end;[(page-1)*num,num]
  • 链接查询
    • 内链接(交集): inner join … on …
    • 左连接(外链): left join … on …
    • 右连接(外链): right join … on … having …
    mysql> select s.*,c.name from students as s left join classes as c on s.cls_id = c.id having c.name is null;
    +----+----------+------+--------+--------+--------+-----------+------+
    | id | name     | age  | heigh  | gender | cls_id | is_delete | name |
    +----+----------+------+--------+--------+--------+-----------+------+
    | 12 | 小明12   |   33 | 170.00 | 男     |      4 |           | NULL |
    | 13 | 小明13   |   34 | 176.00 | 女     |      5 |           | NULL |
    +----+----------+------+--------+--------+--------+-----------+------+
    2 rows in set (0.01 sec)
    
  • 自关联
    • 案例:[一张表解决关联] 省、市、县、乡| 公司部门 |id-name-parent_id
    • 一个表中的一个字段关联另外一个字段
    • select province.atitle,city.atitle from areas as province inner join areas as city on city.pid=province.aid having province.atitle=“山东省”;
  • 子查询-简单[少用比较浪费时间]
    select * from students where height=(select max(height) from students);
  • 数据库设计
    • 数据库设计软件:power designer , db designer
    • 范式 NF
      • 1NF: 每个字段不可拆分
      • 2NF: 必须有主键,主键可以有多个字段组成;其余字段全部依赖主键;
      • 3NF:
    • E-R 模型
      • E表示entry,实体
      • R表示relationship,关系
      • 多对一:在多添加字段
      • 多对多:新加中间表

1-3 Mysql与Python交互

  • mysql-client 客户端的快捷键
    行首:ctrl+a; 行尾:ctrl+e
  • update 里面用两个表关联
    旧: goods:id|name|cate_name|brand_name|is_show|is_saleoff
        goods_cates:id|name
        goods_brands:id|name
    --- goods_cates ---
    create table goods_cates(
       id int unsigned primary key auto_increment,
       name varchar(40) not null
    );
    -- 数据插入
    insert into goods_cates(name) select cate_name as name from goods group by cate_name;
    -- 拆分表并赋值 
    update goods as g inner join goods_cates as c on g.cate_name = c.name set g.cate_name = c.id;
    --  修改表字段和类型
    alter table goods change cate_name cate_id int unsigned not null;
    -- 关联外键:确定相对应列的对比
    alter table goods add foreign key(cate_id) reference goods_cates(`id`);
    
    --- goods_brands ---
    --  注意:在创建表的时候一起插入数据
             需要对brand_name用as起别名,否则name字段就没有值
    create table goods_brands(
      id int unsigned primary key auto_increment,
      name varchar(40) not null select brand_name as name from goods group by brand_name
    );
    
    --- goods ---
    alter table goods
    change cate_name cate_id int unsigned not null,
    change brand_name brand_id int unsigned not null;
    
    alter table goods 
    add foreign key(cate_id) reference goods_cates(`id`),
    add foreign key(brand_id) reference goods_brands(`id`),
    
    alter table goods drop foregin key 外键名称;
    `在实际开发中很少用到外键,因为效率比较低`
    
  • python安装pymsql
    • python2.x MySQLdb
    • python3.x pymysql
    • 安装
      • pip -V
      • 有网: pip3 install pymysql
      • 无网:pip3 install “本地路径”
  • python操作sql:查询数据
    • 流程
      开始--创建connection--获取cursor---[执行查询|执行操作]--关闭cursor--关闭connection--结束
      from pymysql import *
      
      
      def main():
          # 创建 connection
          conn = connect(host='127.0.0.1',port=3306,user='root',password='123456',database='python_test',charset='utf8')
          # 链接 cursor
          cursor = conn.cursor()
          
          cursor.execute("select * from goods;")
          cursor.fetchone() # 返回元组
          cursor.fetchmany()
      
          # 关闭 cursor
          cursor.close()
          conn.close()
      
      if __name__ == "__main__":
          main()
      
      
  • 案例:京东商城-查询|添加|删除|修改数据

    注意:添加|删除|修改数据 必须提交 conn.commit() | conn.rollback()

    from pymysql import connect
    
    
    class JD():
      def __init__(self):
          #链接对象
          self.conn = connect(host='127.0.0.1',port=3306,user='root',password='123456',database='python_test',charset='utf8')
          self.cursor = self.conn.cursor()
    
      def __del__(self): 
          #关闭对象
          self.cursor.close()
          self.conn.close()
    
      def excute_sql(self, sql):
    
      def show_all_items(self):
    
      def show_cates(self):  
    
      def show_brands(self): 
    
      def add_brands(self):
    
      def get_info_by_name(self):
    
      @staticmethod
      def print_num()
            print("----京东----")
            print("所有商品")
            print("所有商品分类")
            print("所有商品分类品牌")
            return input("请输入功能对应的序号:")
            
      def run():
        while True:
          num = self.print_num()
          
          if num == "1":
              self.show_all_items()
          elif num == "2":
              self.show_cates()
          elif num == "3":
              self.show_brands()
          elif num == "4":
              self.add_brands()
          elif num == "5":
              self.get_info_by_name()
          else:
              print("输入有误,重新输入")
    
      def main():
          jd = JD()
          jd.run()
    
    if __name__ == "__main__":
      main()
    
    
  • 添加:防止SQL注入

1-4 Mysql高级

  • 视图 view:虚拟的表
    • 提高了重用性,就像一个函数
    • 对数据库重构,却不影响程序的运行
    • 提高了安全性能,可以对不同用户
    • 让数据更清晰
  • 事务
    start transaction; // -- begin
    select balance from checking where customer_id = 10233276;
    update checking set balance = balance - 200.00 where customer_id = 10233276;
    update saving set balance = balance + 200.00 where customer_id = 10233276;
    commit;
    
    • 四大特性:(简称ACID)
      • 原子性(Atomicity)
      • 一致性(Consistency)
      • 隔离性(isolation)
      • 持久性(durability)
  • 索引

    注意:建立太多索引将会影响插入和更新的速度,因为它同样需要更新每个索引文件

    • 当数据量很大,查询数据会变得很慢?优化方案:索引
    • 是什么? 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),他们包含着对数据表里所有记录的引用指针*;更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度
    • 目的:提高查询效率
    • 原理:树 B-Tree
    -- 开启时间监测
    set profiling = 1; 
    -- 查看执行时间
    show profiles;
    
    -- 索引操作:当数据库创建了,主键和外键时候会相应创建索引
    show index from table_name;
    create index index_name on table_name(colum_name(长度));
    drop index index_name on table_name;
    
  • (了解)账户管理
    • 在生产环境下操作数据库时绝对不可以使用root账户连接,而是创建特定的账户,授予这个账户特定的操作权限,然后连接进行操作,主要的操做就是数据的crud
    • MySQl账户体系:根据账户具有的权限的不同,MySQl的账户可以分为以下几种
      • 服务实例级账号:启动一个mysqld,即为一个数据库实例;如果某用户如root,拥有服务实例级别分配的权限,那么该账号就可以删除所有的数据库,连同数据库中的表
      • 数据库级别账号:对特定数据库进行增删改查的所有操作
      • 数据表级别账号:对特定表执行增删改查所有操作
      • 字段级别的权限:对某些表的特定字段进行操作
      • 存储程序级别的账号:对存储程序进行增删改查的操作
    • 账户的操作主要包括创建账户、删除账户、修改密码、授权权限等

    注意:1.进行账户操作时,需要使用root账户登陆,这个账户拥有最高的实例级权限
    2.通常都是用数据库级操作权限

    -- 创建账户授权
    all privileges
    grant 授权列表 on 数据库 to `用户名`@`访问主机` identified by '密码';
    show grants for `用户名`@`访问主机`;
    
    grant select on jing_dong.* to 'laowang'@'localhost' identified by '123456';
    show grants for laowang@localhost;
    -- 修改
    grant 授权列表 on 数据库 to `用户名`@`访问主机` with grant option;
    flush privileges;
    -- 修改用户密码
    update user set authentication_string=password('新密码') where user='用户名';
    flush privileges;
    -- 删除用户
    drop user `用户名`@`访问主机`;
    flush privileges;
    
    • root 账户密码忘记怎么办!!
  • Mysql 主从
  • 功能
    • 数据备份
    • 读写分离:负载均衡
  • 主从同步的机制
  • 配置主从同步的基本步骤
    1. 在主服务器上,必须开启二进制日志机制和配置一个独立的ID
    2. 在每一个从服务器上,配置一个唯一的ID,创建一个用来专门复制主服务器数据的账号
    3. 在开始复制进程前,在主服务器上记录二进制文件的位置信息
    4. 如果在开始复制之前,数据库中已经有数据,就必须先创建一个数据库快照(可以使用mysqldump导出数据库,或者直接复制数据文件)
    5. 配置从服务器要链接的主服务器的IP地址和登陆授权,二进制日志文件名和位置
  • 详细配置主从同步的方法
    • 步骤一:备份
      mysqldump -u用户名 -p密码 数据库名称>xxx.sql
    • 步骤二:恢复

      注意:链接数据库,需要手动创建新的数据库
      mysql -u用户名 -p密码 数据库名<xxx.sql
      source xxx.sql

    • 步骤三:配置主服务器 master
      sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
      
      server-id = 1
      log_bin   = /var/log/mysql/mysql-bin.log
      
      sudo service mysql restart
      
      
    • 步骤四:配置从服务器 salve
      sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
      
      server-id = 2
      # log_bin   = /var/log/mysql/mysql-bin.log
      
      sudo service mysql restart
      
      
    • 步骤五:在master创建一个 用于从服务器同步数据使用的账号
        mysql -uroot -p
        grant replication slave on *.* to `slave`@`%` identified by 'slave';
        flush privileges;
        show master status; // 赋值到 master_log_file
      
    • 步骤六:
    change master to master_host='',master_user='slave',master_password='slave',master_log_file='',master_log_pos=590;
    
    start slave; # 开启同步状态
    show slave status; # 查看同步状态
    ********************** row ******************
        Slave_IO_Running:Yes
        Slave_SQL_Running:Yes
    

2. redis 数据库

https://github.com/redis/redis
官方文档 https://www.redis.net.cn/tutorial/3505.html

3. MongoDB数据库

官方文档 https://www.mongodb.com/docs/manual/indexes/

介绍

优势: 易扩展;大数据量高性能;灵活的数据模型,高可用
缺点: 数据可能回重复,占用更多的资源

存储的数据类型:
Object ID: 文档ID|保证每个文档的唯一性
(12字节的16进制数
前4字节:当前时间戳;
接下来3字节:机器ID;
接下来2字节:mongodb进程id
最后3字节:简单的增量值)
String:字符串,常用,必须是有效的UTF-8
Boolean:存储一个布尔值,true或者false
Integer
Double
Arrays
Object
Null
Timestamp
Date: new Date(‘2018-01-05’)

安装和启动

安装(-y 默认是yes)
sudo apt-get install -y mongodb-org
其他的安装方式
1.下载压缩包
2.解压缩
tar -zxvf mongodb-linux-x86_64-*****.tgz
3.移动到 /usr/local 目录下
sudo mv -r mongodb-linux-x86_64-*****/ /usr/local/mongodb
4.将可执行文件添加到path 
export PATH=$PATH:/usr/local/mongodb/bin

查看帮助
mongod --help

启动[多方式]
sudo mongod --config /usr/local/mongodb/mongod.conf

启动
sudo service mongod start 

停止
sudo service mongod stop 

重启
sudo service mongod restart 

查看时候启动成功
ps ajx|grep mongod

配置文件位置
/etc/mongod.conf

默认端口 
27017

日志位置
/var/log/mongodb/mongod.log

客户端 mongo

启动本地客户端: mongo
查看帮助: mongo --help
退出: exit 或 ctrl+c

it 翻页

增删改查

注意:数据库 use 时候,自动创建数据库。

查看数据库列表   show dbs/show database;
选择数据库      use dbname;
查看当前数据库   db;
删除数据库      db.dropDatabase()

数据存储在集合里面

不手动创建集合:向不存在集合中第一次加入数据时,集合会被创建出来
手动创建集合
db.createCollection(name,options)
db.createCollection("stu")
db.createCollection("sub",{capped:true,size:10})
 参数capped默认值是False表示不设置上限,值true表示设置上限
 参数size:当capped值为true时,需要指定此参数,表示上线大小,当文档达到上限时,会将之前的数据覆盖,单位为字节

查看集合
show collections
删除集合
db.集合名称.drop()

插入

db.集合名称.insert(document) # _id 存在就会报错!!!

db.集合名称.save(document) # 文档_id存在修改,不存在_id添加

查找
db.集合名称.find()
更新
db.集合名称.update(,,{multi:})
db.集合名称.update({name:“xiaowang”},{$set:{name:“xiaozhang”}})
删除
db.集合名称.remove(,{justOne:true})
justOne:只删除一条的效果

高级查询

  • find() 查询
    db.集合名称.find({条件文档})
  • findOne() 查询一条
    db.集合名称.findOne({条件文档})
  • pretty() 将结果格式化
    db.集合名称.find({条件文档}).pretty()
  • skip limit
    db.集合名称.find().limit(4).skip(5)
    db.集合名称.find().skip(5).limit(4)
  • KaTeX parse error: Expected '}', got 'EOF' at end of input: … db.集合名称.find({where:function(){
    return this.age>30;}
    })
  • 投影:选择返回结果的字段
    db.集合名称.find({},{字段名:1,字段名称:0,…}) # 1字段name返回,0不反回,默认不返回
    默认:对于_id列默认是显示的,如果不显示需要明确设置为0 其他字段不显示默认不写
  • 排序
    db.集合名称.find({}).sort({字段名称:[1|-1]}) 降序 -1;升序:1
  • 统计个数
    db.集合名称.find({条件}).count()
    db.集合名称.count({条件})
  • 消除重复
    db.集合名称.distinct(‘去重字段’,{条件})
关系运算:大小比较("$cmp")、等于("$eq")、大于("$gt")、大于等于("$gte")、小于("$le")、小于等于("$lte")、不等于("$ne")、判断 null ("$ifNull"),这些返回值都是 boolean 值类型的。
逻辑运算:与("$and")、或("$or")、非 ("$not")
字符串操作:连接("$concat")、截取("$substr")、转小写("$toLower")

范围内 $in
或者 $or 
and:  添加多个字段

db.集合名称.find({age:{$gt:23}})

备份恢复

  • 备份
    mongodump -h dbhost -d dbname -o dbdirectory
    -h 服务器地址,也可以指定端口号
    -d 需要备份的数据库名称
    -o 备份的数据库存放位置,此目录中放着备份出来的数据
  • 恢复
    mongorestore -h dbhost -d dbname --dir dbdirectory
    –dir 备份数据所在的位置

聚合命令 aggregate

聚合是基于数据处理的聚合管道,每一个文档通过一个由多个阶段(stage)组成的管道,
可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理、输出相应的结果
db.集合名称.aggregate({管道:{表达式}})

# 常用管道
$group:将集合中的文档分组,可用于统计结果
$match:过滤数据,只输出符合条件的文档
$project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
$sort:将输入文档排序后输出
$limit:限制聚合管道返回的文档数
$skip:跳过指定数量的文档,并返回余下的文档
$unwind:将数组类型的字段进行拆分

#表达式
语法:表达式:'$列名'
$sum:计算总和,$sum:1 表示以一倍计数
$avg:计算平均值
$min:获取最小值
$max:获取最大值
$push:在结果文档中插入值到一个数组中
$first:根据资源文档的排序获取第一个文档数据
$last:根据资源文档的排序获取最后一个文档数据
$group

g r o u p 对应字典中有几个键,结果中就有几个键分组依据需要放 到 i d 里面取不同的字段的值需要使用 , ′ g e n d e r , group 对应字典中有几个键,结果中就有几个键 分组依据需要放到 _id 里面 取不同的字段的值需要使用,'gender, group对应字典中有几个键,结果中就有几个键分组依据需要放id里面取不同的字段的值需要使用gender,age’
取字典嵌套字典中的值的时候$_id.字段
能够按照多个键进行分组 {$group:{_id:{country:'$country',province:'$province'}}}
结果是 {_id:{country:"",province:""}}

  • _id表示分组的依据,使用某个字段的格式为’KaTeX parse error: Expected '}', got 'EOF' at end of input: …合名称.aggregate({group:{
    _id:'KaTeX parse error: Expected '}', got 'EOF' at end of input: …ender', count:{sum:1},
    awg_age:{ a v g : " avg:" avg:"age"}
    }})
  • Group by null
    db.集合名称.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …d:null, count:{sum:1},
    awgAge:{ a v g : " avg:" avg:"age"}
    }})
多字段同时分组

高级语法

sort skip limit

先写 skip 再 limit,效率高一些

unwind

数据 t2 {“username”:“Alex”,“tag”:[‘C#’,‘Java’,‘C++’]}
如何获取tag的长度?
db.t2.aggregate({KaTeX parse error: Expected 'EOF', got '}' at position 24: …sername:'Alex'}}̲,{unwind:‘$tags’})
结果:
{“username”:“Alex”,“tag”:“C#”}
{“username”:“Alex”,“tag”:“Java”}
{“username”:“Alex”,“tag”:“C++”}

注意:
db.t3
{“username”:“Alex”,“tag”:[‘C#’,‘Java’,‘C++’]}
{“username”:“Bom”,“tag”:[]}
{“username”:“Jone”,“tag”:[‘C#’]}

db.inventory.aggregate({
{KaTeX parse error: Expected '}', got 'EOF' at end of input: …nd:{ path:'字段名称’,
preserveNullAndEmptyArrays: #防止丢失数据
}})

索引建立

索引:提升查询速度
分类:
单键索引
多键索引

mongoshell是js的交互环境

测试:插入10万条数据
for(i=0;i<100000;i++;){db.t255.insert({name:'test'+i,age:i})}

db.t1.find({name:'test10000'})
db.t1.find({name:'test10000'}).explain('executionStats')

建立索引之后对比
语法:db.集合.ensureIndex({属性:1}) 1表示升序,-1 降序
具体操作:db.t1.ensureIndex({name:1})
db.t1.find({name:'test10000'}).explain('executionStats')

  • 查看
    db.collection.getIndexes() 该语法命令运行要求是MongoDB 3.0+

  • 创建
    语法:db.collection.createIndex(keys, options)
    db.collection.ensureIndex({“name”:1},{“unique”:true})

  • 删除
    说明:可以移除指定的索引,或移除所有索引
    db.comment.dropIndex({userid:1})
    所有索引的移除
    db.collection.dropIndexes()

  • 分析查询性能
    分析查询性能(Analyze Query Performance)通常使用执行计划(解释计划、Explain Plan)来查看查询的情况,如查询耗费的时间、是
    否基于索引查询等。
    那么,通常,我们想知道,建立的索引是否有效,效果如何,都需要通过执行计划查看。
    语法:db.collection.find(query,options).explain(options)
    db.comment.find({userid:“1003”}).explain()
    关键点看: “stage” : “COLLSCAN”, 表示全集合扫描
    关键点看: “stage” : “IXSCAN” ,基于索引的扫描


mongodb mysql redis 的区别和使用场景

  • mysql是关系数据库,支持事务
  • mongodb,redis是非关系数据库,不支持事务
  • mysql、redis、mongodb 的使用根据如何方便进行选择
    • 希望速度快的时候,用mongodb和redis
    • 数据量过大的时候,频繁使用的数据存入redis、其他的存入mongodb
    • mongodb不用提前建表建数据库,使用方便,字段数量不确定的时候使用mongodb
    • 后续需要用到数据关系的时候,此时考虑mysql

爬虫数据去重,实现增量式爬虫

  • 使用数据库建立关键字段的唯一索引进行去重
  • url地址去重
    • 使用场景
      • url地址对应的数据不会变的情况,url地址能够唯一判别一条数据的情况
    • 思路
      • url数据持久化,存储在redis中,set
      • 拿到url地址,判断在redis的url集合中是否存在
      • 存在:说明已经请求过不在请求
      • 不存在:没有请求过,请求,把URL存在redis的集合中
    • 布隆过滤
      • 使用多个加密算法加密url,得到多个值
      • 往对应值的位置把结果设置为1
      • 新来的一个url,一样通过加密算法生车某个值
      • 如果对应的位置全为1,说明这个url地址已经抓过
      • 否则没有抓过,就把对应位置的值设置为1
  • 根据数据本身进行去重
    • 选择特定的字段,使用加密算法(md5,sha1)将字段进行加密,生成字符串,存入redis集合中
    • 后续新来一条数据,同样的方法进行加密,如果得到的字符串在redis中存在,说明数据存在,对数据进行跟新,否则说明数据不存在,直接插入

python 程序中使用 mongodb

pip install pymongo

from pymongo import MongoClient
class TestMongo(Object):
  def __init__(self):
    client = MongoClient(host=",port=27017) 
    self.collection = client["test"]["t1"] # 使用方括号的形式选择数据库和集合

  def test_insert(self):
    # insert 接收字典、返回object
    ret = self.collection.insert({"name":"xiaoyuan","age":45})
    print(ret)

  def test_insert_many(self):
    item_list = [{"name":"test{}".format(i),"age":10.format(i)} for i in range(10)]
    #  insert_many 接收列表
    t = self.collection.insert_many(item_list)
    for i in t.inserted_ids:
      print(i)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值