zoukankan      html  css  js  c++  java
  • python 存储引擎 mysql(库,表, 行) 单表多表操作 (foreign key) sql_mode pymysql模块讲解

    ##################总结###############

    mysql 常用数据类型

    整型:tinyint  int(42亿条左右)  bigint

    小数:float double decimal 越往后 越精准

    mysql> create table tt(x float(255,30));
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> desc tt;
    +-------+---------------+------+-----+---------+-------+
    | Field | Type          | Null | Key | Default | Extra |
    +-------+---------------+------+-----+---------+-------+
    | x     | float(255,30) | YES  |     | NULL    |       |
    +-------+---------------+------+-----+---------+-------+
    1 row in set (0.01 sec)
    
    mysql> insert into tt values(1.11111111111111111111111111);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from tt;
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111164093017600000000000000 |
    +----------------------------------+
    1 row in set (0.00 sec)

    字符串:char(10)简单粗暴 浪费空间 存取速度快

    varchar:精准 节省空间,存储速度慢

    sql 优化 定长类型往前放,变长的往后放

          比如性格  比如地址或者描述信息

    255个字符,超过了就把文件路径存放到数剧库中.

        比如图片,视屏等找打一个文件服务器,数剧库中只存路径或url

    时间类型:

      最常用:datatime

    mysql> create table t12(dt datetime);
    mysql> insert into t12 values(now());
    Query OK, 1 row affected (0.00 sec)
    mysql> select * from t12;
    +---------------------+
    | dt                  |
    +---------------------+
    | 2019-01-17 15:48:10 |
    +---------------------+
    1 row in set (0.00 sec)

    枚举类型与集合类型  enum和set

    age enum('20', '22')
    hobby set(
    'play','music','read','study'); insert into consumer values( 'music','read' )

    库基本操作

    #查看所有数剧库
    show databases;
    #查看创建数据库语法
    show create database db1;
    #查看当前在哪个数据库下
    select database();
    
    #进入某个数剧库下
    use 数剧库名字
    #删除数剧库
    drop database 数剧库名字
    
    #修改数剧库字符集
    alter database db1 charset utf8;

    表基本操作

    #进入某个表
    use db1
    #创建一个表
    create table t1(id int,name varchar(50), sex enum('nan','nv'),age int(3));
    #查看所有表名
    show  tables;
    #插入指定的列
    语法一:
    insert into 表名(字段1,字段2,字段3,字段N) values(值1,值2,值3..值N)
    语法二:
    insert into 表名 values (值1,值2,值3,值N) insert into t1 values(2,'张三','nan',18);
    语法三:
    insert into 表名 values (值1,值2,值3,值N),
    (值1,值2,值3,值N),(值1,值2,值3,值N)
    #更新(修改)数据
    update user set password='123456' where user='root' and host='localhost'
    #删除
    delele from user where password='123'

    #创建一个表把id列设置为主键 不允许重复 不允许为空 id自增 name为varchar类型20个字节
    create table t3 (id int primary key auto_increment, name varchar(20));
    #创建一个server表 设置ip和port 为主键列 这2个列为and关系 这ip和port不能同时有重复数据
    create table server(ip varchar(15), port char(5), server_name varchar(10) not null,primary key(ip,port));


    表基本修改操作
    ###修改表的名称
    mysql> alter table t1 rename t11;
    ###添加字段列名称
    mysql> alter table t2 add age varchar(10);
    Query OK, 0 rows affected (0.04 sec)
    Records: 0  Duplicates: 0  Warnings: 0###删除表某个字段 
    mysql> alter table t2 drop  column age;
    ###修改某列名称
    mysql> alter table t2 change name name1 varchar(20);
    alter table t1 modify name char(3);  #修改字段属性的,将name字段的char长度改为3

    在已经有的表上添加外键关系
    alter table 表名 add foreign key(c_id) references class(id)
    查询数据 select
    select * from 表名 #查询所有字段数据
    
    select distinct 字段1,字段2....from 库名.表名 #想要的结果字段
            where 条件 #后面跟的是你的查询条件
            group by field(字段) #分组
            having #筛选
            order by field(字段)#将结果按照后面的字段进行排序
            limit 限制条数
    ##################################
    重点中的重点:关键字的执行优先级
    from
    where
    group by
    having
    select
    distinct
    order by
    limit
    1.找到from
    2.拿着where指定的约束条件,去文件/表中去除一条记录
    3.将去取出的一条条记录进行分组group by 如果没有整体为一组
    4.将分组的结果进行having过滤
    5.select
    6.去重
    7.按条件排序 order by
    8.限制显示条数

    单表查询

    
    
    #我们来创建一个员工表,然后对员工表进行一个简单的查询,来看一下效果,下面是员工表的字段
    company.employee
        员工id      id                  int             
        姓名        emp_name            varchar
        性别        sex                 enum
        年龄        age                 int
        入职日期     hire_date           date
        岗位        post                varchar
        职位描述     post_comment        varchar
        薪水        salary              double
        办公室       office              int
        部门编号     depart_id           int

    ##创建表 插入数据
    create table employee (
    id int primary key auto_increment,
    name varchar(20) not null,
    sex enum('male','female') not null default 'male',#大部分是男的
    age int(3) unsigned not null default 28,
    hire_date date not null,#聘用日期
    post varchar(50),#职位
    post_comment varchar(100),#职位描述
    salary double(15,2),# 薪水 精确2个小数位 最长15位
    office int,#部门办公室
    depart_id int#部门编号
    )
    ######################
    insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values
    ('egon','male',18,'20170301','老男孩驻沙河办事处外交大使',7300.33,401,1), #以下是教学部,全都是老师
    ('alex','male',78,'20150302','teacher',1000000.31,401,1),
    ('wupeiqi','male',81,'20130305','teacher',8300,401,1),
    ('yuanhao','male',73,'20140701','teacher',3500,401,1),
    ('liwenzhou','male',28,'20121101','teacher',2100,401,1),
    ('jingliyang','female',18,'20110211','teacher',9000,401,1),
    ('jinxin','male',18,'19000301','teacher',30000,401,1),
    ('成龙','male',48,'20101111','teacher',10000,401,1),
    
    ('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
    ('丫丫','female',38,'20101101','sale',2000.35,402,2),
    ('丁丁','female',18,'20110312','sale',1000.37,402,2),
    ('星星','female',18,'20160513','sale',3000.29,402,2),
    ('格格','female',28,'20170127','sale',4000.33,402,2),
    
    ('张野','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
    ('程咬金','male',18,'19970312','operation',20000,403,3),
    ('程咬银','female',18,'20130311','operation',19000,403,3),
    ('程咬铜','male',18,'20150411','operation',18000,403,3),
    ('程咬铁','female',18,'20140512','operation',17000,403,3)
    #简单查询
    select id,name,sex,age,hire_date,post,post_comment,salary,office,depart_id from employee;
    select name,salary from employee;

    #去重
    select distinct post from employee #会对部门进行去重
    select distinct post,sex from employee;#有坑 只有他俩合起来是一个重复记录的时候才会去重

    #四则拼接运算
    select concat('姓名:',name,'年薪:',salary*12) AS Annual_salary from employee;#四则拼接
    SELECT CONCAT('姓名: ',name,'  年薪: ', salary*12)  AS Annual_salary,CONCAT('性别:',sex) from employee; #多个条件连接
    where 约束
    1.比较运算符: > < >= <= <> !=
    2.between 80 adn 100 值在80到100之间
    3.in(80,90,100)值是80或90或100
    4.linke 'wgon%'
     pattern可以识%或_,
     %表示任意多字符
     _表示一个字符
    5.逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not
    #单条查询
    select * from employee where post='sale';
    
    #多条件查询
    select name,salary from employee where post='teacher' and salary> 10000
    
    #关键字between and 写一个区间
    select name,salary from employee where salary between 10000 and 20000
    
    #加个not,就是不在这个区间内,薪资小于10000的或者薪资大于20000的,注意没有等于
    select name,salary from  employee where not salary between 10000 and 20000
    
    #判断某个字段是否为空null 不能用等号 需要用is
    select name,post_comment from employee where post_comment is null
    
    #判断某个字段是否为空 后面可以在接上where条件
    select name,post_comment from employee where post_comment=''
    
    #查询一下指定工资条件 3000,3500,4000,9000的人
    select name,salary from employee where salary in(3000,3500,4000,9000)
    
    #查询一下不是工资条件 3000,3500,4000,9000的人
    select name,salary from employee where salary not in(3000,3500,4000,9000)
    
    #关键字like模糊匹配查询
    select * from employee where name like 'eg%'
    #通配符匹配'_'
    #注意我这里写的两个_,用1个的话,匹配不到alex,因为al后面还有两个字符ex。
    select * from employee where name like 'al__'
    
    #########分组##########
    #为什么要分组,取每个部门的最高工资 取每个部门的员工数  取男人数和女人数
    #默认拿到的结果都是每组的第一条数据 这样有问题 解决方案 需要改sql_mode
    #只能查看分组依据和使用聚合函数 #因为一般分组之后,我们再考虑其中一条数据就没有什么意义了
    select * from employee group by post;
    #GROUPBY关键字和GROUP_CONCAT()函数一起使用,比如说我想按部门分组,每个组有哪些员工,都显示出来,怎么搞
    #按照岗位分组,并查看组内所有成员名,通过逗号拼接在一起
    SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;
    
    select post,count(id) as count from employee group by post;
    #关于集合函数,mysql提供了以下几种聚合函数:count、max、min、avg、sum等,上面的group_concat也算是一个聚合函数了,做字符串拼接的操作
    
    ####强调
    #如果我们用设置了unique约束的字段作为分组的依据,则每一条记录自成一组,这种分组没有意义多条记录之间的某个字段值相同,该字段通常用来作为分组的依据
    
    ########聚合函数######
    #count是统计个数用的
    select count(*) from employee;
    #后面跟where条件的意思是统计一下满足depart_id=1这个的所有记录的个数
    select count(*) from employee where depart_id=1
    
    #max()统计分组后每组的最大值,这里没有写groupby,那么就是统计整个表中所有记录中薪资最大的,薪资的值
    select max(salary) from employee;
    SELECT MIN(salary) FROM employee;#最小的
    SELECT AVG(salary) FROM employee;#平均
    SELECT SUM(salary) FROM employee;#合计
    SELECT SUM(salary) FROM employee WHERE depart_id=3;
    
    #########having##########
    #来个需求:统计各部门年龄在30岁及以上的员工的平均薪资,并且保留平均工资大于10000的部门
    #注意:having只能在group by后面运行
    select post,avg(salary) as new_sa from employee where age>=30 group by post having avg(salary) > 10000;
    
    #########排序######
    #默认升序
    select * from employee order by salary asc; #升序
    select * from employee order by salary desc; #降序
    
    ########limit######
    #从10开始 往后走5条数据
    select * from employee limit 10,5
    
    ########正则表达式#######
    select * from employee where name regexp '^ale';
    select * from employee where name regexp 'on$';
    select * from employee where name regexp 'a{2}';
    
    #查看所有员工中名字是jin开头,n或者g结果的员工信息
    select * from employee where name regexp '^jin.*[g|n]$';

     多表查询 

    #建表
    #部门表
    create table department(
    id int,
    name varchar(20) 
    );
    
    #员工表,之前我们学过foreign key,强行加上约束关联,但是我下面这个表并没有直接加foreign key,这两个表我只是让它们在逻辑意义上有关系,并没有加foreign key来强制两表建立关系,为什么要这样搞,是有些效果要给大家演示一下
    #所以,这两个表是不是先建立哪个表都行啊,如果有foreign key的话,是不是就需要注意表建立的顺序了。那我们来建表。(employee 员工表)
    create table employee(
    id int primary key auto_increment,
    name varchar(20),
    sex enum('male','female') not null default 'male',
    age int,
    dep_id int
    );
    
    #给两个表插入一些数据
    insert into department values
    (200,'技术'),
    (201,'人力资源'),
    (202,'销售'),
    (203,'运营'); #注意这一条数据,在下面的员工表里面没有对应这个部门的数据
    
    insert into employee(name,sex,age,dep_id) values
    ('egon','male',18,200),
    ('alex','female',48,201),
    ('wupeiqi','male',38,201),
    ('yuanhao','female',28,202),
    ('liwenzhou','male',18,200),
    ('jingliyang','female',18,204) #注意这条数据的dep_id字段的值,这个204,在上面的部门表里面也没有对应的部门id。所以两者都含有一条双方没有涉及到的数据,这都是为了演示一下效果设计的昂
    ;
    #department 部门表 employee 员工表
    select * from department,employee
    ##我们要找的数据就是员工表里面dep_id字段的值和部门表里面id字段的值能对应上的那些数据啊
    #如果把员工表放前面 会在* 的时候显示不好看 其实结果是一样的 -- select * from department,employee where employee.dep_id=department.id select * from employee,department where employee.dep_id=department.id; #再看一个需求,我要查出技术部的员工的名字 select employee.`name` from employee,department where employee.dep_id=department.id and department.name='技术'
    #多表连接查询语法
    #重点:外链接语法 SELECT 字段列表 FROM 表1 INNER|LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段; #inner 只保留你有 关联的数据 #left 以左表显示为主 #right以右表显示为主
    #以下语句表的顺序 不分先后顺序
    select employee.name from department inner join employee on department.id =employee.dep_id
    
    
    select employee.name from employee inner join department on employee.dep_id =department.id where department.`name`='技术';
    #从结果可以看出 这个显示结果会多显示一个203运营组为空 这个是以左边为主 因为用户表没有运营组的数据 select * from department left join employee on department.id=employee.dep_id
    
    select employee.id,employee.name,department.name from employee left join department on employee.dep_id=department.id;

    #以左表为准,即找出所有员工信息,当然包括没有部门的员工 select * from department right join employee on department.id=employee.dep_id
    
    select employee.id,employee.name,department.name from employee right join department on employee.dep_id=department.id;
    
    -- 可以通过 as 给表起别名
    -- select s.id,s.name,s.gender from students as s;
    #显示左右2个表全部记录 select * from employee left join department on employee.dep_id=department.id union select * from employee right join department on employee.dep_id=department.id
    #示例1:以内连接的方式查询employee和department表,并且employee表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门
    select department.`name`,employee.`name` from employee inner join department on employee.dep_id=department.id where employee.age >25
    #示例2:以内连接的方式查询employee和department表,并且以age字段的升序方式显示
    select * from employee inner join department on employee.dep_id=department.id ORDER BY age asc;
    ####子查询
    #子查询其实就是将你的一个查询结果用括号括起来,这个结果也一张表,就可以将它交给另外一个sql语句
    #我们之前的做法是:先连表 #然后根据连表的结果进行where过滤
    
    #首先从部门表里面找到技术部门对应的id
    select id from department where name='技术'
    
    #那我们把上面的查询结果用括号括起来,它就表示一条id=200的数据,然后我们通过员工表来查询dep_id=这条数据作为条件来查询员工的name
    select * from employee where dep_id =(select id from department where name='技术')
    带in的关键字子查询
    #查询员工平均年龄在25岁以上的部门名,可以用连表,也可以用子查询,我们用子查询来搞一下
    #这里特别迷糊 group by employee.dep_id 相当于过滤组id department.name
    select id,name from department
        where id in 
            (select dep_id from employee group by dep_id having avg(age) > 25);
    
    select department.name from department inner join employee on department.id=employee.dep_id 
        group by department.name 
        having avg(age)>25;                                                                                                                                                                          
    #查看不足1人的部门名(子查询得到的是有人的部门id )
    select name from department where id not in (select distinct dep_id from employee);
    #带比较运算符的子查询
    #比较运算符:=、!=、>、>=、<、<=、<>
    #查询大于所有人平均年龄的员工名与年龄
    select name,age from employee where age > (select avg(age) from employee);
    #带EXISTS关键字的子查询
    select * from employee where exists (select id from department where id=200)
    
    #不会执行前面的数据 后面的条件为假
    select * from employee where exists (select id from department where id=204);
    
    
    快速理解foreign key(外键其实就是标明表和表之间的关系,表和表之间如果有关系的话就三种:一对一,多对一,多对多)

    一对一
    两张表:学生表和客户表
    
    一对一:一个学生是一个客户,一个客户有可能变成一个学校,即一对一的关系
    
    关联方式:foreign key+unique
    
    
    #一定是student来foreign key表customer,这样就保证了:
    #1 学生一定是一个客户,
    #2 客户不一定是学生,但有可能成为一个学生
    customer 顾客表 
    create table customer(
    id int primary key auto_increment,
    name varchar(20) not null,
    qq varchar(10) not null,
    phone char(16) not null
    );
    create table student(
    id int primary key auto_increment,
    class_name varchar(20) not null,
    customer_id int unique, #该字段一定要是唯一的
    foreign key(customer_id) references customer(id) #外键的字段一定要保证unique
    on delete cascade
    on update cascade
    );
    #增加客户
    insert into customer(name,qq,phone) values
    ('李飞机','31811231',13811341220),
    ('王大炮','123123123',15213146809),
    ('守榴弹','283818181',1867141331),
    ('吴坦克','283818181',1851143312),
    ('赢火箭','888818181',1861243314),
    ('战地雷','112312312',18811431230)
    ;
    #增加学生
    insert into student(class_name,customer_id) values
    ('脱产3班',3),
    ('周末19期',4),
    ('周末19期',5)
    ;

    多对一 或者一对多
    员工信息表有三个字段:工号  姓名  部门    部门 id 部门名称 部门介绍

    dep部门表 emp员工表
    #
    创建一个部门表 CREATE TABLE dep ( id INT PRIMARY KEY auto_increment KEY, dep_name CHAR ( 10 ), dep_comment CHAR ( 50 ) ); mysql> desc dep; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | dep_name | char(10) | YES | | NULL | | | dep_comment | char(50) | YES | | NULL | | +-------------+----------+------+-----+---------+----------------+ #创建一个员工表 和部门表表做关联 create table emp(id int primary key auto_increment, name char(16), gender enum('nan','lv') not null default 'nan', dep_id int, foreign key(dep_id) references dep(id) );

    这时候 直接插入 员工 会报错的  因为,你的部门还没有呢,你的员工表里面的那个dep_id外键字段的数据从何而来啊?

    #创建3个部门
    INSERT INTO dep ( dep_name, dep_comment )
    VALUES
        ( '外交部', '负责部门之间外交的' ),
        ( '教育部', '辅导学生的' ),
        ( '技术部', '最牛鼻的部门' )
    #插入几个用户
    insert into emp(name,gender,dep_id) values ('张三','nan',4),('李四','nan',5),('alex','lv',6);
    # truncate dep#可以把数据清空 id重置

    多对多 关系

    #多对多
    三张表:出版社,作者信息,书
    
    多对多:一个作者可以写多本书,一本书也可以有多个作者,双向的一对多,即多对多
      
    关联方式:foreign key+一张新的表
    #创建一个作者表
    create table author(
    id int primary key auto_increment,
    name varchar(20)
    );
    id 名字
    #创建一个书表

    create table book(
    id int primary key auto_increment,
    bname char(16),
    poice int
    )

    书名字  poice书价格

    ##########添加数据#########

    #添加4个作者

    insert into author(name) values('egon'),('alex'),('yuanhao'),('wpq');

    #添加书信息

    insert into book(bname,poice) values('九阴神功',100),('九阴真经',200),('九阴真经',200),('九阴白骨爪',300),('降龙十巴掌',400),('葵花宝典',500)

    #这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了

    create table author2book(
    id int not null unique auto_increment,#创建id列 不能为空唯一 自增
    author_id int not null,#作者id 不能为空
    book_id int not null, #书id 不能为空
    constraint fk_author foreign key(author_id) references author(id)
    #constraint fk_author 唯一约束UNIQUE的另一个写法
    #作者id references关联到id
    on delete cascade
    on update cascade,
    constraint fk_book foreign key(book_id) references book(id)
    #constraint fk_author 唯一约束UNIQUE的另一个写法
    #书id references关联到书id
    on delete cascade
    on update cascade,
    primary key(author_id,book_id)
    );

    #插入四个作者,id依次排开
    insert into author(name) values('egon'),('alex'),('yuanhao'),('wpq');
    #每个作者与自己的代表作如下
    1 egon: 
          1 九阳神功
          2 九阴真经
          3 九阴白骨爪
          4 独孤九剑
          5 降龙十巴掌
          6 葵花宝典
    
    
    2 alex: 
          1 九阳神功
          6 葵花宝典
    
    3 yuanhao:
          4 独孤九剑
          5 降龙十巴掌
          6 葵花宝典
    
    4 wpq:
          1 九阳神功
    
    insert into author2book(author_id,book_id) values
    (1,1),
    (1,2),
    (1,3),
    (1,4),
    (1,5),
    (1,6),
    (2,1),
    (2,6),
    (3,4),
    (3,5),
    (3,6),
    (4,1)
    ;

    中间那一张存放关系的表,对外关联的字段可以联合唯一

    将来你们接触某一些大型项目的时候,尽量不要给表建立外键关系,因为外键直接在数据库级别就变成耦合的了,那么我们要拓展或者删除或者更改某些数据库或者数据表的时候,拓展起来就比较难,我们可以自己从自己的程序代码的逻辑层面上将这些关联关系建立好,有很多公司就是这么做的,利于拓展,如果我们加了很多的foreign key ,那么当你想删除一个表的时候,可能会牵一发而动全身

    还有一个注意的地方 直接删除外键字段是不可以的 

    表的外键字段,然后先解除外键字段的关系,才能删除外键字段

     foreign key的下面几个约束作用:

        1、先要建立被关联的表才能建立关联表

        2、在插入数据记录的时候,要先想被关联表中插入数据,才能往关联表里面插入数据

        3、更新或者删除数据的时候,都需要考虑关联表和被关联表的关系 

    解决方案:
    a.删除表的时候,先删除关联表,再删除被关联表
    
    b.重建表的时候,在加外键关联的时候加上这两句:on delete cascade 和 on update cascade
    CREATE TABLE emp (
    id INT PRIMARY KEY auto_increment,
    NAME CHAR ( 16 ),
    gender enum ( 'nan', 'lv' ) NOT NULL DEFAULT 'nan',
    dep_id INT,
    FOREIGN KEY ( dep_id ) REFERENCES dep ( id )
    on delete cascade
    on update cascade
    );

    #成功了,并且员工表里面关联部门表id的数据也都删除了

    #如果改了组id号,那么我员工表里面的id号也会跟着改变

    1. 是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值
    2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值
    sex enum('male','female') not null default 'male'
    age int unsigned NOT NULL default 20 必须为正值(无符号) 不允许为空 默认是20
    3. 是否是key
    主键 primary key
    外键 foreign key
    索引 (index,unique...)


    1.存储引擎 :表类型,mysql会更根据不用的表类型 会有不同处理机制(如MyISAM类型表默认就3个文件 数据文件,表结构,索引文件)

     MyISAM引擎特点: 

        不支持事物(事物是指逻辑上的一组操作,组成这个组操作,要么全成功,要么全失败)

             如:我给你转账 我这边减去1千 你那边加上1千  这中间有一个失败 就算失败

        表级锁定(数据更新时会锁定整个表)

        读写互相阻塞(会在写入的时候阻塞读取,还会在读取阻塞写)

        只会缓存索引(可以通过 key_buffer_size的值来提高缓存索引,以大大提高访问性能减少io,这个缓存区只会做缓存索引,不会缓存数据)

        读取速度快 占用资源少

        不支持外键约束,但是支持全文索引

    InnoDB引擎特点:

        支持事物:

            原子性:那么发生 要么不发生

            一致性:事物发生前后数据完整性必须保证一致

            隔离性:一个正在执行的事物完毕钱,对其他的会话是不可见

            持久性:一个事物一旦被提交,它对数剧库中的数据更改是永久性的

     

    1.创建表时指定引擎
    create table innodb_t2(id int)engine=innodb;
    2.在配置文件存储引擎
    linux:vim /etc/my.cnf   windows:my.ini文件
    [mysqld]
    default-storage-engine=INNODB  #配置默认引擎,现在用的mysql默认基本都是InnoDB,所以其实都可以不用配置了
    innodb_file_per_table=1  #表示独立表空间存储,可以不写

    sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入。在生产环境必须将这个值设置为严格模式,所以开发、测试环境的数据库也必须要设置,这样在开发测试阶段就可以发现问题.

        方式一:先执行select @@sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set sql_mode = '修改后的值'或者set session sql_mode='修改后的值';,例如:set session sql_mode='STRICT_TRANS_TABLES';改为严格模式
    
            此方法只在当前会话中生效,关闭当前会话就不生效了。
    
        方式二:先执行select @@global.sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set global sql_mode = '修改后的值'。
    
            此方法在当前服务中生效,重新MySQL服务后失效
    
        方法三:在mysql的安装目录下,或my.cnf文件(windows系统是my.ini文件),新增 sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,
            添加my.cnf如下:
            [mysqld]
             sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER
            然后重启mysql。

    pymysql 模块 

    安装方法 pip install pymysql

    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='123456.com',
        database='shanku',
        charset='utf8'
    )
    # cursor=conn.cursor()#获得元祖数据的游标
    cursor = conn.cursor(pymysql.cursors.DictCursor) #获取字典类型数据的游标
    sql='select * from userinfo;'
    
    # sql='select * from userinfo where username=%s and password=%s'%(username,pwd)
    # sql = "insert into userinfo values(4,'gaowang',666);"
    # cursor = conn.cursor() #获取元组类型数据的游标
    # cursor = conn.cursor(pymysql.cursors.DictCursor) #获取字典类型数据的游标
    # sql = 'select * from userinfo;'
    # sql = "select * from userinfo where username='%s' and password='%s';"%(username,pwd)
    
    
    res = cursor.execute(sql)  #将结果放一个集合等待被查询
    # print(cursor.fetchall())#读取所有内容
    #many_data=cursor.fetchmany(3) #一下取出3条数据
    print(cursor.fetchone())#读取一行
    # cursor.scroll(1,'absolute') #顺着指针的一行往下读取数据
    #cursor.scroll(1,'relative')#从第一行开始读取
    
    print('>>>>>',cursor.fetchone())#一行打印
    # print('>>>>>',cursor.fetchmany(1))#这个明天再找
    conn.commit()#进行增删改的时候 必须要提交的
    # print(res)

     #模拟登陆

    import pymysql
    conn=pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='123456.com',
        database='shanku',
        charset='utf8'
    )
    username=input('请输入用户名:')
    password=input('请输入密码:')
    cursor=conn.cursor(pymysql.cursors.DictCursor)#获得字典类型的游标
    # sql = "select * from userinfo where uname='%s' and password='%s'"%(username,password)
    #防注入 使用下面方式
    sql = "select * from userinfo where uname=%s and password=%s;"
    # ret=cursor.execute(sql)#影响的行数
    #防注入 使用下面方式
    ret = cursor.execute(sql,[username,password])  #res受影响的行
    #其实它本质也是帮你进行了字符串的替换,只不过它会将uname和pword里面的特殊字符给过滤掉。
    print(ret)
    
    cursor.close() #关闭游标
    conn.close()   #关闭连接
    if ret:
        print('登陆成功')
    else:
        print('登陆失败')
    #####这样容易引起sql注入风险
    
    请输入用户名:haha' -- xxx
    请输入密码:sadas
    select * from userinfo where uname='haha' -- xxx' and password='sadas'
    1
    登陆成功
    
    
    请输入用户名:xxx' or 1=1 -- xxxxxx
    请输入密码:wrwqr
    select * from userinfo where uname='xxx' or 1=1 -- xxxxxx' and password='wrwqr'
    4
    登陆成功
    
    我靠 这样 又登陆成功了 

    获取插入的最后一条数据的自增ID

    import pymysql
    conn=pymysql.connect(host='localhost',user='root',password='123',database='egon')
    cursor=conn.cursor()
    
    sql='insert into userinfo(name,password) values("xxx","123");'
    rows=cursor.execute(sql)
    print(cursor.lastrowid) #在插入语句后查看
    
    conn.commit()
    
    cursor.close()
    conn.close()
    不怕大牛比自己牛,就怕大牛比自己更努力
  • 相关阅读:
    大数据量分表时 两个表查询比较快的方式
    开启SQL Server执行占用时间显示和逻辑读取次数显示
    【转】SQL Server海量数据库的索引、查询优化及分页算法
    Exchange无法发送邮件 未找到匹配的连接器来路由外部收件人解决办法
    HTML介绍&常用的标签
    关于HTML文件、JS文件、CSS文件
    python命名空间和作用域
    pymysql
    存储过程、视图、触发器、函数
    多表查询
  • 原文地址:https://www.cnblogs.com/zaizai1573/p/10277650.html
Copyright © 2011-2022 走看看