day45

 
数据库知识总结:
一,mysql是什么:
 一:为啥使用数据库
  之前使用文件(excel)管理数据的,但是数据量特别大的时候,使用excel管理的話就比较麻烦了,因此需要引入一个新的数据管理软件 :数据库管理系统
  MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司。MySQL 最流行的关系型数据库管理系统,
   在 WEB 应用方面MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
   
  #mysql就是一个基于socket编写的C/S架构的软件
二,数据库的分类:
 1,关系型数据:    就是通过某种关系存储的数据
  特点:     1,有约束
      2,基于硬盘的存储(就是将数据存储在硬盘上,)      持久化===落地
 
  典型代表:
    MySQL oracle(国企)  sqlserver(微软)   sqllist  db2
 
 2,非关系型数据:    就是数据与数据之间没有关系,存储以key和
  特点:  1,没有约束(key==value)
     2,基于内存的存储(将数据放入到内存中)
  典型代表:
    MemCache,redis(微博),MongoDB
三mysql的架构: #mysql就是一个基于socket编写的C/S架构的软件
  客户端:
   socket客户端,连接服务器,发送指令(sql语句)
  服务端;接收客户端的指令,并将结果返还会给客户端
四mysql的安装:
  版本:5.5以上   5.7以下
  1.可执行文件:
   .exe 或者 .msi结尾的文件,点击下一步
  2. 压缩包
   解压,进入目录bin
   mysqld:启动服务
   msyql:连接服务器
  3.添加环境变量的配置
五:初始化:
        mysql initialise -secure
  
  数据库(就相当于======文件夹)
   表(就相当于======文件 )
   数据行(就相当于===== 文件中的一行内容)     记录就是一行内容
  在客户端连接mysql:
   启动数据库(cmd终端中):mysql -u用户名 -p密码 -h(id)地址 -P端口号
   案列: mysql -uroot -p123 -h127.0.0.1 -P3306
   exit; 退出
  在cmd终端中启用服务器:
   1,在cmd终端中以管理员身份打开: net start mysql
          启动成功,会有mysql>字样
      关闭mysql服务器: net stop mysql,
          exit;退出
   2,在cmd对话框中有个服务:打开服务,查找mysql,然后右击 选择启动或关闭或自动
六:数据库的操作:*************************************************************************
 一:数据库
        1,增加:
   sql语句:   create database 数据库名称;
     案例: create database db1;
               查: show databases;        即查看当前的所有库名
    在这里可以提前规定它的字符编码,不规定的是默认编码拉丁码 如果输入中文就会乱码
     create database 数据库名称 charset=utf8;
     案列;  create database db1 charset=utf8;
  2,删除:
   sql语句: drop database 数据库名称;
     案例: drop database db1;
  3,修改:
   没有专门的修改指令删了重新建
  4,查询:
   sql语句:    show databases;     即查看当前的所有库名
               show create database db1;       查看db的创建过程
  5,使用:
      sql语句:    use 数据库名称;    案例: use db1;
 $$$二:数据表
           首先在要在数据库下   (及文件夹下建文件)
   新建表:
    use db;
  1.增加:
   sql语句:   create table 表名(列名1 列类型,列名2 列类型);
    案例:  create table t1(id int,name char(32))
    在这里引入几个固定概念
    1>; auto_increment 自增
    2>; primary key    主键索引
    3>; not null     不能为空    null  为空
    4>; default      默认值
    5>; engine       发动机,引擎
   最终的案列格式:*************************************************
    create table t1(
     id int auto_increment primary key,
     name varchar(32) not null default '',
     gender varchar(32) not null default '',
     age int not null default 0
     )engine=Innodb charset=utf8;
    注意:1,在这里除了int型的默认值不能为空
      2,最后一行不能有逗号
      3,列类型建议使用varshar()
      4,auto_increment 和 primary key  一般情况下是搭配使用,当然也可单独使用,但是不建议
       最终的格式:**********************************
     create table 表名(列名1 列类型[是否为空 默认值],
           列名2 列类型[是否为空 默认值],
           ......
           列名n 列类型[是否为空 默认值]
           )engine=引擎  charset=字符编码
     表名的命名方式与变量名命名一样,不能为关键字重名,不能为重数字和数字开头,以字母数字下划线组成 
     列名的命名: 一张表中不能有重复的列名,列名和列类型不能为空,两者必须有
     在这里有这么几个知识点:1,列类型
             2,引擎
             3,索引
    一列类型:
      1,数值型: tinyint  范围:
         有符号: -128到127
         无符号: 0 到 255  unsigned
          smallint  范围:
         有符号: -32768到32767
         无符号: 0 到 65535  unsigned
          mediumint  范围:
         有符号: -8388608到8388607
         无符号: 0 到 16777215
          int   .......
          bigint   ......       (范围越来越大)
        区别: 就是取值范围不一样,根据自己公司业务需求定  无符号和有符号的区别
         float(M,D)浮点型
         decimal(M,D) 定点型  比float更加精准
          M:小数总共多少位 decimal(5, )
          D:小数点后面几位 decimal(5, 2)
          案列:比如 说存 salary 工资 : 6000.23    即decimal(,2)
      2,字符串型:
        char() : 定长
         特点:速度快,但是浪费空间,资源
        varchar():变长
         特点:速度比char慢,但是节省空间
        text;  文本型
         用于存储大量数据字符,数据较长时使用这个字段
      3,时间型
        data  2019-2-12   推荐使用datatime
  2,删除(表的删除):
    sql语句 :drop table 表名;     将表中所有数据都删除了,慎用
      案列: drop table t1;    
  3,改
                sql语句:    a:修改字段
        alter table 表名 change 原列名 新列名;
        alter table 表名 change 原列名(name) 新列名(username varchar(32) not null default '')
        注意别忘记列类型
       b:新增字段:
        alter table 表名 add 新列名(pwd char(32) not null default '');
       c:删除字段
        alter table 表名 drop 列名;
        案例:alter table t1 drop pwd;
  4,查询**********************
    sql语句: show tables:    查询所有表
       desc table;     查询表结构
       show create table 表名 :  查看表的创建过程
 $$$三,数据行操作
  1,增加 
   sql语句:
    insert into 表名(列名1,列名2) values (值1,值2);
    insert into 表名(列名1,列名2) values (值1,值2),(值1,值2),......,(值n,值n);
    insert into 表名(列名1,列名2) select 列名1, 列名2 from 表名;     ****就是将一个表中数据添加到另一个表中
    案列:
    insert into ddd(name,phone)  select name,phone from ddd;       #增加  有点像复制 
  2,删除
   sql语句:
    drop table 表名;直接删除的是整个表
          
    delete from 表名(t3); 将表中的所有的 数据删除掉, 再次添加的时候, 继续会延续上一个 ID
     
    truncate 表名(t3);    将表中的所有的 数据删除掉, 再次添加的时候, ID 会重新开始
     truncate 速度快 
    
     delete from 表名 where id > 10
     delete from 表名 where id < 10
     delete from 表名 where id <= 10
     delete from 表名 where id >= 10
     delete from 表名 where id != 10
     delete from 表名 where id = 10 and name='xxx';  and : 并且 两个条件都必须要成立
     delete from 表名 where id = 10 or name='xxx';   or :  或者 只要满足一个条件成立
  3,修改:
   sql语句:
    update t3 set username='zekai';
    update t3 set username='xxxx'  where  id=3;
   update t3 set username='xxxx', pwd='xxxxx'  where  id=3;
   复制表结构:
   select * from service where 1=2;
  4,查询:
   sql语句:
 ***** 普通查询
    select * from t1;  查询表所有内容
    select 列名1 列名2 from 表名; 查询某一列的数据
 ***** 高级查询
    
   ****a. where 条件查询:
     select * from 表名 where  id=10;
     select * from 表名 where  id >10 and id<15;
     select * from 表名 where  id > 10;
      != : 不等与    >= <=       
     between and:闭区间
      select * from t1 where id between 9 and 12;
     in:  在某一个集合中
      select * from t1 where id in(9,10,11...);
      select * from t4 where id in (select id from t3 where id between 2 and 4)
     not in :不在
   *** b. 通配符:
        select * from 表名 where 列名 like 'ale%'  - ale开头的所有(多个字符串)
     select * from 表名 where name like 'ale_'  - ale开头的所有(一个字符)
   *** c, 限制取几条:  limit
     select * from 表名 limit 索引偏移量, 取出多少条数据;
     select * from t3 limit 0, 10;  第一页
     select * from t3 limit 10, 10;  第二页
     分页核心SQL:
     select * from t3 limit (page-1)*offset, offset;
   ****d, 排序  order by
     降序:desc
      select * from t4 order by 列名 desc; descending
     升序:asc
      select * from t4 order by 列名 asc;   ascending
   ****e, 分组  group by
     select age, 聚合函数(count(num)/sum(num)/max(num)/min(num)/avg(num)) from 表名 group by 列名;
      
      select age,avg(num) from t5 group by age;
      select age,count(num) from t5 group by age;
      select age,count(num) as ct from group by age;     as为起别名,显示别名
     having :二次删选
      select age, count(num) as cnt from t7 group by age  having cnt>1;    
     where 和 having的区别:
         1). having与where类似,可筛选数据
         2). where针对表中的列发挥作用,查询数据
         3). having针对查询结果中的列发挥作用,二次筛选数据, 和group by配合使用
   ****f, 连表操作:
        1,内连接:inner join   就是显示有对应关系的
     2,左连接: left join    重点
      是将左边表的数据全部显示
      select * from 表名1 left join 表名2 on 表名1.id= 表名2.外键;
      select * from userinfo left join department on userinfo.depart_id=department.id
     3,右连接: right join
      select * from userinfo right join department on userinfo.depart_id=department.id;
      右边的表全部显示, 左边没关联的用null表示
       ps:
         a.只需要记住左连接 left join
         
         b.可以连接多张表 通过某一个特定的条件
   
 四 外键: 
     create table 要建的表名(列名1 列类型[是否为null 默认值],
       列名2 列类型[是否为null 默认值],
       列名3 列类型[是否为null 默认值],
       ......
       constraint 外键名(自定义的名字) foreign key 列名(要建的列名) references 表名(关联的列名)
       )engine=Innodb charset=utf8;
      #constraint 外键名(fff) foreign key (列名(de_if)) references 表名(ggg)(关联的列名)
   案列:
   第一种:create table course(
     cid int auto_increment primary key,
     cname varcher(32) not null default '',
     teacher_id int not null default 1,
     constraint tyy foreign key (teacher_id) references teacher(tid)
     )engine=Innodb charset=utf8;       #关联一个表
   第二种:关联两个表
   create table score(
    sid int auto_increment primary key,
    student_id int not null default 0,
    corse_id int not null default 0,
    number varchar(32) not null default '',
    constraint ttt foreign key (student_id) references student(sid),
    constraint rrr foreign key (corse_id) references course(cid)
    )engine=Innodb charset=utf8;
   #注意;列的类型为int时,默认值不能为空,不能为'',必须有默认值,
     除了int型 其他是字符串类型时,要加双引号
     注意字符串双引号的检查,不要多加或漏掉,  如果出现错误,结束命令不执行命令就用 'c
 五:索引:
   一 主键索引:primary key    不能为空 加速查找 不能重复
     第一种:
      create table t1(
       id int auto_increment primary key,
       name varchar(32) not null default ''
       )engine=Innodb charset=utf8;
     第二种:
      alter table t1 change id id int  auto_increment primary key
   二 唯一索引:
    create table t1(id int,num int,unique(num))engine= Innodb charset=utf8;
     作用:num列的值不能重复     加速查找
     第一种:
      create table t1(
       id int auto_increment primary key,
       name varchar(32) not null default '',
       unique ix_name ('name')
       )engine=Innodb charset=utf8;
     第二种:
      create unique index 索引名称(ix_name) on 表名(t1)(name);
      create unique index 索引名称(ix_name_age) on 表名(t1)(name,age);
      
      案例:
      create table user2host(
       id int auto_increment primary key,
       userid int not null default 0 ,
       hostid int not null default 0,
       unique(userid,hostid),
       constraint pp foreign key (userid) references ddd(id),
       constraint gg foreign key (hostid) references ree(id))engine=Innodb charset=utf8;
     #unique(userid,hostid)  为联合唯一索引,注意它的位置,如果要用唯一索引就在要建唯一索引的列名后面加唯一索引,
   三: 普通索引
     
     第一种:
      create table t1(id int auto_increment primary key,
       name varchar(32) not null default '',
       index ix_name(name))engine=Innodb charset=utf8;
     第二种:
      create index 索引名称(ix_name) on 表名(t1)(name);
   删除:
    drop 索引名称(ix_name) on 表名(t1);
   场景:
    使用频繁的列上加一个索引  
    缺点:就是删除和修改的时候速度变慢了
  索引的使用:
          explain 工具
    explain select name from t1 where id=1;
    查看sql语句是否用的上索引, 或者查看sql执行效率的工具
        - 组合索引最左前缀
         如果组合索引为:(name,email)
         where name and email       -- 使用索引
         where name                 -- 使用索引
         where email                -- 不使用索引
    
  慢日子查询(slow log):
    日志文件:记录了执行速度特别慢的sql语句
    开启步骤:
     1.show variables like '%query%';
     2. set global long_query_time = 1; 设置慢查询的时间
     3.  slow_query_log = ON
     4.  slow_query_log_file  = E:programmysql-5.6.44-winx64dataoldboy-slow.log 日志文件的路径
    普通日志记录(general  log):                即 SQL审计 (记录sql的操作语句)
     show variables like '%general%';
     set global general_log = ON      设置开启普通日志         不建议使用,占内存
 六:引擎
      存储引擎:
     create table t1(
      id int auto_increment primary key,
      name varchar(32) not null default ''
      )engine=Innodb charset=utf8;
    
  分类: (****************)
  Innodb
   1.(默认版本包含5.5)
   2.支持事务
   3.不支持全文索引
   4.索引和数据都是在同一个文件中, .ibd
     表的结构实在.frm文件中
  MyIsam
   1.(默认版本5.5以下 5.3)
   2.不支持事务
   3.支持全文索引
   4..frm: 表结构
     .MYD: 表数据
     .MYI: 表索引
 七:事务************************
   四大特性:
    原子性:一组操作,要么全部成功,要么全部失败
    一致性:操作前和操作后,总的数额是一致的
    隔离性:本次事务的操作对其他事务的操作时没有任何影响的
    持久性:当我们commit/rollback之后,影响就已经生效 补偿性事务来解决
   开启:
    start transaction
    一组sql语句的操作
     完成(commit/rollback)
     ps :
      针对mysql的:
       start transaction
       drop table t1;
       rollback;
      其他的数据库中也是一样的, 但是除了oracle(flashback)
 八:SQLAIchemy****************************
   SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,
   使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果
  ORM 是一种思想 对象关系映射
      安装:在cmd终端输入   pip3 install SQLAIchemy
    SQLAlchemy本身无法操作数据库,其必须以来pymsql等第三方插件,Dialect用于和数据API进行交流,
    根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作
    使用pymysql的前提条件:
     1,表先要建好
     2,需要自己手动写多条sql语句     
     为了改进这两种情况,就需要一种思想:orm 对象关系映射,      目的就是直接在pycham中写入代码 代码传给sqlalchemy,他会将代码转变为sql语句传给服务器,然后服务器将数据传给它,它在反应到pycham中
     改进:**************
     类 ==>表
     实例化 ===>数据
     这种思想叫:ORM(object relationship mapping)对象关系映射
     基于这种思想开发的产品,python比较出名的orm框架:SQLALchemy
     具体作用,通过一个类生成一张表 然后通过实例化这个类的对象,通过这个对象来操作表中的数据
     也就是说通过类对应的是一张表,
     通过实例化对象对应的是表中一行一行的数据
     SQLALchemy的操作:
      基本原理:将代码转换成sql语句
     pip3 install sqlalchemy
     使用SQLALchemy 也是基于pymysql
    首先导入,在cmd终端  输入 pip3 install sqlalchemy
       连接成功后  在pycham中导入模块
      在创建数据库的时候,要想是库中的数据支持中文
      create database db charset=utf8;
    导入模块
    from sqlalchemy.orm import sessionmaker, relationship
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey,UniqueConstraint, Index
    
    建立连接:
    engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/db', max_overflow=5)
     # create_engine(mysql+pymysql://用户名:密码@ip地址:端口号/数据库名,连接池)
    Base = declarative_base()  # 声明一个base类 引入这个declarative_base()    固定用法
 
    # 创建单表
    class User(Base):
     __tablename__ = 'user1'
     id = Column(Integer, autoincrement=True, primary_key=True)
     name = Column(String(32), nullable=False, server_default='')
     extra = Column(String(32))
    
    #    为user1表创建索引:
     __table_args__ = (
      UniqueConstraint('id', 'name', name='ui_id_name'),
      Index('ix_id_name', 'name', 'extra')    注意:这个索引的名字必须放在第一位,然后才是要建立的索引的列名
           ) #UniqueConstraint为唯一索引      在此表中为联合唯一索引
       #Index   为普通索引          为组合索引
    Base.metadata.create_all(engine)        #生成这个表      会将当前执行文件 中所有继承自Base类的类,生成表
 
    # 创建多张表
    class Group(Base):
     __tablename__ = 'group123'
     id = Column(Integer,primary_key=True)     #注意主键索引
     name = Column(String(32), unique=True, nullable=False)
     port = Column(Integer, default=55)     # int不能为空
 
    class Server(Base):
     __tablename__ = 'server'
     id = Column(Integer, primary_key=True, autoincrement=True)    注意主键索引,自增
     hostname = Column(String(64), unique=True, nullable=False)
    
    class ServerToGroup(Base):
     __tablename__ = 'servertogroup'
     nid = Column(Integer, primary_key=True, autoincrement=True)  自增 主键索引
     server_id = Column(Integer, ForeignKey('server.id')) *************外键
     group_id = Column(Integer, ForeignKey('group123.id'))**************外键
 
    def init_db():
     Base.metadata.create_all(engine)     ****生成表
    def drop_db():
     Base.metadata.drop_all(engine)                       ****删除表
    drop_db()
    init_db()
 数据表的操作:
   表建立成功后:
    Session = sessionmaker(bind=engine)        #用一个类去接受绑定的方法
    session = Session()            #实例化得到对象
    1,增加数据
     增加一条数据:
    # obj = UserType(name='普通用户')        #实例化了一个对象,这个对象代表一行一行数据
    # session.add(obj)                    #把实例化得到的对象添加到表中
    2,增加多条数据
    data = [
     UserType(name='vip用户'),
     UserType(name='vip中p用户'),
     UserType(name='svip用户'),
     UserType(name='黑金用户')
    ]
    session.add_all(data)
    # 查询数据
    res = session.query(UserType)
    print(res)  # SELECT usertype.id AS usertype_id, usertype.name AS usertype_name FROM usertype   是sql语句
    # 查询全部数据
    # rea = session.query(UserType).all()#这个得到的是列表,对象列表,里面是地址和对象,属性    只要有。all()得到的就是列表
      #注意 此时如果不知道数据类型是字典还是列表,最好print一下,看到类型才取值
    # print(rea)
    # for row in rea:                  #row表示每条数据
    #     print(row.name,row.id)         #对象点方法拿到它的值
    
    # 查询第一条数据
    # obj = session.query(UserType).first()
    # print(obj.id,obj.name)
    # 查询多条数据
    # obj = session.query(UserType).filter(UserType.name == '黑金用户', UserType.id == 5).all()  # 得到name为黑金用户 且 id=5的全部对象
    # print(obj)  # 得到的是一个对象
    # for row in obj:
    #     print(row.id,row.name)
    # 如果此时为一条数据时 也可用以下方法,即列表取值
    # print(obj[0].id, obj[0].name)
    #删除数据
    #session.query(UserType).filter(UserType.id>4).delete()
    # 修改数据
    session.query(UserType).filter(UserType.id==3).update({"name":"syy用户"})
    #首先你要把查询的一条语句找到,就是找到要修改的数据,然后再去.update()  括号中必须是字典形式
    # 若不加filter这个条件,他会就会把数据的name全部改为syy用户
    
    session.commit()
    session.close()
     条件:
   ret = session.query(Users).filter_by(name='alex').all()
   ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
   ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
   ret = session.query(Users).filter(Users.id.in_([1,3,4])).all()
   ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all()
   ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
   from sqlalchemy import and, or
   ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
   ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
   ret = session.query(Users).filter(
     or_(Users.id < 2,and_(Users.name == 'eric', Users.id > 3),Users.extra != "")).all()
  通配符:
   ret = session.query(Users).filter(Users.name.like('e%')).all()
   ret = session.query(Users).filter(~Users.name.like('e%')).all()
  限制:limit
   ret = session.query(Users)[1:2]
  排序:
   ret = session.query(Users).order_by(Users.name.desc()).all()
   ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()
  分组:
   from sqlalchemy.sql import func
   ret = session.query(Users).group_by(Users.extra).all()
   ret = session.query(func.max(Users.id), func.min(Users.id)).group_by(Users.name).all()
   ret = session.query(ret = session.query( func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()
  连表:***************************
   ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()
   ret = session.query(Person).join(Favor).all()     
   ret = session.query(Person).join(Favor, isouter=True).all()      左连接
   这个有个正面查询,反面查询
 九:mysql用法在pycham的用法,
    SQL注入    ===>安全问题
   一:在python中连接mysql;
  1.   在终端cmd 中输入 pip3 install  pymysql    
  2.   在pycham中输入以下
    
      import pymysql
    连接mysql服务器
   conn = pymysql.connect(host="localhost",user="root",
     password="123",database="db1",charset="utf8")    host可以是主机名,可以是主机地址,user为用户名 ,database为要连接的数据库,charset为字符编码
    建立一只手,从服务器中取数据
   #cursor = conn.cursor()  如果括号中没指定,他取出来的数据是以元组类型显示,无法更好的见名知意
   cursor = conn.cursor(cursor=pymysql.cursor.DictCursor)  通常采用字典这种方式,更好的知道数据的内容
       利用sql语句来完成对数据库的操作
   sql = "select * from student where id> %s" % (12,)
       1: 函数方法功能体
     ......
      功能方法结束
   
   cursor.execute(sql)        把sql语法提交给服务器
    2:删除和更新的时候需要事务提交commit
   conn.commit()   查找的时候不需要此功能
   #res = cursor.fetchone()     获得一条数据
   #res = cursor.fetchmany(10)  获得许多条数据 即括号内的数据
   res = cursor.fetchall()      获得全部数据                  
      这样得到的数据都是列表里面套字典
   print(res)               打印一下这个数据
   cursor.close()           关闭手这只工具
   conn.close()   关闭连接
   
   案列:
       向t2表中插入10条数据
    import pymysql
    import random
    # 连接mysql服务器a
    conn = pymysql.connect(host='localhost', user='root', password='123', database='t123', charset='utf8')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = 'insert into t2 (name,age) values (%s,%s)'
    data = []
    for i in range(10):
     num = random.randrange(0, 10)
     data.append(('root' + str(num), 'root' + str(num) + '@qq.com'))
    cursor.executemany(sql, data)  #提交多条
    conn.commit()
    res = cursor.fetchall()
    print(res)
    cursor.close()
    conn.close()
   import mysql
 改表:
 分组:select id,name from 表名 where 条件1 and 条件2 group by 分组的列名 having 分组后的二次筛选 limit 限制取几条
 

 多表连接查询:左连接 union 右连接     ===>全连接     显示的是有对应关系的数据, 还显示两张表中彼此没有对应关系的数据
    inner join ...on... #内连接     只是连接有对应关系的两张表
    left join ...on...#左连接  显示有对应关系的数据,且显示左表中没的对应关系的数据 即左表数据全部显示,右边表数据无关系的不显示
    right join ...on...#右连接      显示有对应关系的数据,且显示右表中没的对应关系的数据 即右表数据全部显示,左表数据无关系的不显示
    思路先连表,在查询
    多表连接可以不断的和虚拟表连接    表连接完成再有条件,再有分组 再有二次筛选 再有排序 再有限制取几条
 数据库备份:
    语法:
     mysqldump -h 服务器 -u用户名 -p密码 数据库名 >备份文件.sql
     #示例:
     #单库备份
     mysqldump -uroot -p123 db1 > db1.sql
     mysqldump -uroot -p123 db1 table1 table2 > db1-table1-table2.sql
     #多库备份
     mysqldump -uroot -p123 --databases db1 db2 mysql db3 > db1_db2_mysql_db3.sql
     #备份所有库
     mysqldump -uroot -p123 --all-databases > all.sql
     #导入数据
     
 sql注入:字符串的拼接关系所致,用特殊符号把sql语句进行了注释,所以形成了安全问题
         在服务端防止sql注入问题,不要自己拼接字符串,让pymysql去拼接,用execute()来传值,把需要的值写在他的括号里面
   案例;
   import mysql
   conn = pymysql.connect(host='localhost', user='root', password='123', database='t123', charset='utf8')
   cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
   inp_user = input("请输入用户名:").strip()
   inp_pwd = input("前输入密码:").strip()
   sql = "select * from yy where name=%s and pwd = %s"
   print(sql)
  在这里就可以用execute来解决sql注入带来的问题
   res = cursor.execute(sql, (inp_user, inp_pwd))      #在这里传值,注意括号,解决了sql注入
   print(res)
   if res:
    print("登录成功")
   else:
    print("登录失败")
   cursor.close()
   conn.close()
        在表中添加数据 前提是在pycham中用语法添加数据
   import mysql
   conn = pymysql.connect(host='localhost', user='root', password='123', database='t123', charset='utf8')
   cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
   sql = "insert into yy(name,pwd) values (%s,%s)"          添加数据                   *******
   print(sql)
   rows = cursor.execute(sql, ('张无忌', "234"))                        ***************
   print(rows)
    #data = ['name':'asa','ggg':123]
    #rows = cursor.executemany(sql,data)                #插入多条数据
   #rows = cursor.execute('update yy set name="sb" where pwd="pwdr"')     修改数据 
   #print(rows)
   conn.commit()        #只有执行commit 这条增加的数据才会正真的添加到表中   ****************
   cursor.close()
   conn.close()
   
原文地址:https://www.cnblogs.com/Fzhiyuan/p/11055194.html