mysql - 数据库

内容回顾

day35

# 并发编程
# io操作 : input/output
# 阻塞 非阻塞(get_nowait) 同步 异步(start terminate submit map) 并发 并行
# 进程的三状态图 : 阻塞 运行 就绪
# 进程  计算机中最小的资源分配单位
    # 进程之间数据隔离\资源不共享
    # 可以利用多个CPU
    # 开启和销毁的开销大
    # 由操作系统负责调度
    # multiprocessing模块
        # Process类 : 开启进程
            # 各种操作进程的方法
            # 守护进程 : 守护到主进程的代码结束
        # IPC : 进程之间通信
            # 基于文件Queue Pipe\基于网络 socket 第三方工具
        # 进程中的互斥锁 Lock :性能好
        # 进程中的递归锁 RLock : 效率低
            # 递归锁可以锁多次不会发生死锁
# 线程
    # 计算机中能够被操作系统调度的最小单位
    # 线程之间资源共享
    # 可以利用多核
    # 开启和销毁的开销小
    # 由操作系统负责调度
    # GIL锁 : 全局解释器锁 互斥锁
        # 导致了Cpython解释器下  同一个进程下的多个线程 不能利用多核
        # 由于垃圾回收机制gc不能在多线程环境下正常进行引用计数
    # threading模块
        # Thread类
            # 开启线程
            # 守护线程 : 守护整个主线程的
            # 子线程先结束
            # 主线程结束
            # 主进程结束(意味着主进程就结束了,一旦主进程结束,所有的属于这个进程的资源都被回收了)
            # 主进程结束了 如果还存在守护线程,那么守护线程会随着进程的结束被回收
        # 锁:
            # 死锁现象  交叉使用互斥(递归锁)锁
            # 线程互斥锁
            # 线程递归锁
            # 单例模式 要加锁
            # 线程之间数据安全
                # 但凡是 带着判断 判断之后要做xxxx 都需要加锁
                # if while += -= *= /= 都需要加锁
                # n = 0;tmp=n;n = tmp+1
            # append pop extend 队列 logging都是线程安全的
    # 线程队列
        # queue模块
        # Queue 先进先出
            # 生产者消费者模型
        # LifoQueue 后进先出栈
            # from queue import LifoQueue
            # lq = LifoQueue()
            # lq.put(1)
            # lq.put(2)
            # lq.put(3)
            # print(lq.get())
        # PriorityQueue 优先级队列
            # from queue import PriorityQueue
            # pq = PriorityQueue()
            # pq.put((10,'alex'))
            # pq.put((5,'egon'))
            # pq.put((15,'yuan'))
            # print(pq.get())
            # print(pq.get())
            # print(pq.get())
    # 池 concurrent.futrues
        # 进程池 ProcessPoolExecutor
        # 线程池 ThreadPoolExecutor
        # 回调函数
# import requests
# from concurrent.futures import ThreadPoolExecutor
#
# def get_url(name,url):
#     ret = requests.get(url)
#     return name,ret.content
#
# def dump(res):
#     with open(res.result()[0],mode='wb') as f:
#         f.write(res.result()[1])
#
# tp = ThreadPoolExecutor(4)
# dic = {
#     'baidu':'http://www.baidu.com',
#     'taobao':'http://www.taobao.com',
#     'jd':'http://www.jd.com',
#     'sina':'http://www.sina.com',
#     'sogou':'http://www.sogou.com',
#     'cnblog':'https://www.cnblogs.com/Eva-J/articles/9676220.html',
# }
# for k in dic:
#     ret = tp.submit(get_url,k,dic[k])
#     ret.add_done_callback(dump)

# 协程
    # 资源开销小
    # 协程是微线程
    # 本质是一条线程 所以不能利用多核
    # 由程序控制的,不是由操作系统调度的
    # gevent 第三方模块
    # 协程能够识别的IO操作 : 网络操作 sleep
    # 协程和cpython解释器下的线程有啥区别 :资源开销小 能够把单线程的效率提高 协程能够识别的io操作不如线程多

# 学了什么
    # 基础数据类型
    # 流程控制 if while for
    # 文件操作
    # 函数 (定义 调用 参数 返回值 命名空间和作用域 闭包 装饰器 生成器 迭代器 匿名函数 内置函数 递归)
    # 模块 (常用模块 自定义模块 模块的导入 开发规范 包)
    # 面向对象(基础 三大特性 三个装饰器 内置方法 反射)
    # 网络编程(osi协议 socket模块 tcp的粘包 socketserver)
    # 并发编程(操作系统概念 进程 线程 协程)
# 回顾作业
    # 三次登录 购物车 atm 博客园 选课系统 ftp

初始数据库

# 数据库管理系统-DBMS
    # 网络应用服务端
    # 我们要使用服务端的数据 - 需要有一个客户端
        # 客户端可以自己写   : 未来写代码的时候
        # 也可以用别人写好的 : 第三方的工具 数据库管理软件的公司出版的官方客户端
    # 数据库管理系统本质上也是管理一堆文件
        # 只不过人家的管理方式比我们更高效 更安全
# 数据库管理员-DBA
    # 搭建数据库服务环境
    # 用户的创建 权限的管理
    # 性能\语句的优化
    # 数据库的二次开发 : 让数据库具有公司的特质
# 软件
    #  mysql : 小公司 互联网企业
    # 甲骨文 oracle  : 事业单位 金融企业
    # 微软 sql server
    # sqllite
# 名词
    # DB    数据库 - 文件夹
    # table 表 - 文件
    # data  一条数据-每一行数据

# 数据库的分类
    # 关系型数据库 mysql oracle sqlserver sqllite
    # 非关系型数据库 redis mongodb memcache hbase

day36

1.初始数据库

  1. dbms 数据库管理系统

    dba 数据库管理员

    db 数据库/文件

    table 表/文件

    data 表中的具体数据

  2. 关系型mysql oracle sqlserver sqllite

    非关系型 redis mongodb hbase

# mysqld install 安装sql服务
# net start mysql 启动服务
# net stop mysql 关闭服务

# mysql -uroot -h192.168.12.45 -p
# Enter password:
# mysql>

# 你启动的mysql.exe是客户端 S 你安装好的服务是server
# 在客户端需要指定 要登录的数据库所在的ip 以及用户名和密码
# mysql -uroot -p123 -h192.168.12.45
# mysql> set password = password('123');  设置密码
    # 需要注意要在sql的结尾输入;表示整个sql语句的结束
    # 如果忘记了可以在换行之后补上。
# \c表示放弃当前行要执行的sql语句
# exit 表示退出客户端

# 用户
# create user '用户名'@'允许的网段' identified by '密码'
# grant usage on 数据库.表 to 'eva'@'%';
# grant select on 数据库.* to 'eva'@'%';
# grant update on *.* to 'eva'@'%';
# grant insert on *.* to 'eva'@'%';
# grant delete on *.* to 'eva'@'%';
# grant all on ftp.* to 'eva'@'%';

# show databases;  查看当前的所有库

2.基础操作

1.数据库(文件夹)的操作

​ 创建数据库

create database  数据库名;

​ 查看所有的库

show databases;

​ 切换到对应库中/进入对应的文件夹

use 数据库名;

​ 查看当前所在的库

select database();

2.表(文件)的操作

​ 创建表

create table 表名(列名 数据类型 约束条件);

​ 查看有哪些表

show tables;

​ 查看表结构

desc 表名;
describe 表名;

3.数据的操作

​ 写数据

insert into 表名 values(2,'alex','sb123');

​ 查看表

select * from 表名

​ 数据的修改

update 表名 set 数据的=修改  where 条件

​ 数据的删除

delete from 表名 where 条件

4.数据类型

​ 数字类型

整数  tinyint(255)     int
小数  float       double
unsigned  无标点符号    约束用的

​ 字符串

char(字符)255        定长,节省时间,浪费空间
varchar(字符)65535   变长,节省空间,浪费时间

​ 时间类型

now()       函数表示当前时间
datetime    年月日时分秒    0000-9999
date        年月日
time        时分秒
year        年
timestamp   年月日时分秒   1970-2038

​ enum 和set

enum  单选
set   多选   自动去重

例子.数值类型和字符串

# 整数
# create table t1(i1 tinyint,i2 int);
# 默认创建的所有数据都是有符号的
# create table t2(i1 tinyint unsigned,i2 int unsigned);
# unsigned表示无符号

# 小数
# create table t3(f1 float,f2 double)
# create table t4(f1 float(7,2))

# 字符串
# char(25)
    # 'abc            ' 浪费空间、节省时间
# varchar(25)
    # '3abc'            节省空间、浪费时间
# create table t5(c1 char(5),c2 varchar(5));

例子.时间类型和枚举集合

# create table t6(dt datetime,d date,t time,y year,ts timestamp);
# insert into t6 values(now(),now(),now(),now(),now());
# insert into t6(dt) values('2018-8-8 8:8:8');
# insert into t6(dt) values(20180808080808);
# insert into t6(d) values(20180808);
# insert into t6(t) values('8:8:8');


# create table t7(dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,y year);

# create table t8(username char(12),gender enum('male','female'));
# create table t9(username char(12),hobby set('抽烟','喝酒','烫头','洗脚'));

day37

1.单表查询

  1. select 列查询

    select * from 表;             *代表所有的列
    
  2. 指定列查询

    select 列1,列2 from 表;
    
  3. 在列中使用四则运算

    select 列1,列2*12  from 表;
    
  4. 重命名

    select 列1,列2 as annl_列2 from 表;
    
    select 列1,列2 annl_列2 from 表;      	      加不加as都可以
    
    1. 去重

      select distinct 列 from 表;
      
      select distinct  列1,列2 from 表;     可以去重多个列
      
  5. 函数 concat() 拼接

    select concat('姓名:',列名1),concat('年薪;',列名2) from 表;
    
    select concat_ws('|','a','b','c')
    

    7.case when语句 == if条件判断句

2.where语句 根据条件进行筛选行

1. 比较运算符 = > < >= <= !=/<>
select * from 表  where age > 18;
  1. between a and b #[a,b] 区间
    select * from 表 where salary between 10000 and 20000;
    
  2. in
    select * from 表 where  age  in(18,20);
    
    1. like 模糊查询
      1. ​ _通配符 表示一个字符长度的任意内容

        select * from 表 where name like '赵_'
        
        1. % 通配符 表示任意字符长度的任意内容

          select * from 表 where name like '赵%'
          
          select * from 表 where name like '%赵%'
          
        2. regexp 正则匹配 有模糊查询,正则就用的很少

          select * from employee where emp_name regexp '^jin'
          
5.逻辑运算

​ and

select * from 表 where age >18 and post = 'teacher';

​ or

select * from 表 where age<30 or age>20;

​ not

select * from 表 where age not in (15,18,20);
6. 关于null
    # 查看岗位描述为NULL的员工信息
    # select * from employee where post_comment is null;
    # 查看岗位描述不为NULL的员工信息
    # select * from employee where post_comment is not null;
7.五个聚合函数
    # count   统计 
    # max     最大值
    # min     最小值
    # avg     平均值
    # sum     求和
8.分组聚合 group by
select * from 表 where 条件 group by 分组
例;
    # 查询岗位名以及岗位包含的所有员工名字
    # select post,group_concat(emp_name) from employee group by post;

    # 查询各部门年龄在20岁以上的人的平均薪资
    # select post,avg(salary) from employee where age>20 group by post;

9.过滤 having (group by + 聚合函数)
例子
 # 查询平均薪资大于1w的部门
 # select avg(salary) from employee group by post having avg(salary) > 10000


    # 1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
    # select post,emp_name,count(id) from employee group by post having count(id)<2

    # 2. 查询各岗位平均薪资大于10000的岗位名、平均工资
    # select post,avg(salary) from employee group by post having avg(salary) > 10000

    # 3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
    # select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;
  1. order by 排序
    # 升序
    #  select * from employee order by 排序的列名;
    #  select * from employee order by 排序的列名asc;
    # 降序
    #  select * from employee order by salary desc;

    # select * from employee order by age,salary;
    # select * from employee order by age,salary desc;
    # select * from employee order by age desc,salary;
  1. limit
select * from sc limit 1 # 第一条
select * from sc limit 0,30 # 前30条

    # select * from 表 order by 列 limit n; 取前n条
    # select * from 表 order by 列 limit m,n; 从m+1开始,取n条
    # select * from 表 order by 列 limit n offset m; 从m+1开始,取n条
  1. select * from 表 where 条件 group by 分组 having 过滤 order by 排序 limit n;

  2. 编码问题
# 编码问题
# 1.临时解决问题 在客户端执行 set xxxx = utf8;
# 2.永久解决问题 在my.ini添加 set xxxx = utf8;
# 3.实时解决问题 create table 表名() charset=utf8;

day38

1.今日内容

1.pymysql 模块

import pymysql
conn = pymysql.connect(host='127.0.0.1', 
                       	# ip地址
                       port=3306,
                       	# 端口号
                       user='root',
                       	# 用户名
                       password='123456',
                       	# 密码
                       database='db1',
                       	# 指定连接的库
                       charset='utf8'
                       	# 设置编码
                       ) 	
cursor = conn.cursor()
	# 默认输出元组格式
# cursor = conn.cursor(pymysql.cursors.DictCursor)    # cursor游标 cursor数据库操作符
	# 设置为字典格式输出
sql = "select * from sc"       # sql = 'insert into books values(%s,%s,%s,%s,%s)'
	# sql语句    只支持%s
ret = cursor.execute(sql) 
	# 执行sql语句
# ret = cursor.execute(sql,[user,pwd]) 
	# 防sql注入
#print(cursor.fetchone())
	# 拿去一条数据
#print(cursor.fetchall())
	# 拿去全部数据
#print(cursor.fetchmany(3)) 
	# 拿去指定条数据
for i in cursor.fetchall():
    # 迭代取值
    print(i)
#cursor.scroll(2,'absolute') 
	# 绝对移动光标
#cursor.scroll(2,'relative') 
	# 相对移动光标
conn.commit() # 进行增删改时需要进行提交
cursor.close() # 关闭光标
conn.close() # 关闭数据库连接

2.多表查询

连表
方式一
笛卡尔积
内连接(所有不在条件匹配内的数据,都会被剔除连表)
select * from 表1,表2 where  数据1 = 数据2;
例如:select * from employee,department where dep_id = department.i;
方式二
inner join
select * from 表1 inner join 表2 on 数据1 = 数据2;
例如:select * from employee inner join department on dep_id = department.id;
外连接
左外连接 left join
左边表为主表,副表数据如果无法对应主表,会通过null补齐
select * from 表1 left join 表2 on 数据1 = 数据2;
例如:select * from employee left join department on dep_id = department.id;
右外连接 right join
右边表为主表,副表数据如果无法对应主表,会通过null补齐
select * from 表1 right join 表2 on 数据1 = 数据2;
例如:select * from employee right join department on dep_id = department.id;
union 全外连接
表与表都连接 数据都会有
select * from 表1 union 表2 on 数据1 = 数据2;
子查询
例子;
  # 查询平均年龄在25岁以上的部门名
    # select name from department where id in (select dep_id from employee group by dep_id having avg(age)>25);

    # 查看技术部员工姓名
        # 先查询技术部的id
            # select id from department where name = '技术';
        # 根据技术部id查询employee表 找到技术部id对应的人名
            # select * from employee where dep_id = 200;
        # 结果
            # select name from employee where dep_id = (select id from department where name = '技术');

    # 查看不足1人的部门名(子查询得到的是有人的部门id)
        # 先从employee中查有多少个部门有人
            # select distinct dep_id from employee;
        # 从department表中把不在上述部门中的那些项找出来
            # select * from department where id not in (200,201,202,204);
        # 结果
            # select * from department where id not in (select distinct dep_id from employee);

    # 查询大于所有人平均年龄的员工名与年龄
        # 所有人的平均年龄
            # select avg(age) from employee;   # 28
        # 查大于上述平均年龄的人
            # select name,age from employee where age>28;
        # 结果
            # select name,age from employee where age>(select avg(age) from employee);
    # 查询大于部门内平均年龄的员工名、年龄
        # 查询各部门平均年龄
            # select dep_id,avg(age) from employee group by dep_id;
        # 查大于部门平均年龄的人
            # select * from employee where dep_id = 200 and age>18
            # select * from employee where dep_id = 201 and age>43
            # select * from employee where dep_id = 202 and age>28
            # select * from employee where dep_id = 204 and age>18
        # 结果
            # select * from employee inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t
            # on employee.dep_id = t.dep_id;
            #
            # select * from employee inner join (select dep_id,avg(age) as avg_age  from employee group by dep_id) as t
            # on employee.dep_id = t.dep_id where age>avg_age;
 

day39

1,今日内容

1.约束

  1. 非空 not null

    create table 表1(字段1 int not null,name char(12));
    	不写默认插入0
    create table 表1(字段1 int .name char(12) not null);
    	默认插入空字符串
    
    1. default 默认值

      create table 表1(id int,name char(12),sex enum('男','女)default '男')
      
      

      非空 和默认

      create table 表1(id int not null ,name char(12) not null,sex enum('男','女') not null default '男');
      
  2. 唯一约束 unique(不能重复)

    create table 表1(id int unique,name char(12 unique);
    

    联合唯一约束(不能同名同姓)

    create table t5(姓 char(12),名 char(12),unique(姓,名));
    

    唯一 + 非空 id name

    唯一加非空 第一个被设置了非空+唯一约束会被定义为主键 primary key

    create table t6 (id int not null unique ,name char(12) not null unique);
    
  3. 主键(primary key) 唯一性 不能有重复 比如 id =1 不能再重复

    # create table t6(id int primary key, name char(12) not null unique);
    # create table t5(family char(12) ,name char(12),primary key(family,name));  # 约束各自不能为空 且联合唯一 还占用了整张表的主键
    
  4. unsigned 无标点符号 约束用的

  5. 自增 auto_increment

    单独不可以 必须加上唯一或者主键 才会自增

    # delete from t7; 清空表数据但不能重置auto_increment
    # truncate table t7;  # 清空表并且重置auto_increment
    
    
    # create table t9(id int unique auto_increment, name char(12)) auto_increment=100000; ==>指定自增从10000开始
    
    # 修改auto_increment
        # alter table 表名 auto_increment = n; 修改表的auto_increment
        # alter table t7 auto_increment = 1000; 修改表的auto_increment
    
    

6.外键:foreign key

一、主键是能确定一条记录的唯一标识,比如,一条记录包括身份正号,姓名,年龄。身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。

外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。比如,A表中的一个字段,是B表的主键,那他就可以是A表的外键。

创建

foreign key(class_id) references class2(cid)); 关联(references)

# create table class2(cid int unique,cname char(12));   表id 必须是唯一的
# create table stu2(id int,name char(12),class_id int,foreign key(class_id) references class2(cid));

7.级联更新

foreign key(class_id) references class3(cid) on update cascade);

stu3 class3 级联更新
    # create table class3(cid int primary key,cname char(12));
    # create table stu3(id int,name char(12),class_id int,foreign key(class_id) references class3(cid) on update cascade);
    # insert into class3 values(1,'py27');
    # insert into stu3 values (1,'日魔',1),(2,'炮手',1)
    # update class3 set cid = 2; 修改了class3中的cid,stu3中相关的数据也会跟着变化,是on update(更新如果换成delete 就是级联删除) cascade关联字设置导致的

2.储存引擎

# show create table books;

# show engines;

# 什么是存储方式、存储机制(存储引擎)
    # 表结构 存在一个文件中  : 硬盘上
    # 表数据 存在另一个文件中、内存中
    # 索引(目录) 为了方便查找设计的一个机制 :

# 存储引擎的种类
    # innodb : 索引+数据 表结构  数据的持久化存储
        # 事务 :一致性 n条语句的执行状态是一致的
            # begin;   # 开启事务
            # select id from innot where id =1 for update;
            # update innot set id = 2 where id = 1;
            # commit;  # 提交事务 解锁被锁住的数据,让他们能够被修改
        # 行级锁 :只对涉及到修改的行加锁,利于并发的修改,但是对于一次性大量修改效率低下
        # 表级锁 :一次性加一把锁就锁住了整张表,不利于并发的修改,但是加锁速度比行锁的效率要高
        # 外键约束 :被约束表中的数据不能随意的修改/删除 约束字段据要根据被约束表来使用数据
    # myisam : 索引 数据 表结构  数据的持久化存储
        # 表级锁
    # memory : 表结构
        # 数据断电消失

# create table innot(id int) engine = innodb;
# create table myist(id int) engine = myisam;
# create table memot(id int) engine = memory;

day40

1.今日内容

1.表的修改
表的创建:create table
表的删除:drop table
表结构查询: desc 表名 table
表的修改: alter table

1.修改表名(整张表)

alter table 表名 rename 表名

2.修改编码

alter table 表名 charset 编码(utf8);

3.修改自增的位置

alter table 表名 auto_increment 自增的位置;

4.添加字段

alter table 表名 and 字段名  类型(长度) 约束;

5.删除某一个字段

alter table 表名 drop 字段名  

6.修改字段名

alter table 表名 change 字段名 新字段名 类型(长度) 约束

7.修改类型

alter table 表名 modify 字段名  新类型(新长度) 约束

8.修改字段顺序

name id age

id修改到第一个位置
alter table 表名 change id id类型(长度) 约束 first;

指定
alter table 表名 add 字段名 类型(长度) 约束 after 指定位置;   #不指定默认加在最右侧;
2.表与表之间的关系

表与表关联必须要靠外键,但是外键要关联表的子段必须要有主键;

# 一对多 foreign key
# create table class(id int primary key,cname char(12));
# create table student(id int primary key,sname char(16),cid int,
# foreign key(cid) references class(id));

# 多对多
# create table class(id int primary key,cname char(12));
# create table teacher(id int primary key,tname char(12));
# create table teach_cls(id int,cid int,tid int,
# foreign key(cid) references class(id)),
# foreign key(tid) references teacher(id))
# );

# 一对一
# create table guest(id int primary key,name char(12));
# create table student(id int primary key,sname char(12),gid int unique,
# foreign key(gid) referances guest(id));

3.索引原理
# 磁盘预读性原理
    # 1个block块 4096个字节/9ms

# 树
    # 树 根节点 分支节点 叶子节点
    # 平衡树 balance tree - B树

# 聚集索引/聚簇索引 : 叶子节点会存储整行数据 —— innodb的主键
# 辅助索引/非聚集索引 :除了主键之外的普通索引都是辅助索引,一个索引没办法查到整行数据,需要回聚集索引再查一次(回表)

# b+树 是为了更好的处理范围问题在b树的基础上有所优化
# mysql中innodb存储引擎的所有的索引树都是b+树

day41

索引

# 表的修改
    # 表的重命名
    # 表的编码
    # 添加字段
    # 删除字段
    # 移动字段
    # 字段的重命名
    # 字段的类型长度
    # 约束的修改
# 表与表之间的关系
    # 一对一 : unique + 外键
    # 一对多 : 外键
    # 多对多 : 产生了第三张表,第三张表中至少有两个外键,分别关联两张表
# 索引原理
    # 磁盘预读性原理 :每一次都磁盘都是有单位的,一次最少读取1block块
    # 树:根root,分支branch,叶子leaf
        # b树 balance tree
            # 1.数据存储在分支节点和叶子节点上(导致了树的高度增加,找到一个数据的时间不稳定)
            # 2.在查找范围的时候不够便捷
        # b+树
            # 1.数据不再存储在分支节点了,而是存储在叶子节点上(树的高度降低,找到所有数据的时间稳定)
            # 2.在叶子节点与叶子节点之间添加的双向指针提高了在查找范围的效率
    # 索引的两种存储方式
        # 聚集索引(聚簇索引):innodb中的主键
            # 数据直接存储在索引的叶子节点
        # 辅助索引(非聚集索引)
            # 数据不直接存储在索引的叶子节点
# 优缺点:
    # 优点 :加快查询速度
    # 缺点 :降低写的效率 ,占用更多的磁盘空间
# 索引 : index / unique / primary key
    # 操作索引 :创建和删除
        # 创建 :create index 索引名 on 表名(字段名);
            # create index ind_id on s1(id);
            # create index ind_id2 on s1(id);
        # 删除 :drop index 索引名  on 表名;
            # drop index ind_id2  on 表名;
    # 正确的使用索引(******)
        # 1.只有对创建了索引的列进行条件筛选的时候效率才能提高
        # 2.索引对应的列做条件不能参与运算、不能使用函数
        # 3.当某一列的区分度非常小(重复率高),不适合创建索引
        # 4.当范围作为条件的时候,查询结果的范围越大越慢,越小越快
        # 5.like关键字 : 如果使用%/_开头都无法命中索引
        # 6.多个条件 : 如果只有一部分创建了索引,条件用and相连,那么可以提高查询效率
                      # 如果用or相连,不能提高查询效率
            # and
                # select count(*) from s1 where id=1000000  and email = 'eva1000000@oldboy';
            # or
                # select count(*) from s1 where id=1000000  or email = 'eva1000000@oldboy';
        # 7.联合索引
            # creat index ind_mix on s1(id,name,email);
            # select count(*) from s1 where id=1000000  and email = 'eva1000000@oldboy';  快
            # select count(*) from s1 where id=1000000  or email = 'eva1000000@oldboy';   慢   条件不能用or
            # select count(*) from s1 where id=1000000;                                   快
            # select count(*) from s1 where email = 'eva1000000@oldboy';                  慢   要服从最左前缀原则
            # select count(*) from s1 where id>1000000  and email = 'eva1000000@oldboy';  慢   从使用了范围的条件开始之后的索引都失效
    # 基础概念(介绍)
        # explain 执行计划
            # explain select count(*) from s1 where id=1000000  and email = 'eva1000000@oldboy';
        # 覆盖索引
            # 在查询的过程中不需要回表 -- 覆盖索引 using index
            # explain select count(*) from s1 where id < 1000;
        # 索引合并
            # explain select count(*) from s1 where id=1000000  or email = 'eva1000000@oldboy';

24mysql

安装mysql步骤

  1. 配置环境变量

  2. 根目录创建my.ini配置文件

    *路径如果是\s或\n需要使用双斜杠

    [client]
    #设置mysql客户端默认字符集
    default-character-set=utf8 
    [mysql]
    # 设置mysql客户端默认字符集
    default-character-set=utf8 
    user = 'root'
    password = '123'
    [mysqld]
    #设置3306端口
    port = 3306 
    # 设置mysql的安装目录
    basedir=E:\mysql-5.6.45-winx64 
    # 设置mysql数据库的数据的存放目录
    datadir=E:\mysql-5.6.45-winx64\data 
    # 允许最大连接数
    max_connections=200
    # 服务端使用的字符集默认为8比特编码的latin1字符集
    character-set-server=utf8
    # 创建新表时将使用的默认存储引擎8
    default-storage-engine=INNODB
    
  3. 以管理员身份打开cmd切换到bin目录

  4. 安装mysql服务

    mysqld install
    
  5. 启动mysql

    net start mysql
    
  6. 登录mysql

    mysql -h主机名 -u用户名 -p密码
    
    设置密码 set password = password('123')
    

    第一次登录不需要填写密码直接回车就可以

  7. 修改密码

    set password for root@localhost = password('123'); 
    

    三种修改方式

    方法1: 用SET PASSWORD命令 
        首先登录MySQL,使用mysql自带的那个客户端连接上mysql。 
        格式:mysql> set password for 用户名@localhost = password('新密码'); 
        例子:mysql> set password for root@localhost = password('123'); 
        
    方法2:用mysqladmin  (因为我们将bin已经添加到环境变量了,这个mysqladmin也在bin目录下,所以可以直接使用这个mysqladmin功能,使用它来修改密码)
    
        关于mysqladmin的介绍:是一个执行管理操作的客户端程序。它可以用来检查服务器的配置和当前状态、创建和删除数据库、修改用户密码等等的功能,虽然mysqladmin的很多功能通过使用MySQL自带的mysql客户端可以搞定,但是有时候使用mysqladmin操作会比较简单。
        格式:mysqladmin -u用户名 -p旧密码 password 新密码 
        例子:mysqladmin -uroot -p123456 password 123  
        
    方法3:用UPDATE直接编辑那个自动的mysql库中的user表 
        首先登录MySQL,连接上mysql服务端。 
        mysql> use mysql;   use mysql的意思是切换到mysql这个库,这个库是所有的用户表和权限相关的表都在这个库里面,我们进入到这个库才能修改这个库里面的表。
        mysql> update user set password=password('123') where user='root' and host='localhost';   其中password=password('123') 前面的password是变量,后面的password是mysql提供的给密码加密用的,我们最好不要明文的存密码,对吧,其中user是一个表,存着所有的mysql用户的信息。
    
        mysql> flush privileges;  刷新权限,让其生效,否则不生效,修改不成功。
    

    忘记密码

    1 停掉MySQL服务端(net stop mysql)
    2 切换到MySQL安装目录下的bin目录下,然后手动指定启动程序来启动mysql服务端,指令: mysqld.exe --skip-grant-tables
    3 重新启动一个窗口,连接mysql服务端,
    4 修改mysql库里面的user表里面的root用户记录的密码:
    	update user set password = password('666') where user='root';
    5 关掉mysqld服务端,指令:
    	tasklist|findstr mysqld
    	taskkill /F /PID 进程号
    	
    6 正常启动服务端(net start mysql)
    

mysql指令

  1. 查看字符集编码的指令:

    show variables like "%char%";
    
  2. 查看储存引擎

    show engines;
    

    默认储存引擎是 Innodb

    mysql5.5之前的默认存储引擎,MyISAM引擎

操作库

  1. 查看所有库

    show databases;
    
  2. 创建库

    create database 库名 charset utf8;
    
  3. 删除库

    drop database 库名;
    
  4. 使用库

    use 库名;
    
  5. 修改数据库编码

    alter database 库名 charset 编码;
    

操作表

  1. 创建表

    create table 表名(列名 数据类型 约束条件);
    
  2. 查看当前库下全部的表

    show tables;
    
  3. 删除表

    drop table 表名;
    
  4. 查看表结构/详细结构

    describe 表名;
    describe 表名\G;
    
  5. 修改表名

    alter table 表名 rename 新表名;
    
  6. 增加列

    alter table 表名 add 列名 数据类型 约束条件;
    alter table 表名 add 列名 数据类型 约束条件 first; # 放到最前面
    alter table 表名 add 列名 数据类型 约束条件 after 列名; # 放到指定列后
    
  7. 删除列

    alter table 表名 drop 列名;
    
  8. 修改列

    alter table 表名 change 旧列名 新列名 数据类型 约束条件;
    
  9. 复制表

    create table 表名 select * from 旧表名;
    create table 表名 select * from 旧表名 where 1=2; # 复制表结构
    

基础数据类型

  1. 整型

    TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT

    作用:存储年龄,等级,id,各种号码等

    整形的宽度是显示限制,不够时用0填充,超出是显示最大限制

    设置无符号:unsigned

    1567156337977

  2. 浮点型

    FLOAT DOUBLE DECIMAL

    作用:存储薪资、身高、温度、体重、体质参数等

    float:

    ​ float(m,d)

    ​ 单精度浮点数(非准确小数值),m是整数部分+小数部分的 总个数,d是小数点后个数。m最大值为255,d最大值为30
    double:

    ​ double(m,d)

    ​ 双精度浮点数(非准确小数值),m是整数部分+小数部分的总个数,d是小数点后个数。m最大值也为255,d最大值也为30

    decimal:精度高,但是整数位数少

    ​ decimal(m[,d])

    ​ 准确的小数值,m是整数部分+小数部分的总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。比float和double的整数个数少,但是小数位数都是30位

  3. 日期类型

    DATE,TIME,DATETIME ,IMESTAMP,YEAR

    YEAR
    	YYYY(范围:1901/2155)2018
    DATE
    	YYYY-MM-DD(范围:1000-01-01/9999-12-31)例:2018-01-01 
    TIME
        HH:MM:SS(范围:'-838:59:59'/'838:59:59')例:12:09:32
    DATETIME
        YYYY-MM-DD HH:MM:SS(范围:1000-01-01 00:00:00/9999-12-31 23:59:59Y)
    TIMESTAMP
    	YYYYMMDD HHMMSS(范围:1970-01-01 00:00:00/2037 年某时)
    # DATETIME的日期范围是1001——9999年,TIMESTAMP的时间范围是1970——2038年。
    
  4. 字符串型

    char varchar

    char:定长,简单粗暴,浪费空间,存取速度快,范围0-255(字符)

    varchar:变长,精准,节省空间,存取速度慢,范围0-65535(字符)

    其他字符串类型:

    BINARY VARBINARY BLOB TEXT

    1567157014710

  5. 枚举类型

    enum:在给定的值中选一个

    create table 表名(enum('值1','值2','...'))
    
  6. 集合类型

    set:在给定的值中选多个

    create table 表名(col set('值1','值2','...'))
    insert into 表名 values('值1,值2,...')
    

表的增删改查

insert into 表名 values(值);

delete from 表名 where 条件;

update 表名 set 列名 = 值 where 条件;

  1. 查询全部

    select * from 表名;
    
  2. 查询指定列

    select 列名 from 表名;
    
  3. 按条件查询

    1. wehere

      select * from 表名 where 条件;
      select * from sc where id > 2 and id < 5
      
    2. in

      select * from sc where id in(1,3,5) 
      
    3. like

      select * from sc where age like '1%'; # %匹配任意个 _匹配一个
      
  4. concat

    select concat('编号:',id,'姓名:',name,'年龄:',age) as '全部信息' from sc; # 自定义显示方式
    
  5. group

    select age,count(age) from sc group by age; # 分组
    
  6. having

    select age,count(age)as num from sc group by age having num > 1; # 分组后再筛选
    
  7. distinct

    select distinct age from sc; # 去重,如果关键字后有多个字段则为去除这些字段之间相同的值
    
  8. oreder

    select * from sc order by id; # 排序,默认为asc 降序为desc
    
  9. limit

    select * from sc limit 1 # 第一条
    select * from sc limit 0,30 # 前30条
    
  10. 多表查询

    1. 笛卡尔积

      select * from t1,t2 where t1.id = t2.id;
      
    2. 连表查询

      1. inner join

        select * from t1 inner join t2 on t1.id = t2.id;
        
      2. left join:左边表为主表,副表数据如果无法对应主表,会通过null补齐

        select * from t1 left join t2 on t1.id = t2.id;
        
      3. right join:右边表为主表,副表数据如果无法对应主表,会通过null补齐

        select * from t1 right join t2 on t1.id = t2.id;
        
      4. union

        select * from t1 left join t2 on t1.id = t2.id union select * from t1 right join t2 on t1.id = t2.id;
        
    3. 子查询

      select * from tb1 where id in (select * from tb2 where sex = '女')
      

严格模式

模式设置和修改(以解决上述问题为例):

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

添加my.cnf如下:
[mysqld]			sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER

完整性约束

  1. 不为空:not null

    create table 表名(列名 数据类型 not null);
    
  2. 默认值:default

    create table 表名(列名 数据类型 default '默认值');
    
  3. 唯一:unique

    create table 表名(列名 数据类型 unique);
    
  4. 主键:primary key

    create table 表名(列名 数据类型 primary key);
    
  5. 自增:auto_increment

    create table 表名(列名 数据类型 primary key auto_increment);
    create table 表名(列名 数据类型 primary key auto_increment)auto_increment=5;# 设置起始值
    
  6. 外键:foreign key

    1. 表与表之间的关系:一对一 多对一 多对多

    2. 创建外键关系

      create table sex
      (seid int not null,primary key (seid));
      create table stu(id int not null,sex int,primary key (id));
      alter table stu add constraint FK_Reference_1 foreign key (sex)
         references sex (seid) 
            on delete restrict on update restrict
      
      create table sex(sexid int primary key,name varchar(55));
      create table stu(stuid int primary key,sex int,
                       constraint fk1 foreign key(sex) references sex(sexid));
      create table stu(stuid int primary key,sex int,
                       constraint 外键名 foreign key(当前表外键) references 外键表(外键表主键));
      
    3. 删除外键关系

      alter table 表名 drop foreign key	外键名
      
    4. 级联
      级联有三种模式:严格模式、cascade、set null

      严格模式:有外键约束时,被关联字段不能随意删除和修改(默认)

      cascade:有外键约束时,被关联字段被修改时,关联字段会随着修改

      ser null:有外键约束时,被关联字段被修改时,关联字段会为空

      constraint fk_t1_publish foreign key(pid) references publish(id) 
      	on delete cascade on update cascade; # 设置级联
      alter table stu add constraint FK_Reference_1 foreign key (sex)
      	references sex (seid) 
      	on delete restrict on update restrict; # 设置级联
      

pymysql

import pymysql
conn = pymysql.connect(host='127.0.0.1', 
                       	# ip地址
                       port=3306,
                       	# 端口号
                       user='root',
                       	# 用户名
                       password='123456',
                       	# 密码
                       database='db1',
                       	# 指定连接的库
                       charset='utf8'
                       	# 设置编码
                       ) 	
cursor = conn.cursor()
	# 默认输出元组格式
# cursor = conn.cursor(pymysql.cursors.DictCursor) 
	# 设置为字典格式输出
sql = "select * from sc"
	# sql语句
ret = cursor.execute(sql) 
	# 执行sql语句
# ret = cursor.execute(sql,[user,pwd]) 
	# 防sql注入
#print(cursor.fetchone())
	# 拿去一条数据
#print(cursor.fetchall())
	# 拿去全部数据
#print(cursor.fetchmany(3)) 
	# 拿去指定条数据
for i in cursor.fetchall():
    # 迭代取值
    print(i)
#cursor.scroll(2,'absolute') 
	# 绝对移动光标
#cursor.scroll(2,'relative') 
	# 相对移动光标
conn.commit() # 进行增删改时需要进行提交
cursor.close() # 关闭光标
conn.close() # 关闭数据库连接
posted @ 2020-03-05 13:28  赵刚、  阅读(133)  评论(0编辑  收藏  举报