MySQL 数据库

终端命令:

vi                                   文本编辑器

cat /etc/password | grep “用户名”  获取user表



sudo -i                              获取root权限


sudo apt-get install python3-pip     安装pip3


sudo pip3 install pymysql            安装mysql


sudo apt-get install mysql-server    安装服务端


sudo apt-get install mysql-client    安装客户端


sudo apt-get update                  读取列表 保存到 /var/lib/apt/lists


sudo apt-get upgrade                 对比下载列表并更新


sudo /etc/init.d/mysql status        查询状态


sudo /etc/init.d/mysql stop          停止服务


sudo /etc/init.d/mysql restart       重启服务


sudo /etc/init.d/mysql reload        重新加载


mysql -h主机地址 -u用户名 -p密码     链接mysql




                      修改mysql默认字符集:


sudo -i                              1.获取root


chmod  644 文件名                    2.修改文件权限


cd etc/mysql/mysql.conf.d            3.进入配置文目录


cp etc/msql.cnf/mysqld.cnf.bak       4.备份


subl mysqld.cnf                      5.vi打开源文件

[mysqld]  目录

character_set_server = utf8          6.添加命令

/etc/init.d/mysql


                                                

mysqldump -u用户 -p源库名 > ~/xxx.sql             数据备份:

                                                       参数:

          --all-databases                                 1.备份所有库

          库名                                            2.备份单个库

          -B 库1 库2..                                    3.备份多个库

          库名 表1 表2...                                 4.备份指定库指定表

 


                                                  数据恢复:


mysql -uroot -p < 目标库名 xxx.sql                       1. 恢复备份库

mysql -uroot -p --one-database 目标库名 < xxx.sql        2. 恢复备份内某一个库

恢复:表不删除 表记录删除覆盖




                                                  MySQL远程连接:

sudo -i                                                 1.管理员模式

cd /etc/mysql/mysql.conf.d/                             2.cd到mysql目录

vi mysqld.cnf                                           3.打开注释掉默认IP

#bind-address = 127.0.0.1                               4.保存

/etc/init.d/mysql restart                               5.重启服务


                                                  授权用户:


grant 授权列表 on 库.表 to “用户名“@”%”identified by “密码” with grant option         1.命令格式

示例:grant all privileges on *.* to "tiger"@"%" identified by "123" with grant option;     2.示例

all privileges、select、insert ...                              4.库.表: *.*  所有库所有表  3.权限列表


                                                  python3模块安装:

模块名 :pymysql 

        在线 :sudo pip3 install pymysql

离线 :pymysql-0.7.11.tar.gz

    $ tar -zxvf pymyql-0.7.11.tar.gz

    $ cd pymysql-0.7.11

    $ sudo python3 setup.py install

        验证:

            $ python3

            >>> import pymysql

            >>> 


                                                  python2模块安装:

模块名 :MySQLdb

安装 :sudo pip install mysql-python



                                                  sqlalchemy 框架 安装:

    在线 :sudo pip3 install sqlalchemy

    离线 :

      $ tar -zxvf SQLAlchemy-1.2.10.tar.gz

      $ cd SQLAlchemy-1.2.10

      $ sudo python3 setup.py install

    验证:

      $ python3

      >>> import sqlalchemy

      >>> 


                                                   pymysql使用:


from pymsql import *                                   导入模块

(db = pymysql.connect(...))                               1、建立数据库连接

c = db.cursor())                                          2、创建游标对象

c.execute("insert ....")                                  3、游标方法: 

db.commit()                                               4、提交到数据库

c.close()                                                 5、关闭游标对象

db.close()                                                6、断开数据库连接 :


                                                          7.connect对象:

db = pymysql.connect(参数列表)

      1、host :主机地址,本地 localhost

      2、port :端口号,默认3306

      3、user :用户名

      4、password :密码

      5、database :库

      6、charset :编码方式,推荐使用 utf8

                                                          8.连接对象的方法:

数据库连接对象(db)的方法

      1、db.close() 关闭连接

      2、db.commit() 提交到数据库执行

      3、db.rollback() 回滚

      4、cur = db.cursor() 返回游标对象,用于执行具体SQL命令

                                                          9.游标对象的方法:

游标对象(cur)的方法

      1、cur.execute(sql命令,[列表]) 执行SQL命令

      2、cur.close() 关闭游标对象

      3、cur.fetchone() 获取查询结果集的第一条数据

                        ((记录1),)

      4、cur.fetchmany(n) 获取n条

                        ((记录1),(记录2))

      5、cur.fetchall() 获取所有记录


  ORM:orm(Object Relation Mapping 对象关系映射) 定义:把对象模型映射到MySQL数据库中



SQL命令:



/var/lib/mysql                                                       MySQL数据目录


show variables like "autocommit";                                    查询commit事务


begin;                                                              开启事务


commit;                                                             提交事务(MySQL默认自动提交)


rollback;                                                           终止事务


system sudo -i                                                       由数据直接进入终端


show databases;                                                     查看已有库


create database 库名;                                               创建库


create database 库名 charcater set utf8;                            指定字符集


show create database 库名;                                          查看库字符集


select database();                                                查看当前所在库


use 库名;                                                           切换库


drop database 库名;                                                 删除库


show tables;                                                        查看已有表


create table 表名(字段名1 数据类型,....);                        创建表


show create table 表名;                                             查看表字符集


desc 表名;                                                          查看表结构


drop table 表名;                                                    删除表


insert into 表名 values(值1),(值2)...;                         插入完整记录


insert into 表名 (字段名1,...) values(值1),...;               插入字段数据


select * from 表名 [where 条件];                                    查询所有字段


select 字段名1,字段名2,...from 表名[where 条件];                  查看字段


alter table 表名 add 字段名 数据类型;                                添加字段


alter table 表名 add 字段名 数据类型 first;                         头插)


alter table 表名 add 字段名 数据类型 after 字段名;                  指定插入)


alter table 表名 drop 字段名;                                       删除字段


alter table 表名 modify 字段名 新数据类型;                          修改数据类型


alter table 表名 rename 表名;                                       表重命名


delete from 表名 where 条件;                                        删除表记录(必须加where)


alter table 表名 change 原名 新名 数据类型;                         字段重命名


 create table 表名 select .. from 表名 where 条件;                   复制表(不复制key)


create table 表名 select * from 表名 where false;                    复制表结构(不复制key)


sex enum(“M”,"F","S") not null defaulf "S"                       约束


show variables like 变量名;                                         查询MySQL变量


select 字段名列表 from 表名列表;                                     (笛卡尔积)


select t1.name,t2.name from t1,t2 where 条件                         多表查询   


create index 索引名 on 表名(字段名);                                 添加普通索引


create table(....index(字段名),...)                             创建表时创建普通索引


drop index 索引名 on 表名;                                          删除普通索引


show index from 表名;                                               查看普通索引


create unique index 索引名 on表名(字段名);                        添加唯一索引


create table 表名( .... , unique key (字段名) );                     创建表时创建唯一索引


drop unique index 索引名 on 表名;                                   删除唯一索引


show unique index from 表名;                                        查看唯一索引


alter table 表名 add primary key(字段名);                         添加主键索引


create table 表名( .... , id int, primary key (字段名) );           创建表时创主键一索引


(id int primary key auto_increment,)auto_increment=10000;            设置自增长起始值


alter table 表名 modify id int auto_increment;                       添加自增长


alter table 表名 auto_increment=20000;                               修改自增长起始值


alter table 表名 modify id int;                                      删除自增长


alter table 表名 drop primary key;                                   删除主键索引


show index from 表名\G;                                              查看表索引


desc 表名;                                                          查看表结构(key)


Non_Unique:1   :index                                              普通索引(查询结果)


Non_Unique:0   :unique                                             唯一索引(查询结果)


alter table 表名 drop foreign key 外键名;                            删除外键


show create table 表名;                                              查看外键名


                                                                     创建外键:

create......t1();

create table t2(

...

...

foreign key(参考字段名)

references 主表(被参考字段名)

on delete 级联动作

on update 级联动作); 

                                                                     添加外键:

alter table 表名 add 

foreign key(参考字段) references 主表(被参考字段)

on delete ...

on update ...

                                                                     级联动作:

restrict(默认)不允许主表操作从表

cascade :跟随删除、更新

set null:主表更改后从表值为NULL


                                                                     内链接:

select 字段名 from表1 

inner join 表2 on 条件

inner join 表3 on 条件...;


                                                                     外链接.左链接:

以左表为主显示查询结果

         select 字段名 from 表1 

         left join 表2 on 条件

         left join 表3 on 条件...;

右链接

        以右表为主显示查询结果



                                                                     数据导入:


load data  infile “文件名”

into table 表名

fields terminated by “分隔符”

lines terminated by “\n”;


                                                                     数据导出:

select ... from 表名

into outfile “/var/lib/mysql-files/文件名”

fields terminated by “分隔符”

lines terminated by “\n”;


                                                                     数据恢复:

恢复单个库

     mysql -uroot -p < 目标库名 xxx.sql

从所有库备份中恢复某一个库(-one-database)

     mysql -uroot -p --one-database 目标库名 < xxx.sql

恢复:表不删除 表记录删除覆盖


                                                                     数据备份:

mysqldump -u用户 -p源库名 > ~/xxx.sql

--all-databases  备份所有库

库名             备份单个库

-B 库1 库2..     备份多个库

库名 表1 表2...  备份指定库指定表



运行时间检测:

   开启:set profiling=1;

   关闭:set profiling=0;

   查询执行记录:show profilings;


update 表名 set 字段1=值1,字段名2=值2,... where 条件               更改表记录:

   如果不加where条件,所有记录全部清空




                      SQL查询:


3.select ... 聚合函数 from 表名

1.where

2.group by...

4.having ...

5.order by ...

6.limit ...;


select ... from 表名 where 条件(select ....);                         查询嵌套:

    2、找出每个国家攻击力最高的英雄的名字和攻击值

       select name,gongji from sanguo

       where 

       (country,gongji) in

       (select country,max(gongji) from sanguo group by country);


where:只能操作表中实际存在的字段

group by:给查询结果进行分组

having:对查询结果进一步筛选

distinct:不显示字段重复值



show engines;                                                        查看所有存储引擎

show create table 表名;                                              查看表的存储引擎

create table 表名(...)engine=myisam;                                 创建表时指定存储引擎

alter table 表名 engine=innodb;                                      添加储存引擎


                                                                     InnoDB:

InnoDB特点(2文件):

      行级锁、支持外键、事务操作

      .frm(表结构,索引)、.ibd(表记录)


MyISAM特点(3文件):                                                MyISAM:

      独享表空间、表级锁

      .frm(结构)、.myd(记录)、.myi(索引)


                                                                     锁:

select :加读锁之后别人不能更改表记录,但可以进行查询

insert、delete、update :加写锁之后别人不能查、不能改

锁粒度:

     表级锁 :myisam

     行级锁 :innodb


                                                                     调优:

1.选择合适的存储引擎

2.常用字段建立索引

3.where 避免使用 !=、NULL判断、or链接、

   like前置%、in、not in、*代替字段、



                        数据类型:



数据类型:


int             大整型(4个字节)  2**32 - 1(4294967295)


tinyint         微小整型(一个字节) 

                有符号(signed默认):-128 ~ 127

                无符号(unsigned):0 ~ 255


smallint        小整型(2字节)

bigint          极大整型(8字节)

float           浮点数(4个字节,7个有效位)

       字段名 float(m,n) m:总位数 n:小数位数

decimal         浮点数(28个有效位)

      字段名 decimal(m,n)m:总位数 n:小数位数

            将9的倍数包装成4个字节

      余数   字节

        0      0

       1-2     1

       3-4     2

       5-6     3

       7-9     4


字段名 enum(值1,值2...);               单选(enum)


字段名 set(值1,值2...);                多选(set)

    (多项放在一个字符串内用,号隔开)


date:“YYYY-MM-DD”

time:“HH:MM:SS”

datetime:“YYYY-MM-DD HH:MM:SS”

timestamp:“YYYY-MM-DD HH:MM:SS”

datetime:不给值默认返回Null

timestamp:不给值默认返回系统时间


时间函数

now()                                                       返回服务器当前的时间

curdate()                                                   返回当前时期

curtime()                                                   返回当前日期

year(date)                                                  返回指定时间的年份

date(date)                                                  返回指定时间的日期

time(date)                                                  返回指定时间的时间

 

聚合函数

avg(字段名):求该字段的平均值

sum(字段名):求和

max(字段名):最大值

min(字段名):最小值

count(字段名):统计该字段的个数



运算符:+ - * / %


时间运算符

select * from 表名

where 字段名 运算符(时间-interval 时间间隔单位);

时间间隔单位:1 day | 2hour | 1 minute | 2year | month


数值比较: =  !=  >  >= < <=

字符比较: =  !=

逻辑比较: and   or

范围内比较:

      1.where 字段名 between 值1 and 值2

      2.where 字段名 in(值1,值2,....)

      3.where 字段名 not in (值1,值2,...)

空:where name is null

非空:where name is not null

NILL:空值,只能用is或is not取匹配

“” : 空字符串,用 = 或  != 去匹配

模糊比较:

     where 字段名 like 表达式

     表达式

        _ : 匹配单个字符

       %:匹配0到多个字符

        NULL不会被统计


排序:order by ASC | DESC

显示: limit 开始显示位置,条数   

     每页显示n条记录,显示第m页:

     limit(m-1)*n,n



           MySQL 与 Python 交互



# frist.py

import pymysql


# 创建数据库对象

db = pymysql.connect(host="localhost", user="root",

                     password="123456", database="db4",

                     charset="utf8")

# 利用db方法创建游标对象

cur = db.cursor()


# 利用游标对象的execute()方法执行SQL命令

cur.execute("insert into sheng values\

             (16,300000,'台湾省');")

# 提交到数据库

db.commit()

# 关闭游标对象

cur.close()

# 断开数据库链接

db.close()



# 增 删 改


import pymysql

# 创建数据库链接

# 链接到db4库

db = pymysql.connect(host="localhost", user="root",

                     password="123456", database="db4",

                     charset="utf8")


# 创建游标

cur = db.cursor()

try:

    # 添加记录

    cur.execute("insert into sheng values (17,168800,'浙江');")

    # 修改记录

    cur.execute("update sheng set id=666 where id=17;")

    # 删除记录

    cur.execute("delete from sheng where s_name='浙江';")

# 截获EXception类型错误

except Exception as e:

    # 出现异常后回滚

    db.rollback()

    # 输出错误

    print("Error ", e)

else:

    # 提交数据

    db.commit()



# 关闭游标

cur.close()

# 断开数据库链接

db.close()



# 查询


import pymysql

# 创建数据库链接

db = pymysql.connect(host="localhost", user="root",

                     password="123456", database="db4",

                     charset="utf8")

# 创建游标

cur = db.cursor()

try:

    # 查找

    cur.execute("select * from sheng;")

    # 取出一条记录就少一条

    print("***************************")

    data1 = cur.fetchone()

    print(data1)

    print("***************************")

    data2 = cur.fetchmany(3)

    for i in data2:

        print(i)

    print("***************************")

    # 遍历取出数据

    data3 = cur.fetchall()

    for x in data3:

        print(x)

    # 提交数据

    db.commit()


except Exception as e:

    db.rollback()

    print("Error ", e)


# 关闭游标

cur.close()

# 断开数据库链接

db.close()



# 参数化


import pymysql

# 创建数据库链接

db = pymysql.connect(host="localhost", user="root",

                     password="123456", database="db4",

                     charset="utf8")

# 创建游标

cur = db.cursor()

try:

    s_id = input("请输入省的编号")

    s_name = input("请输入省的名字")

    # 用占位符参数化数据

    sql_insert = "insert into sheng(s_id,s_name) values(%s,%s)"

    # execute方法 传参必须是列表

    cur.execute(sql_insert, [s_id, s_name])


    # 提交数据

    db.commit()


except Exception as e:

    db.rollback()

    print("Error ", e)


# 关闭游标

cur.close()

# 断开数据库链接

db.close()



                   数据库用户登录




from mysqlpython import Mysqlpython

from hashlib import sha1


uname = input("请输入用户名:")

pwd = input("请输入密码:")

# 用sha1给pwd加密


s1 = sha1()  # 创建sha1加密对象

s1.update(pwd.encode("utf8"))  # 指定编码

pwd2 = s1.hexdigest()  # 返回16进制加密结果


sqlh = Mysqlpython("db4")

select = "select password from user where \

          username=%s;"

result = sqlh.all(select, [uname])

# print(result)

# (('7c4a8d09ca3762af61e59520943dc26494f8941b',),)


if len(result) == 0:

    print("用户名不存在")

elif result[0][0] == pwd2:

    print("登录成功")

else:

    print("密码错误")



                    ORM  sqlalchemy框架


# 创建一张表


# 连接数据库的模块

from sqlalchemy import create_engine

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column, Integer, String


engine = create_engine("mysql+pymysql://root:123456@localhost/db4", encoding="utf8")

Base = declarative_base()  # orm基类


class User(Base):  # 继承Base基类

    __tablename__ = "t123"

    id = Column(Integer, primary_key=True)

    name = Column(String(20))

    address = Column(String(40))


Base.metadata.create_all(engine)





      MongoDB




终端命令:


在线安装:

    sudo apt-get install mongodb

    默认安装路径 :  /var/lib/mongodb

    配置文件 : /etc/mongodb.conf 

    命令集 : /usr/bin   /usr/local/bin

下载解压:

    PATH=$PATH:/opt/mongodb.../bin

    export PATH

    将以上两句写入 /etc/rc.local

备份:

    mongodump -h 主机地址 -d 库名 -o 文件名

恢复:

    mongorestore -h 主机地址: 端口号 -d 库名 文件路径

pymongo 模块安装:

    sudo  pip3 install  pymongo


mongod --port  8080             设置端口(默认27017)

mongo                           进入mongo shell

quit() exit ctrl+c/z/d          退出mongo shell

mongostat                       监测速度  (command 命令次数 flushes IO次数 vsize   虚拟内存)

mongotop                        监测时长 ( ns  数据集合、 total 总时长、 read  读时长 、write 写时长)

mongofiles -d 库名 put 文件      将文件以GridFS方式存入数据库

mongofiles -d 库名 get 文件      将文件从数据库导出




 Mongo命令:


use   库名                            创建/选择库


show dbs                              查询库


db.dropDatabase()                    删除库


db.createCollection(“集合名”)      创建集合


db.集合名.insert(...)                创建集合


show collections                      查询集合


show tables                             查询集合


db.getCollection("集合名")               查询集合所在库


db.集合名.drop()                         删除集合


db.集合名.renameCollion("新集合名")       重命名集合


db.集合名.insert({name:"tom"..})         插入文档


db.集合名.save({name:"tom",...})          插入文档


db.集合名.insert([{}, {}...])           插入多个文档


db.集合名.save([{} {}...])                插入多个文档(加_id键会覆盖原文档)


db.集合名.find(查找条件,域)               查找文档


db.集合名.findOne(查找条件,域)            只显示找到的第一条文档


db.集合名.distinct("集合名")               查看集合内某个域的取值范围


db.集合名.remove(query,justOne)           删除指定条件文档(默认false删除所有)


db.集合名.update(query, update,upert,multi)             修改文档


db.集合名.find().count()                                计数统计查询结果文档的个数


db.集合名.find().pretty()                              将查询结果格式化显示


db.集合名.find().limit(n)                              显示查找结果的前n条结果


db.集合名.find().skip(n)                               跳n过前条显示后面的结果 

        

db.集合名.find().count()                               计数统计查询结果文档的个数


db.集合名.find().sort({filed:1/-1,...})               排序  1:升序, -1:降序,第项相同按照第项二排序


db.集合名.find({'域名.下标':内容{_id:0})                  操作组中的某一项


db.集合名.find({"外域名.内部文档域":内容}, {_id:0})        操作内部文档(Object)的域


db.集合名.ensureIndex({域:1/-1})                         创建索引(1:正向索引  -1:反向)


db.集合名.getIndexes()                                   查看某个集合中的索引


db.集合名.ensureIndex({域:1/-1}},{name:'索引名'})         自定义索引名称


db.集合名.dropIndex(({域:1/-1})                           删除索引

    

db.集合名.dropIndex("索引名")                             删除索引


db.集合名.dropIndexes()                                   删除所有索引(默认_id索引无法删除)


db.集合名.ensureIndex({域名1:1/-1,域名2:1/-1})            创建符合索引 更节省空间


db.集合名.find({'数组.下标':值},{_id:0})                  如果对数组创建索引 查找值也属于索引查找


db.集合名.ensureIndex({域:1/-1},{unique:true})            创建唯一索引


db.集合名.ensureIndex({域:1/-1},{sparse:true})            创建稀疏索引


db.createCollection('集合名',{capped:true,size:10000,max:3}) 创建固定集合


db.集合名.aggregate()                                      聚合操作



比较操作符:

    $eq         等于

    $lt         小于(字符串也可以比较大小)

    $lte        小于等于

    $gt         大于

    $gte        大于等于

    $ne         不等于

    $in         在什么里(in)

    $nin        不在什么里(not in)

逻辑操作符:

    $and        与

        query内如果多个条件用逗号隔开默认就是and关系

    $or         或

    $not        非

    $nor        既不也不

数组操作符:

    $size       只显示指定个size个数的文档]

    $all        查找数组中包含多项的

    $slic       取数组中部分显示,在域(field)中声明


其他query查询:

    $exists     判断一个域是否存在

    $mod        余数查找

    $type       数据类型查找

修改操作符:

    $set        修改一个直 不存在则添加

    $unset      删除一个域

    $rename     修改域名

    $setOnInsert 第三个参数为true作为补充插入数据 否则无用

    $inc        加减修改器可以使整数小数正数负数

    $mul        乘法修改器可以使整数小数正数负数

    $min        设置域的值为上线 超过min修改为min

    $max        设置域的值为下线 小于max修改为max


数组修改符:

    $push       向数组中添加一项

    $pushAll    向数组中添加多项

    $pull       从数组中删除一项

    $pullAll    从数组中删除多项

    $each       对多个值进行逐一操作

    $position   指定插入位置(配合each使用)

    $sort       对数组进行排序(配合each使用)

    $pop        弹出一项(1:弹出第一项 -1:最后一项)

    $addToSet   向数组中添加一项(不允许重复)

时间类型:ISODate()

    nuw Date() 自动生成当前时间

    Date()       获取当前计算机时间格式字符串

    ISODate()    生成当前时间

    ISODate("2018-01-01 12:12:12")      自定义时间

    ISODate("20180101 12:12:12")        自定义时间

    ISODate("20180101")                 自定义时间

    valueOf()    生成时间戳

    null        如果某个域的值不存在可以设置为null



修改参数:

    query:      筛选要查找要修改的文档

    update:     将筛选的文档修改为什么内容需要配合修改操作符

    upsert:     bool值  默认false  如果query的文档不存在则不进行任何操作

                 设置为true 如果query和文档不存在 就根据query和update插入新文档

    multi:      bool值  默认false 如果query文档有多条则只修改第一条

                 设置为true 则修改所有符合条件的文档

常用聚合操作符:

    $group      求和

    $avg        求平局值

    $max        求最小值

    $project    修改文档的显示效果

    $match      过滤想要的数据(同query)

    $limit      显示前几个文档

    $skip       跳过前几个文档显示

    $sort       排序



查找参数:

    query(条件):

        键值对的形式给出要展示的文档

    field(域):

        以键值对对的形式给出要展示或不展示的域

        0为值不显示该域 1为值显示该域

        如果使用0设置某些域不显示默认其他域显示

        如果使用1设置某些域显示默认其他域不显示

        *_id 只有设置为0才不显示否则默认显示

        除_id以外,其他域必须同时设置0或1


索引:

    指建立指定键值及所在文档中存储位置的对照清单

    使用索引可以方便我们进行快速查找,减少数据遍历次数,从而提高查找效率

    覆盖索引:

        查找操作需要获取的域,只有索引域没有其他域。

        此时索引表可以直接提供给用户想要的内容,提高查找效率

    唯一索引:

        创建的索引,索引域值无重复,此时可以创建唯一索引

        唯一索引数据结构更加便于查找

    稀疏索引:

        只针对有指定域的文档创建索引表,如果某个文档没有该域则不会插入到索引表中

    索引约束:

        1. 索引表也需要占用一定的磁盘空间

        2. 当数据发生更新时索引表也要随之更新

    综上 : 

        1. 数据量比较大时更适合创建索引,数据量较小时没有必要付出索引代价

        2. 频繁进行查找操作而不是更新删除插入操作,此时更适合使用索引


固定集合:

    大小固定的集合,称之为固定集合

    插入速度更快,顺序查找更快

    可以控制集合的空间大小

    能够自动淘汰早期数据

    参数:

        capped:true   创建固定集合

        size:10000   固定集合的大小  字节数

        max :1000    表示最多多少条文档


聚合操作:

    对文档的信息进行整理统计的操作

    返回:

        统计后的文档集合

        db.collection.aggregate()

    功能:

        聚合函数,完成聚合操作

    参数:

        聚合条件,配合聚合操作符使用

    返回:

        聚合后的结果


    聚合管道

        将前一个聚合操作产生的结果,交给后一个聚合操作继续使用


文件存储


    1.存储路径

        将文件放在本地路径(网络路径)下,然后数据库中存储该文件的查找路径

        优点 : 

            节省数据库空间

        缺点 : 

            当数据或者文件位置发生变化时文件即丢失


    2. 将文件转换为二进制,存储文件本身

        数据库支持二进制数据格式

        将文件转换为二进制格式,然后存入数据库中

        优点 : 

            数据库和文件绑定,数据库在文件即在

        缺点 : 

            占用数据库空间大,存取效率低

            * 如果是小文件建议转换二进制直接插入

            * 如果是大文件建议使用GridFS方案存储(大于16M)


        GridFS方案解释:

            1. 在mongodb一个数据库中使用两个集合配合存储文件

            2. fs.files 用来存储文件的相关信息,为每一个文件创建一个文档,存储文件名,文件大小,存入时间。。。

            3. fs.chunks 用来分块存储文件的实际内容

                         Binary data 类型数据

            优点 : 存储方便,提供较好的命令支持和编程接口

            缺点 :  存取效率太低 还没有复制的快 

pymongo 模块


    1. 连接数据库,生成数据库连接对象

        conn = pymongo.MongoClient('localhost',27017)


    2. 选择要操作的数据库,生成数据库对象 (__setitem__)

        db = conn.stu

        db = conn['stu']


    3. 获取集合对象

        myset = db.class0

        myset = db['class0']


    4. 通过集合对象调用mongodb数据库操作函数

        增删改查,聚合,索引。。。。。


    5. 关闭数据库连接

           conn.close()



查询练习:


查看班级所人信息

find()


查看年龄大于10岁的学生信息

find({age:{$gt:10}})


查看年龄 8-11 岁之间的学生信息

find({age:{$gt:8,$lt:11}})


找到年龄9岁且为男生的学员

find({age:9,sex:'m'})


找到年龄小于7岁或者大于11岁的学生

find({$or:[{age:{$gt:11}},{age:{$lt:7}}]})


找到年龄8岁或者11岁的学生

find({age:{$in:[8,11]}})


找到有两项兴趣爱好的学生

find({hobby:{$size:2}})


找到喜欢computer的学生

find({hobby:"computer"})


找到既喜欢画画,又喜欢跳舞的学生

find({hobby:{$all:['draw','dance']}})


统计兴趣爱好有3项的学生人数

find({hobby:{$size:3}}).count()


找到本班年龄第二大的学生

find({}).sort({age:-1}).skip(1).limit(1)


查看学生学生兴趣爱好的范围

db.class.distinct('hobby')


找到年龄最小的三个同学

find({}).sort({age:1}).limit(3)


删除虽有年龄小于6岁或者大于12岁的学员

remove({$or:[{age:{$lt:6}},{age:{$gt:12}}]}) 




练习 : 



1.将小红年龄改为8岁,兴趣爱好变为跳舞画画

{$set:{age:8,hobby:['dance','draw']}}


2. 追加小明兴趣爱好 唱歌

{$push:{hobby:'sing'}}


3. 追加小王兴趣爱好,吹牛,打篮球

{$pushAll:{hobby:['吹牛','basketball']}}


4. 小李兴趣多了跑步唱歌,但是要确保不和以前的重复

{$addToSet:{hobby:{$each:['running','sing']}}}


5. 将该班所有同学年龄加1

update({},{$inc:{age:1}},false,ture)


6. 删除小明的sex属性

{$unset:{sex:''}}


7.删除小李兴趣中的第一项

{$pop:{hobby:-1}}


8,删除小红兴趣中的画画和唱歌

{$pullAll:{hobby:['draw','sing']}}


9. 为小红增加一个域,为  score:{english:93,chinese:92,match:78}


{$set:{score:{english:93,chinese:92,match:78}}}


10. 给小红数学成绩加5分

{$inc:{'score.math':5}}


11. 小明的第一爱好改为computer

{$set:{'hobby.0':'computer'}}



聚合练习


使用grade数据库

给更多同学添加 域score

score:{english:87,chinese:76,math:91}


1. 按照性别统计每组人数

aggregate({$group:{_id:'$sex',num:{$sum:1}}})


2. 统计该班中有哪个同学姓名为重名同学

aggregate([{$group:{_id:'$name',num:{$sum:1}}},{$match:{num:{$gt:1}}}])


3. 统计所有男生的语文成绩,只打印姓名,性别,语文成绩即可

aggregate([{$match:{sex:'m'}},{$project:{_id:0,name:1,sex:1,'score.chinese':1}}])


4. 将所有女生按照英语成绩降序排序

aggregate([{$match:{sex:'w'}},{$sort:{'score.english':-1}}])




                             网络编程



Linux下文件类型:

    bcd -lsp

         b(块、设备文件)

         c(字符设备文件)

         d(目录)

         -(普通文件)

         l(链接文件)

         s(套接字文件)

         p(管道文件)

    kill -sig pid:通过pid发送信号杀死指定进程

    kill -l:查看操作系统内所所有sig信号

    信号:

        SIGHUP   断开链接

    SIGINT   Ctrl + c

    SIGQUIT  Ctrl + \

    SIGTSTP  Ctrl + z

    SIGKILL  终止进程且不能被处理

    SIGSTOP  暂停进程且不能被处理

    SIGALRM  时钟信号

    SIGCHLD  子进程改变状态时父进程会收到此信号



OSI七层模型 -----> 网络通信的标准化流程


    应用层: 提供用户服务,具体的内容由特定的程序规定

    表示层: 提供数据的加密和压缩优化

    会话层: 确定建立应用链接,选择传输服务

    传输层: 提供数据传输服务,进行流量控制

    网络层: 路由选着,网络互联

    链路层: 提供链路交换,具体消息的发送

    物理层: 物理硬件,接口,网卡的规定

网络协议:

应用层:TFTP(文件传输)、HTTP(超文本传输协议)、DNS(域名解析)、SMTP(邮件传输)

传输层:TCP、UDP

网络层:IP

物理层:IEEE

IP地址

本地使用:127.0.0.1 或 “localhost”

网络地址:“0.0.0.0” 或 “172.168.40.53”

IPv4: 点分十进制   例如:192.168.1.3   取值0~255(32位)

IPv6: 128位



socket模块:

    ifconfig:查看本机IP (ens33:本地IP  lo:本地回还)

    ipconfig:windoes中

    socket.gethostname() :                获取本机主机名

    socket.gethostbyname('tedu') :        利用主机名获取ip

    socket.gethostbyname('localhost'):    获取本地ip

    socket.gethostbyaddr('127.0.0.1')      访问主机IP地址

    socket.inet_aton('192.168.1.2')        IP十六进制转换

    socket.inet_ntoa(b'\xc0\xa8\x01\02')  IP十进制转换

    socket.getservbyname('ssh')            获取应用程序的端口

创建TCP服务端套接字:

sockfd.socket(sock_family = AF_INET,

               sock_tpye = SOCK_STREAM,

               proto = 0)

    sockfd.bind(addr)      绑定地址

    sockfd.listen(n)          设置监听套接字

  connfd,addr = sockfd.accept() 等待接受客户端链接

  data = connfd.recv(buffersize) 接收消息

  connfd.send(data) 发送消息

  sockfd.close() 关闭套接字

创建TCP客户端套接字:

sockfd.socket(sock_family = AF_INET,

               sock_tpye = SOCK_STREAM,

               proto = 0)

    sockfd.bind(addr)      绑定地址

  sockfd.connect(addr) 链接服务端

  data = connfd.recv(buffersize) 接收消息

  connfd.send(data) 发送消息

  sockfd.close() 关闭套接字



创建UDP客户端套接字:

  sockfd.socket(sock_family = AF_INET,

               sock_tpye = SOCK_DGRAM,

               proto = 0)

    sockfd.bind(addr)      绑定地址

  data = sockfd.recvfrom(buffersize) 接收消息

  sockfd.sendto(data, addr) 发送消息

  sockfd.close() 关闭套接字

创建UDP客户端套接字:

  sockfd.socket(sock_family = AF_INET,

               sock_tpye = SOCK_DGRAM,

               proto = 0)

  data = sockfd.recvfrom(buffersize) 接收消息

  sockfd.sendto(data, addr) 发送消息

  sockfd.close() 关闭套接字


创建本地套接字服务端:

  sockfd = socket(AF_UNIX, SOCK_STREAM) 创建本地套接字对象

  sockfd.bind(file) 绑定套接字文件

  sockfd.listen(3) 监听

  connfd,addr = sockfd.accept() 等待链接

  connfd.recv(buffersize) 接收消息

  connfd.send(data) 发送消息

  sockfd.close() 关闭套接字

创建本地套接字客户端:

  sockfd = socket(AF_UNIX, SOCK_STREAM) 创建本地套接字对象

  sockfd.connect(sock_file) 链接服务端

  connfd.recv(buffersize) 接收消息

  connfd.send(data) 发送消息

  sockfd.close() 关闭套接字




套接字属性:

  sockfd.type 返回套接字类型

  sockfd.family 返回地址类型

套接字方法:

  sockfd.fileno() 获取套接字的文件描述符

  sockfd.getsockname() 获取套结字绑定的地址

  sockfd.getpeername() 获取链接套接字客户端的地址

  sockfd.setsockopt(level,optname, value) 设置端口可立即重用

  sockfd.setblocking(False) 将套接字设置为非阻塞状态

  sockfd.settimeout(sec) 设置套接字的超时时间


select模块: IO多路复用,阻塞等待监控的IO事件发生

rs, ws, xs = select(rlist, 等待处理的IO

  wlist 想要主动处理的IO

  xlist[, 出错希望去处理的IO

  timeout]) 超时检测

p = select.poll 创建poll对象

p.register(s, POLLIN | PLLERR) 注册关注的IO

events = p.poll() 监控关注的IO事件


multiprocessing模块: 创建进程对象

Process(target, 要绑定的函数

name, 给进程起的名称

args, 元组给target函数位置传参

kwargs) 字典给target函数键值传参

p.start() 启动进程terget绑定函数

p.join([timeout]) 阻塞等待子进程退出

p.name                        获取进程名(属性)

p.daemon 设置为True主进程结束杀死所有子进程(必须start()前设置)

p.is_alive() 判断进程是处于alive状态(存活)

p.pid 获取创建进程的pid号(属性)


pool = pool(x) 创建进程池对象(进程池大小)

pool.apply_async(fun, 要执行的函数(异步执行)

args, 以元组形式为fun传参

kwds) 以字典形式为fun传参

pool.apply(fun, args, kwds) (同步执行)

r = pool.map(fun,range(6)) 将要执行的事件放入进程池

pool.close() 关闭进程池

pool.join() 回收进程池


fd1,fd2 = Pipe(duplex=True) 创建管道(Flase:fd1只读,fd2只写)

fd.recv() 从管道读取信息空则阻塞

fd.send(data) 向管道写入内容满则阻塞


q = Queue(maxsize=0) 创建队列对象(存放多少条消息)

q.put(data, 存入消息(支持Python数据类型)

   [block, 默认阻塞 False:非阻塞

   timeout]) block为True是表示超时检测

data = q.get([block,timeout]) 取出消息

q.full() 判断队列是否为满

q.empty()    判断队列是否为空

q.qsize()    获取队列中消息的数量

q.close()    关闭队列


shm = Value(ctype, 创建共享内存共享空间

obj) ctype字符串:(C语言数据类型),obj初始数据

shm.value 表示共享内存的值(可以赋值)

shm = Array(ctype,obj) 创建共享内存共享空间


sem = Semaphore(num) 创建信号量

sem.acquire() 将信号量减1  0时阻塞

sem.release() 将信号量加1

sem.get_value() 获取当前信号量的值(数量)


e = Event() 创建Event事件对象

e.wait([timeout]) 阻塞进程 直到事件对象被set

e.set.() 让事件对象变为被设置状态

e.clear() 使事件对象清除设置状态

e.is_set() 判断当前事件是否被set


Lock = Lock() 创建锁对象

lock.acquire() 上锁

lock.release() 解锁


threading 模块: 创建线程对象

threshold.Thread(target, 线程函数

  name, 线程名字

  args, 元组给线程函数位置传参

  kwargs) 字典给线程函数位置传参

t.start() 启动线程

t.join()  回收线程

t.name 线程名

t.daemon = True 主线程退出分支线程也退出

t.setDaemon(True) 主线程退出分支线程也退出

t.isDaemon 查看daemon值

t.setName(“name”) 设置线程名称

t.is_alive() 查看线程状态

threading.currentThread() 获取当前进程对象


e = threading.Event() 创建Event事件对象

e.wait([timeout]) 事件阻塞

e.set() 设置事件

e.clear()     清除事件


lock = threading.Lock() 创建锁对象

lock.acquire() 上锁

lock.release() 解锁



socketserver集成并发模块:

StreamRequestHandler    处理tcp请求

DatagramRequestHandler  处理udp请求


ForkingMixIn    创建多进程

ThreadingMixIn  创建多线程

 

TCPServer  创建tcp  server

UDPServer  创建udp  server


ForkingTCPServer      ForkingMixIn  +  TCPServer 

ForkingUDPServer      ForkingMixIn  +  UDPServer 

ThreadingTCPServer    ThreadingMixIn  +  TCPServer 

ThreadingUDPServer    ThreadingMixIn  +  UDPServer 




signal模块:

signal.alarm(sec) 设置时钟信号给自己SIGALRM信号

signal.pause() 阻塞进程,等待一个信号

signal.signal(sig, 要处理的信号

   handler) 处理方法(SIG_DFL:默认 SIG_IGN:忽略 func:自定义函数)



sys模块补充:

    sys.argv 获取从命令行获取的参数内容列表

    sys.stdin    0 标准输入IO文件描述符

    sys.stdout   1 标准输出IO文件描述符

    sys.stderr   2 错误IO文件描述符

    sys.exit([status])                        退出一个进程(状态:退出提示字符串)

字符串方法补充:

    S.splitlines  按行分隔


os模块补充:

os.path.exists(file) 判断一个文件是否存在

os.remove(file) 删除文件

os.unlink(file) 删除文件

pid = os.fork() 创建进程 失败-1 成功0

os.getpid() 获取进程的PID号

os.getppid() 获取父进程的PID

os.exit(status) 退出一个进程(状态:整数 默认0)

pid,status = os.wait() 塞等待处理子进程的退出

os.WEXITSTATUS(status) 获取原来退出状态

pid,status = os.waitpid(pid,option) 阻塞等待处理子进程的退出

os.path.getsize('./1.txt')                  读取文件的大小

os.kill(pid,sig) 发送一个信号给某个进程

os.listdir(path) 获取指定目录文件列表

os.path.isfile()  判断一个 文件是否为普通文件

os.path.isdir()  判断一个文件是否为目录 



传输层服务:

    面向连接的传输服务(tcp协议):

        传输特征:

          可靠的数据传输:

            可靠性:无失序、无差错、无重复、无丢失、无重复

        在数据传输前和传输后需要建立连接和断开链接

          面向传输服务建立连接的过程:‘三次握手’

            1.客户端向服务器发送链接请求

            2.服务器接受到请求进行确认,返回确认报文

            3.客户端收到服务器回复最终确认链接

          面向传输服务断开链接的过程:‘四次挥手’

            1.主动方发送报文,告知被动方要断开链接

    2.被动方回复报文,表示已经接受到请求,准备断开

    3.被动方再次发送报文,表示准备处理就绪,可以断开

    4.主动方发送确认报文,断开链接

        应用情况:

    适用于传输较大的内容或文件,网络良好,

    需要保证传输可靠性的情况

    e.g.  信息聊天,文件上传下载,邮件,网页获取


    面向无连接的传输服务(udp协议):

        不保证传输的可靠性

没有建立连接和断开的过程

数据的收发比较自由

适用情况: 

    网络情况较差,对可靠性要求不高,收发消息的两端

    e.g.:网络视频,群聊,广播等



收发函数特性:

     recv特征:

       如果建立的另一端链接被断开, 则recv立即返回空字符串

       recv是从接受缓冲区取出内容,当缓冲区为空则阻塞

       recv如果一次接受不完缓冲区的内容,下次执行会自动接受

     send特征:

        如果发送的另一端不存在则会产生pipe...异常

send是从发送缓冲区发送内容当缓冲区为满则堵塞



http协议:

   超文本传输协议

   用途:

      网站中浏览区器网页的获取,基于网站事物数据传输

      编写基于http协议的数据传输

   特点:

      1.应用层协议,传输层使用tcp服务

      2.简单、灵活,可以使用多种编程语言操作

      3.无状态的协议,既不用记录用户的输入内容

      4.http1.1  ---> http2.0(还没发布)  技术的成熟和稳定性

   http请求(request):

      1.请求格式:

         1)请求行:说明具体的请求类别和内容

          GET    /index.html    /HTTP/1.1

                请求类别   请求内容    协议版本

     2)请求类别:

        GET:获取网络资源

POST:提交一定的附加数据

HEAD:获取相应头

PUT:更新服务器资源

DELETE:删除服务器资源

CONNECT:未使用

TRACE:用于测试

OPTIONS:获取服务器性能信息

2.请求头:对请求的具体描述

     Accept:text/html

        每一个键值对占一行,描述了一个特定信息

3.空行

4.请求体:具体的参数或提交的内容

          get参数或者post提交的内容

   http响应(response):

      1.响应格式:

        1)响应行:反馈具体的响应情况

          HTTP/1.1     20       OK

  版本协议   响应码   附加信息

    3)响应码:

       1xx:提示信息,表示请求已经接收

       2xx:响应成功

       3xx:响应需要定向

       4xx:客户端错误

       5xx:服务器端错误

3)常见响应码:

   200  成功

   404  请求内容不存在

   401  没有访问权限

   500  服务器未知错误

       503  服务器暂时无法执行

      2.响应头:对响应内容的具体描述

      3.空行

      4.响应体:

         将客户端请求内容进行返回



IO多路复用

    定义:

通过一个监测,可以同时监控多个IO事件的行为,

当那个IO可以执行,让这个IO事件发生

同时监控多个IO事件,当哪个IO事件准备就绪就执行哪个IO事件

此时形成多个IO时间都可以操作的现象,不必逐个等待执行

IO准备就绪:

IO事件即将发生时的临界状态是不可逆转的

在程序中存在的IO事件中选择要监测的事件

创建监测,将监测的IO事件注册

等待监测的IO事件发生,判断是什么事件

处理相应的IO


poll方法实现IO多路复用:

   1.创建poll对象:

       p = select.poll

   2.注册关注的IO:

       p.register(s, POLLIN | PLLERR)

       不关注:

          p.unregister(s)

       事件类别:

          POLLIN  POLLOUT  POLLERR  POLLHUP   POLLPRI

          rlist    wlist    xlist     断开   紧急处理 

   3.监控IO:

       events = p.poll()

       功能:监控关注的IO事件

       返回值:

           返回发生IO事件

   events是一个列表[(fileno, evnet), (), ()....]

   每个就绪IO对应一个元组(描述符,就绪事件)

       IO地图:{s.fileno():s}

   4.处理IO事件


位运算:

   按照二进制位进行位运算操作

   & 按为与   |按位或   ^按位异或


   << 左异    >>右移


   11  1011

   14  1110


   &   1010  有0得0

   |   1111  有1得1

   ^   0101  相同为0不同为1

  

   11 << 2  == 44   右侧补零(乘2乘2次)

   14 >> 2  == 3    挤掉右侧的数字(地板除2除2次)

使用:

    1.在低层硬件时操作寄存器

    2.做标志位的过滤




多任务编程:

    意义:

充分利用计算机资源,同时运行多个任务,

提高程序整体的运行效率

    定义:

通过程序利用计算机的多个核心达到同时执行多个任务的目的

因此达到提升程序运行效率的目的

    实施方案:

多进程编程

多线程编程

    并行:

        多个计算机核心在同时处理多个任务,

这时多个任务之间是并行关系

     并发:

        同时运行多个任务,内核在多个任务之间的不断切换,

达到多个任务都会执行的处理效果

此时多个任务之间的并发关系


程序:

    是一个可执行文件,是静态的,只占有磁盘

    不占用计算机运行资源

进程:

    程序在计算机中的一次执行过程

    是一个动态过程,占有一定的计算机资源

    有一定的生命周期

注:

    同一个程序不同的运行过程是不同的进程,

    因为分配的资源和生命周期都不同


进程的创建过程:

    1.用户启动一个程序,或是调用接口发起进程创建

    2.操作系统接收用户请求分配计算机资源创建进程

    3.操作系统将一定状态的进程提供给用户使用

    4.用户利用操作提供的进程完成任务


CPU时间片:

    如果有个进程占有CPU此时我们称为该进程占有CPU的时间片

    多个进程任务或轮流占有CPU时间片并形成并发效果

  

进程信息(process)

    PCB(进程控制块):

         进程创建后 会自动在内存中产生一个空间存放进程信息

    进程信息:

        进程ID 进程占有内存的位置  创建时间、创建位置

查看系统进程信息:ps -aux

    PID(process ID):

      在操作系统中每个进程都有唯一的PID值是由系统分配的

进特征:

    进程是操作系统分配资源的最小单元

    每个进程拥有自己独立的运行空间(4个G的虚拟内存空间)

    进程之间相互独立各不影响

进程的状态:

    三态:

    就绪状态:

         进程具备执行条件,等待系统分配处理器资源进入运行态

    运行态:

         进程占有CPU处于运行状态

    等待态:

         进程暂时不具备运行条件,需要阻塞等待


    五态:

         在三态的基础上增加新建和终止态 

新建:

   创建一个新的程序,获取系统资源的过程

终止:

   进程执行结束,释放资源的过程


ps -aux ---> STAT表示进程状态:

    D  等待态  阻塞  不可中断等待态

    S  等待态  睡眠  可中断等待态

    T  等待态  暂停  暂停执行

    R  运行态(就绪态)

    Z  僵尸

      +  前台进程(在终端运行)

      <  有较高优先级的进程

      N  较低优先级的进程

      s  回话组

      l  有进程链接

进程的优先级:

    top 查看进程运行态优先级

    取值范围:-20~19   -20最高

    nice:

       以指定的优先级运行一个程序

       nice -9 ./hello.py  以9的优先级运行

       sudo nice --9 ./hello.py 以-9优先级运行


    首行添加 #! /usr/bin/python3  指定执行器

      执行:./hello.py

    修改程序权限添加可执行权限

         chmod 775 hello.py


孤儿进程 : 

当父进程先于子进程退出,此时子进程就会成为孤儿进程。

    * 孤儿进程会被系统指定进程收养,即系统进程会成为孤儿

      进程新的父进程。系统进程会自动处理孤儿进程退出状态


僵尸进程 : 

子进程先于父进程退出,父进程没有处理子进程的退出状态,此时子进程就会成为僵尸进程

* 僵尸进程会滞留部分PCB信息在内存中,大量的僵尸进

  程会消耗系统的内存资源,所以要尽量避免僵尸进程产生


如何避免僵尸进程产生

* 父进程先退出

* 父进程处理子进程退出状态

* 创建二级子进程


进程池技术:

    产生原因:

    如果有大量的任务需要多进程完成,而调用周期比较短且需要频繁创建

此时可能产生大量进程频繁创建销毁的情况  消耗计算机资源较大

    使用方法:

    1.创建进程池,在池内放入适当数量的进程

2.将事件封装成函数。放入到进程池

3.事件不断运行,直到所有放入进程池事件运行完成

4.关闭进程池,回收进程

同步互斥机制

    目的:

       解决对共有资源产生的资源争夺

    临界资源:

         多个进程或线程都可以操作的资源

    临界区:

        操作临界资源的代码段

    同步:

    同步是一种合作关系,为完成某个任务,

多进程或者多个线程之间形成的一种协调

按照约定执行,相互告知,共同完成任务

    互斥:

    互斥是一种制约关系,当一个进程或者线程

进入临界区操作资源时采用上锁的方式,

阻止其他进程操作,直到解锁后才能让出资源

多线程:

    什么是线程(thread)?

      线程也是一种多任务编程方式,可以使用计算机的多核资源

      线程被称为轻量级的进程

    线程的特征:

      1.一个进程可以包含多个线程

      2.线程是计算机内核使用的最小单位

      3.线程也是一个运行过程,也要消耗计算机资源

      4.多个线程共享共用进程的资源

      5.线程也有自己的特征属性,TID、指令集、线程栈

      6.多个线程之间独立运行互不干扰 空间不独立(都消耗进程空间)

      7.线程的创建删除消耗的资源要小于进程 线程/进程(1/20)

线程通信:

         多个线程共用线程空间,所以进程的全局变量对进程内线程均可见

         线程的通信方法就是使用去全局变量通信

    注:

         线程间使用全局变量进程通信时,全局变量为共享资源

         往往需要同步互斥机制




进程和线程的区别和联系:

    1.两者都是多任务编程的方式  都能够使用计算机的多核

    2.进程的创建和删除要比线程消耗更多的计算机资源

    3.进程空间独立,数据安全性好,有专门的进程间的通信方法

    4.线程使用全局变量,更加简单,但需要同步互斥操作

    5.一个进程可以包含多个线程,线程共享进程空间资源

    6.进程线程都独立执行,有自己的特有属性


使用情况:

    1.一个进程中并发任务比较多,比较简单,适合使用多线程

    2.如果数据程序比较复杂,特别是可能多个任务通信比较多的时候

      要考虑使用线程同步互斥的复杂性

    3.多个任务存在明显差异,和功能分离的时候没有必要一定写入到一个进程中

    4.使用Python要考虑到GIL的问题



Pyhthon线程GIL问题:

    GIL (全局解释器锁)

    Python --->支持线程操作--->出现IO同步互斥--->加锁--->超级锁,给解释器加锁

    后果:

        同一时刻一个解释器只解释一个线程 

        此时其他线程需要等待。大大降低了Python线程的执行效率

        只能实现并发不能实现并行


Python GIL问题解决方案:

    1.修改c解释器

    2.尽量使用多进程进行并行操作

    3.Python线程尽量用在高延迟多阻塞的IO情形

    3.不使用CPython   使用C#、JAVA 做的得解释器



网络服务器基础:

    循环服务器::

        单进程程序,循环接受客户请求,处理请求,处理完毕后再接受下一次请求

        特点:

            每次只能处理一个客户端请求,如果客户端长期占有服务器则无法处理其他客户端

            请求

        优点:

            实现简单,占用资源少

        缺点:

            无法同时处理多个客户端,体验差

        使用情况:

            任务短暂,可以快速完成,udp比tcp更适合循环

    并发服务器:

        能够同时处理多个客户端任务请求

        IO并发:

            IO多路复用 协程

            优点:

                可以实现IO并发操作,占用系统资源少

            缺点:

                不能够监控CPU密集的情况,并不能有长期阻塞

        多进程/线程并发:

            为每个客户端单独提供一个进程或线程,处理客户端请求

            优点:

                客户端可以长期占有服务器

            缺点:

                消耗计算机资源比较多


 正则基础





正则表达式元字符:

 1.  普通字符匹配 :


        (除了后续讲解的特殊字符全是普通字符)

        可以用普通字符来匹配对应的字符


 2.  或:

 元字符:  |


        匹配规则: 匹配符号两侧的正则表达式均可


 3. 匹配单个字符:

 元字符: .


        匹配规则: 匹配除 \n 外任意一个字符


 4. 匹配开始位置:

 元字符:  ^


        匹配规则: 匹配目标字符串的开头位置


  5. 匹配结束位置:

 元字符 : $


        匹配规则: 匹配目标字符串的结束位置


  6. 匹配重复:

 元字符 : *


        匹配规则: 匹配前面出现的正则表达式0次或多次


 7. 匹配重复:

 元字符 :  +


        匹配规则: 匹配前面出现的正则表达式1次或多次


   8. 匹配重复:

  元字符 : ?


        匹配规则: 匹配前面出现的正则表达式0次或1次


 9. 匹配重复:

  元字符: {n}


        匹配规则: 匹配前面的正则出现n次



  10. 匹配重复:

 元字符 :  {m,n}


        匹配规则 : 匹配前面的正则m-n次



 11. 匹配字符集合:

 元字符: [字符集]

        匹配规则: 匹配字符集中任意一个字符



   12.  匹配字符集:

 元字符:  [^...]


        匹配规则:匹配除了中括号中字符集字符之外的任意一个字符


 13. 匹配任意(非)数字字符:

 元字符 : \d   \D


        匹配规则: \d 匹配任意一个数字字符     [0-9]

                            \D 匹配任意一个非数字字符   [^0-9]



     14. 匹配任意(非)普通字符 :

        (数字字母下划线 普通utf-8字符)

  元字符 : \w   \W


        匹配规则: \w  匹配一个普通字符

                            \W  匹配一个非普通字符



    15.  匹配(非)空字符:

        (空格, \r  \n  \t  \v  \f)

 元字符:  \s   \S


        匹配规则:  \s  匹配任意空字符

                           \S  匹配任意非空字符


    16.  匹配起止位置:

 元字符:  \A   \Z


        匹配规则:  \A  匹配字符串开头位置   ^

                    \Z  匹配字符串结尾位置   $


        完全匹配 : 使用一个正则表达式可以匹配目标字符串的全部内容



 17.  匹配(非)单词边界:

        (普通字符和非普通字符的交接位置认为是单词边界)

 元字符 : \b  \B


        匹配规则 :  \b  匹配单词边界位置

                              \B  匹配非单词边界位置


re模块的使用:

regex = re.compile(pattern,flags = 0)

        功能 : 

            生成正则表达式对象

        参数 : 

            pattern     正则表达式

            flags  功能标志位,丰富正则表达式的匹配

        返回值: 

            返回一个正则表达式对象


 re.findall(pattern,string,flags = 0)

        功能 : 

            根据正则表达式匹配目标字串内容

        参数 : 

            pattern     正则表达式

            string      目标字符串

        返回值: 

            列表 里面是匹配到的内容

            如果正则表达式有子组,则只返回子组中的内容


   regex.findall(string,pos,endpos)

        功能 : 

            根据正则表达式匹配目标字串内容

        参数 :  

            string      目标字符串

            pos,endpos : 截取目标字符串的起止位置进行匹              配,默认是整个字符串

        返回值: 

            列表 里面是匹配到的内容

            如果正则表达式有子组,则只返回子组中的内容


 re.split(pattern,string,flags = 0)

        功能 : 

            通过正则表达式切割目标字符串

        参数 : 

            pattern     正则

            string      目标字串

        返回值 : 

            以列表形式返回切割后的内容


 re.sub(pattern,replace,string,max,flags)

        功能: 

            替换正则表达式匹配内容

        参数: 

            pattern     正则

            replace     要替换的内容

            string      目标字符串

            max         设定最多替换几处

        返回值 : 

            替换后的字符串


    re.subn(pattern,replace,string,max,flags)

        功能和参数同sub

        返回值多一个实际替换了几处


    re.finditer(pattern,string,flags)

        功能: 

            使用正则匹配目标字串

        参数:  

            pattern     正则

            string      目标字串

        返回值: 

            迭代对象 ----》 迭代内容为match对象


    re.fullmatch(pattern,string,flags)

        功能 : 

            完全匹配一个字符串

        参数:  

            pattern     正则

            string      目标字串

        返回值:

            match对象,匹配到的内容


    re.match(pattern,string,flags)

        功能 : 

            匹配一个字符串起始内容

        参数:  

            pattern     正则

            string      目标字串

        返回值:

            match对象,匹配到的内容


    re.search(pattern,string,flags)

        功能 : 

            匹配第一个符合条件的字符串

        参数:  

            pattern     正则

            string      目标字串

        返回值:

            match对象,匹配到的内容



 regex 对象的属性

        flags           标志位数值

        pattern         正则表达式

        groups          子组个数

        groupindex      获取捕获组字典,键为组名值是第几组



  match对象属性:

        match.string        表示目标字符串的开始位置

        match.pos           表示目标字符串的结束位置

        match.re            表示对象生成正则表达式

        match.endpos        目标字符串

        match.lastindex     最后一个分组是第几组

        match.lastgroup     最后一组的名称(捕获)




   match对象方法:

        match.span()        返回匹配到内容的开始结束位置元组

        match.start()       返回匹配到内容的开始位置

        match.end()         返回匹配到内容的结束位置

        match.groups()      返回所有子组匹配到的内容

        match.groupdict()   返回捕获组字典键:捕获名 值:内容

group(n=0)

    功能:

        获取match对象对应的匹配内容

    参数:

        默认为0 表示获取整体的匹配内容

        如果赋值1,2,3。。。表示获取第n个子组匹配到的内容

    返回值:

        返回获取到的内容字串


flags参数:

        re.compile

        re.findall 

        re.search 

        re.match 

        re.finditer 

        re.fullmatch 

        re.split 

        re.sub

        作用:

            辅助正则表达式,扩展丰富的匹配内容、

            regex = re.compile(r"Hello", re.I)  # 忽略字母大小写

            I == IGNORECASE     忽略字母大小写

            S == DOTALL         让元字符 . 能够匹配到\n

            M == MULTILINE      让元字符 ^ $ 能够匹配每一行的开头和结尾

            X == VERBOOS        能够为正则添加注释

        flags传递多个参数时可以用 按位或: | 链接