zoukankan      html  css  js  c++  java
  • mysql系列学习 泽桐

    # 帮助
    help create user;
    # 查看当前用户
    select user();
    # 创建用户
    create user 'egon'@'localhost' identified by '123';
    create user 'alex'@'%' identified by '123';
    create user 'ton'@'192.168.1.%' identified by '123';
    # 授权(直接创建用户后面加上identified by '123')
    grant select on *.* to 'egon'@'localhost' identified by '123';
    grant select (id,name),update (name) on db1.t1 to 'egon'@'localhost';
    flush privileges;
    # 回收权限
    revoke select on db1.* from 'egon'@'localhost';
    # 权限对应表
    mysql.db/mysql.user/mysql.table_priv/mysql.columns_priv
    update mysql.user set authentication_strings=password('123') where user='root' and host='localhost';
    # 远程连接
    mysql -h192.168.1.1 -ualex -p123
    # 增删改查库(文件夹)
    create database db1 charset utf8;
    show create database db1;
    alter database db1 charset gbk;
    drop database db1;
    # 增删改查表(文件)
    use db1;
    create table t1(id int primary key auto_increment,name char(10) not null unique)engine=innodb default charset utf8;
    show tables;
    show create table t1;
    alter table t1 add age int;
    alter table t1 drop age int;
    alter table t1 modify id int primary key auto_increment;
    alter table t1 charset utf8;
    drop table t1;
    # 查看表结构
    describe t1; # desc
    # 操作文件内容(增删改查)
    insert into db1.t1(id,name) values(1,'egon'),(2,'egon2');
    truncate t1; # 数据量比较大情况下,删除速度快
    # 拷贝表结构和记录(键不会拷贝),创建一个新表
    create table t_copy select * from t1;
    # 只拷贝表结构,不拷贝记录
    create table t_copy select * from t1 where 1=2;
    # 查看编码
    \s
    # 以行显示
    ;前加上\G

    一、数据类型
    1、整数类型
    TINYINT SMALLINT MEDIUMINT INT BIGINT
    注意:为该类型指定宽度时,仅仅只是指定查询结果的显示宽度,与存储范围无关
    create table t7(x int(3) zerofill);前面8位用0填充(默认int(11))
    2、浮点型
    定点数类型 DEC等同于DECIMAL  
    浮点类型:FLOAT DOUBLE
    create table t4(salary float(5,2));#5代表有效数字位,2代表小数位
    insert into t4 values (-3.33);
    3、字符串类型(宽度既是字符数)
    char:定长,简单粗暴,浪费空间,存取速度快
    varchar:可变长,精准,节省空间,存取速度慢
    4、日期
    datetime 2017-01-01 10:00:00
    date:2017-01-01
    time:10:00:00
    year:2017
    insert into student values(1,'alex',now(),now(),now(),now());
    insert into student values(1,'alex','2017-01-01','2017','2017-01-01 10:00:00','10:00:00');
    insert into student values(1,'alex','2017/01/01','2017','2017-01-01 10:00:00','10:00:00');
    insert into student values(1,'alex','20170101','2017','20170101100000','100000');
    5、枚举与集合(set可取多个)
    create table student(sex enum('male','female'),hobbies set('music','read'));
    insert into student values('male','music,read');
    insert值不在范围内则存为空

    二、表约束条件
    1、not null、default
    create table student(
    sex enum('male','female')not null default 'male',
    hobbies set('music','read'));
    2、unique
    #多列唯一
    create table services(
    name char(10),
    host char(15),
    port int,
    constraint host_port unique(host,port));
    3、auto_increment
    auto_increment_offset偏移量(起始值),auto_increment_increment步长
    #步长,对指定表生效
    create table services(
    id int primary key auto_increment)
    auto_increment=10;
    #查看变量
    show variables like '%auto_in%';
    #对当前回话生效
    set session auto_increment_offset=200;
    set session auto_increment_increment=2;
    #所有回话生效
    set global auto_increment_offset=200;
    set global auto_increment_increment=2;
    注意:偏移量不能大于步长,否则偏移量会被忽略,默认从1开始
    4、foreign key (on delete cascade 删除操作联动)
    create table emp_info(
    ...
    dep_id int,
    constraint fk_depid_id foreign key(dep_id) references dep_info(id)
    on delete cascade
    on update cascade
    );
    create table dep_info(
    id int primary key auto_increment,
    ...
    );

    三、表查询
    1、单表查询
    1)group by
    #聚合列
    select depart_id,group_concat(name) from employee group by depart_id;
    #计数
    select depart_id,count(name) from employee group by depart_id;
    #最大值,最小值min,sum,avg
    select depart_id,max(name) from employee group by depart_id;
    2)关键字的执行优先级(重点)
    from
    where
    group by
    按照select后的字段取新的虚拟表,有聚合函数则将组内数据进行聚合
    having
    distinct
    order by
    limit
    3)limit(做分页)
    select * from emp limit 0,3;#起始,步长(1-3)
    4)distinct
    select distinct sex from emp;
    5)select字段上做运算
    select name,salary*12 年薪(annual_salary) from emp;

    2、多表查询
    1)简单查询
    #笛卡尔积拼成一张虚拟表
    select * from department,employee;
    #内连接:按照on条件取相同部分
    select * from department,employee where department.id=employee.dep_id;
    select * from employee inner join department on department.id=employee.dep_id;
    #左连接:按照on条件取相同部分再保留左表的记录
    select * from employee left join department on department.id=employee.dep_id;
    #右连接:按照on条件取相同部分再保留右表的记录
    select * from employee right join department on department.id=employee.dep_id;
    #full连接:按照on条件取相同部分再保留左右两表的记录
    select * from employee left join department on department.id=employee.dep_id
    union
    select * from employee right join department on department.id=employee.dep_id;

    2)子查询
    select * from employee where dep_id in (select id from department where name in ('技术','销售'));

    四、索引
    1、原理
    目的在于提高查询效率,本质是不断缩小想要获取的数据的范围来筛选结果。
    2、索引的数据结构
    B+树是通过二叉查找树,再由平衡二叉树,B树演化而来
    ###b+树性质
    1.索引字段要尽量的小
    2.索引的最左匹配特性

    五、MySQL索引管理
    1、MySQL常用的索引

    普通索引INDEX:加速查找

    唯一索引:
    -主键索引PRIMARY KEY:加速查找+约束(不为空、不能重复)
    -唯一索引UNIQUE:加速查找+约束(不能重复)

    联合索引:
    -PRIMARY KEY(id,name):联合主键索引
    -UNIQUE(id,name):联合唯一索引
    -INDEX(id,name):联合普通索引

    2、索引的两大类型hash与btree
    hash类型的索引:查询单条快,范围查询慢
    btree类型的索引:b+树,层数越多,数据量指数级增长(我们就用它,因为innodb默认支持它)

    3、创建/删除索引的语法
    创建索引
    创建表时:
    create table s1(
    id int,
    name char(6),
    index(id)#没有约束的普通索引只能加在最后
    );
    创建表后:
    create index name on s1(name);
    create index id_name on s1(id,name);#联合普通索引
    create unique index name on s1(name);

    删除索引
    drop index name on s1;

    4、正确使用索引
    1 范围问题
    2 尽量选择区分度高的列作为索引
    3 =和in可以乱序
    4 索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把
    所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)
    5 and/or
    条件:
    a = 10 and b = 'xxx' and c > 3 and d =4
    索引:
    制作联合索引(d,a,b,c)
    条件:
    a = 10 or b = 'xxx' or c > 3 or d =4
    索引:
    制作联合索引(d,a,b,c)

    6 最左前缀匹配原则

    联合索引的第二个好处是在第一个键相同的情况下,已经对第二个键进行了排序处理

    5、慢查询优化的基本步骤
    0.先运行看看是否真的很慢,注意设置SQL_NO_CACHE
    1.where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高
    2.explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
    3.order by limit 形式的sql语句让排序的表优先查
    4.了解业务方使用场景
    5.加索引时参照建索引的几大原则
    6.观察结果,不符合预期继续从0分析

    6、慢日志管理
    慢日志
    - 执行时间 > 10
    - 未命中索引
    - 日志文件路径

    配置:
    - 内存
    show variables like '%query%';
    show variables like '%queries%';
    set global 变量名 = 值
    - 配置文件
    mysqld --defaults-file='E:\wupeiqi\mysql-5.7.16-winx64\mysql-5.7.16-winx64\my-default.ini'

    my.conf内容:
    slow_query_log = ON
    slow_query_log_file = D:/....

    注意:修改配置文件之后,需要重启服务


    六、数据库备份与恢复
    #1. 物理备份: 直接复制数据库文件,适用于大型数据库环境。但不能恢复到异构系统中如Windows。
    #2. 逻辑备份: 备份的是建表、建库、插入等操作所执行SQL语句,适用于中小型数据库,效率相对较低。
    #3. 导出表: 将表导入到文本文件中。
    1、使用mysqldump实现逻辑备份
    #语法:
    # 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

    二、恢复逻辑备份
    #方法一:
    mysql -uroot -p123 < /backup/all.sql
    mysql -uroot -p123 db1 < /backup/db1.sql
    #方法二:
    mysql> use db1;
    mysql> SET SQL_LOG_BIN=0;
    mysql> source /root/db1.sql
    三、备份/恢复案例
    四、实现自动化备份
    五、表的导出和导入
    六、数据库迁移
    http://www.cnblogs.com/linhaifeng/articles/7525619.html


    七、pymysql模块
    1、execute使用
    pip3 install pymysql
    import pymysql
    user = input('user>>').strip()
    pwd = input('password>>').strip()
    conn = pymysql.connect(host='localhost',user='root',password='123456',database='day47',charset='utf8')
    cursor = conn.cursor() # 游标既mysql>
    #执行sql
    sql = 'select * from user where user=%s and password=%s;'
    rows = cursor.execute(sql, [user,pwd])
    print('%s rows in set'%rows) #打印rows是受影响行数
    cursor.close()
    conn.close()
    if row:
    print('sucessful')
    else:
    print('failed')

    2、增删改
    sql = 'insert into user(name,password) values(%s,%s);'
    rows = cursor.executemany(sql, [(user,pwd),(user,pwd)]) #相当于自动循环列表执行execute
    print(cursor.lastrowid)#查询最后的自增长ID
    print('%s rows in set'%rows) #打印rows是受影响行数
    conn.commit()

    3、查fetchone,fetchmany,fetchall,没有返回None
    sql = 'select * from user;'
    rows = cursor.execute(sql)
    res1 = cursor.fetchone()#元组
    res2_4 = cursor.fetchmany(3)#元组嵌套元组,没有返回None
    print('%s rows in set'%rows) #打印rows是受影响行数
    conn.commit()

    4、光标移动
    cursor.scroll(0,mode='absolute')#绝对位置
    cursor.scroll(0,mode='relative')#相对位置


    八、视图
    定义:视图就是一张虚拟表,把经常查询的sql语句存为视图方便再次使用
    1、语法:
    create view user_dep
    as
    select user.id uid,user.name uname,dep.id depid,dep.name depname
    from user left join dep on user.dep_id=dep.id;
    #查看视图
    show create table user_dep;
    #修改视图
    alter view user_dep as 新查询语句;

    九、触发器
    create
    TRIGGER trigger_name
    trigger_time trigger_event
    on tb1_name for each row
    begin
    ...;
    end

    delimiter //
    create
    TRIGGER tri_after_insert_cmd_log
    after insert
    on cmd_log for each row
    begin
    if new.is_success='no' then
    insert into err_log(cmd_name,sub_time) values(NEW.cmd_name,NEW.sub_time);
    end if;
    end //
    delimiter ;

    #删除触发器
    delete trigger trigger_name;

    十、事务
    事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。
    start transaction;

    rollback; #如果任一sql异常,可用此命令回滚
    commit; #如果所有sql正常,可用此命令提交


    十一、存储过程
    存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql
    1、无参数
    delimiter //
    create procedure procedure_name()
    begin
    ...
    end //
    delimiter ;
    #调用存储过程
    call procedure_name();
    cursor.callproc('p1');

    2、有参数
    delimiter //
    create procedure procedure_name(
    in min int,
    in max int,
    out res int
    )
    begin
    select * from test where id between min and max;
    set res=1;
    end //
    delimiter ;

    #调用存储过程
    set @n=1 #全局变量
    call p1(3,7,@n);
    select @n; #查看变量值

    #python调用
    import pymysql
    conn = pymysql.connect(host='localhost',user='root',password='123456',database='db1',charset='utf8')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    res = cursor.callproc('p1', args=(3,7,随意)) #_p1_0=3,_p1_1=7,_p1_2=123
    conn.commit()
    print(res.fetchall()) #只能拿到存储过程的select结果
    rows = cursor.execute('select @_p1_0,@_p1_1,@_p1_2')
    print(cursor.fetchall())
    cursor.close()
    conn.close()

    #inout参数
    delimiter //
    create procedure p1(
    inout m int
    )
    begin
    select * from test where id > m;
    set m=1;
    end //
    delimiter ;

    #mysql
    set @x=2
    call p1(@x)
    select @x

    3、查看存储过程
    show create procedure p1\G
    #查看所有存储过程(某一类用like)
    show procedure status like 'p1%';

    4、删除存储过程
    drop procedure proc_name;

    十二、存储过程应用于事务
    delimiter //
    create PROCEDURE p5(
    OUT p_return_code tinyint
    )
    BEGIN
    DECLARE exit handler for sqlexception
    BEGIN
    -- ERROR
    set p_return_code = 1;
    rollback;
    END;

    DECLARE exit handler for sqlwarning
    BEGIN
    -- WARNING
    set p_return_code = 2;
    rollback;
    END;

    START TRANSACTION;
    DELETE from tb1; #执行失败
    insert into blog(name,sub_time) values('yyy',now());
    COMMIT;

    -- SUCCESS
    set p_return_code = 0; #0代表执行成功

    END //
    delimiter ;

    #在mysql中调用存储过程
    set @res=123;
    call p5(@res);
    select @res;

    #在python中基于pymysql调用存储过程
    cursor.callproc('p5',(123,))
    print(cursor.fetchall()) #查询select的查询结果

    cursor.execute('select @_p5_0;')
    print(cursor.fetchall())

    十二、函数
    1、内置常用函数
    1)数学函数
    ROUND(x,y)
    返回参数x的四舍五入的有y位小数的值

    RAND()
    返回0到1内的随机值,可以通过提供一个参数(种子)使RAND()随机数生成器生成一个指定的值。

    2)聚合函数(常用于GROUP BY从句的SELECT查询中)
    AVG(col)返回指定列的平均值
    COUNT(col)返回指定列中非NULL值的个数
    MIN(col)返回指定列的最小值
    MAX(col)返回指定列的最大值
    SUM(col)返回指定列的所有值之和
    GROUP_CONCAT(col) 返回由属于一组的列值连接组合而成的结果

    3)字符串函数
    CHAR_LENGTH(str)
    查看字符数。
    CONCAT(str1,str2,...)
    字符串拼接
    如有任何一个参数为NULL ,则返回值为 NULL。
    CONCAT_WS(separator,str1,str2,...)
    字符串拼接(自定义连接符)
    CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。

    CONV(N,from_base,to_base)
    进制转换
    例如:
    SELECT CONV('a',16,2); 表示将 a 由16进制转换为2进制字符串表示
    FORMAT(X,D)
    将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若 D 为 0, 则返回结果不带有小数点,或不含小数部分。
    例如:
    SELECT FORMAT(12332.1,4); 结果为: '12,332.1000'
    INSERT(str,pos,len,newstr)
    在str的指定位置插入字符串
    pos:要替换位置其实位置
    len:替换的长度
    newstr:新字符串
    特别的:
    如果pos超过原字符串长度,则返回原字符串
    如果len超过原字符串长度,则由新字符串完全替换
    INSTR(str,substr)
    返回字符串 str 中子字符串的第一个出现位置。

    LEFT(str,len)
    返回字符串str 从开始的len位置的子序列字符。
    LOWER(str)
    变小写
    UPPER(str)
    变大写
    REVERSE(str)
    返回字符串 str ,顺序和字符顺序相反。

    SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len)
    不带有len 参数的格式从字符串str返回一个子字符串,起始于位置 pos。带有len参数的格式从字符串str返回一个长度同len字符相同的子字符串,起始于位置 pos。 使用 FROM的
    格式为标准 SQL 语法。也可能对pos使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。在以下格式的函数中可以对pos 使用一个负值。


    4)日期和时间函数
    CURDATE()或CURRENT_DATE() 返回当前的日期
    CURTIME()或CURRENT_TIME() 返回当前的时间
    DAYOFWEEK(date) 返回date所代表的一星期中的第几天(1~7)
    DAYOFMONTH(date) 返回date是一个月的第几天(1~31)
    DAYOFYEAR(date) 返回date是一年的第几天(1~366)
    DAYNAME(date) 返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);
    FROM_UNIXTIME(ts,fmt) 根据指定的fmt格式,格式化UNIX时间戳ts
    HOUR(time) 返回time的小时值(0~23)
    MINUTE(time) 返回time的分钟值(0~59)
    MONTH(date) 返回date的月份值(1~12)
    MONTHNAME(date) 返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);
    NOW() 返回当前的日期和时间
    QUARTER(date) 返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE)
    WEEK(date) 返回日期date为一年中第几周(0~53)
    YEAR(date) 返回日期date的年份(1000~9999)

    5)加密函数
    MD5()
    计算字符串str的MD5校验和
    PASSWORD(str)
    返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。

    6)控制流函数
    CASE WHEN[test1] THEN [result1]...ELSE [default] END
    如果test1是真,则返回result1,否则返回default

    CASE [test] WHEN[val1] THEN [result]...ELSE [default]END
    如果test和val1相等,则返回result,否则返回default

    IF(test,t,f)
    如果test是真,返回t;否则返回f

    IFNULL(arg1,arg2)
    如果arg1不是空,返回arg1,否则返回arg2

    NULLIF(arg1,arg2)
    如果arg1=arg2返回NULL;否则返回arg1
    isnull(arg)
    空返回true


    内置函数重点:
    1、char_length:查看字符数
    select char_length(name) from t1;
    #设置填充字符模式为全字符匹配模式
    set sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
    2、length:查看字节数
    3、date_format
    select date_format('2017-01-01 11:11:11','%Y-%m-%d %H:%i:%S')
    example:
    提取sub_time字段的值,按照格式后的结果即"年月"来分组
    SELECT DATE_FORMAT(sub_time,'%Y-%m'),COUNT(1) FROM blog GROUP BY DATE_FORMAT(sub_time,'%Y-%m');

    4、自定义函数
    delimiter //
    create function f1(
    x int,
    y int)
    returns int
    begin
    declare num int;
    set num = x + y;
    return (num);
    end //
    delimiter ;
    #删除函数
    drop function func_name;
    #执行函数
    select UPPER('egon') into @res;
    SELECT @res;
    # 在查询中使用
    select f1(11,nid),name from tb2;


    十三、流程控制
    1、条件语句
    delimiter //
    create function f5(
    i int
    )
    returns int
    begin
    declare res int default 0;
    if i = 10 then
    set res=100;
    elseif i = 20 then
    set res=200;
    elseif i = 30 then
    set res=300;
    else
    set res=400;
    end if;
    return res;
    end //
    delimiter ;

    2、循环语句
    delimiter //
    CREATE PROCEDURE proc_while ()
    BEGIN

    DECLARE num INT ;
    SET num = 0 ;
    WHILE num < 10 DO
    SELECT
    num ;
    SET num = num + 1 ;
    END WHILE ;

    END //
    delimiter ;

    # my.ini

    [client]
    default-character-set=utf8
    user='root'
    password='123456'

    [mysql]
    default-character-set=utf8

    [mysqld]
    character_set_server=utf8
    secure_file_priv='E:\\'

  • 相关阅读:
    France '98
    【笔记】《通俗详细地讲解什么是P和NP问题》的概念记录
    130831组队赛-Regionals 2011, Asia
    Android 解屏幕锁与点亮屏幕
    Android 点亮屏幕
    利用FFT 计算生成离散解析信号
    hdu5246 超级赛亚ACMer
    用srvctl命令配置service
    MySQL优化之——权限管理
    JS 点击复制Copy插件--Zero Clipboard
  • 原文地址:https://www.cnblogs.com/linzetong/p/8331201.html
Copyright © 2011-2022 走看看