MySQL自增列的步长问题

唯一索引和联合唯一

外键的变种

SQL数据行的增删改查

视图

触发器

函数

存储过程

事务

游标

动态执行SQL(防SQL注入)

 
 
 


1.MySQL自增列的步长问题:
1.基于会话级别(单次登陆状态下):

show session variables like ‘auto_inc%’;    #查看自增长的默认步数,一般为1
set session auto_increment_increment=2;    #设置自增长会话步长为2
set session auto_increment_offset=10;    #设置默认自增长初始值

2.基于全局级别(所有用户生效):

show global variables like ‘auto_inc%’;    #查看全局变量中的自增长的默认步长
set global auto_increment_increment=2;    #设置全局会话步长
set global auto_increment_offset=10;    #设置全局自增长初始值

 


2.唯一索引和联合唯一:

create table t1(
    id int,
    num int,
    name char
    unique uql (num)    #唯一索引
    unique uql (num, name)    #联合唯一
    );

唯一索引和主键 的共同点:
    1.都有加速查找的功能;
    2.都是唯一,不能重复
唯一索引和主键的不同点:
    主键既不能重复也不能为空;
    而唯一索引不能重复,但是可以有值为空,比如联合索引中可以设置一个值为null

 


3.外键的变种:
1.一对一:博客用户表
2.一对多:百合网相亲记录表
3.多对多:用户主机关系表
MySQL自增列的步长问题-风君雪科技博客

 


4.SQL数据行的增删改查:
增:

insert into test(name, age) values(‘name’, 18);
insert into test(name, age) values(‘name1’, 18),(‘name2’, 18);    #一次性插入多个值
insert into test(name, age) select name,age from test1;    #把某张表中的数据插入

删:

delete from test;
delete from test where id>2 and name=’name1′;

改:

updata test set name=’name2′,age=19 where id>12 and name=’name1′;

查:

select * from test;
select id,name from test where id>2;
select name,age,123 from test;
select name as rname from test;
select * from test where id in (1,3,5,7);
select * from test where id in (select id from test1);
select * from test where id between 5 and 9;    #闭区间,左右都可以取到
通配符
select * from test where name like ‘name%’;    %匹配无数字符;_匹配一个字符
分页
select * from test limit 10;    取前十条
select * from test limit 0,10;    表示从0开始,取0后面的10条
select * from test limit 10 offset 20;    表示从20开始,取20后的前10条
排序
select * from test order by id desc;    id从大到小排列
select * from test order by id asc;    id从小到大排列
select * from test order by age desc, id asc;    多个不同排序
select * from test order by desc limit 10;    取后十条
分组(聚合函数:count,max,min,sum,avg求平均值)
select max(id),id from test group by sex;    如果遇到相同的sex,只会取最大id的
select count(id),id from test group by sex;    计数
select count(id) as count,id form test group by sex;
select count(id),id from test group by sex having count(id)>2;    对于聚合函数结果进行二次筛选时,必须使用having

连表操作:

#左右连表 join
select * from test1,test2 where test1.id = test2.part_id;
select * from test1 left join test2 on test1.id = test2.part_id;     test1左边会全部显示
select * from test right join test2 on test1.id = test2.part_id;    test1右边会全部显示
select * from test innder join test2 on test1.id = test2.part_id;    会把出现null的那一行隐藏

#上下连表 union
select id,name from test1
union    #自动去重
select id,name from test2;
select id,name from test1
union all    #不去重
select id,name from test2;

转储mysql文件:

mysqldump -uroot test1  > test1.sql -p    #数据表结构+数据
mysqldump -uroot -d test1  > test1.sql -p    #只有数据表结构
导入mysql文件:
create databases test1;
mysqldump -uroot -d test1 < test1.sql -p;

临时表

select id from (select id from test where num>60) as B;

添加条件

select min(num),min(num)+1,case when num<10 then 0 else min(num) end from score

 


5.视图:

#创建
create view as view1 select * from test where id>10;
#视图是一个临时表
#视图是虚拟出来的,不是物理表,因此不能插入数据

#修改
alter view 视图名称 as SQL

#删除
drop view 视图名称;

 


6.触发器:

#插入前
create trigger t1 BEFORE INSERT on student for EACH ROW
BEGIN
INSERT into teacher(tname) values(NEW.sname);
END
#插入后 after insert
#删除前 before delete
#删除后 after delete
#更新前 before update
#更新后 after update
#由于默认;结束,因此不会执行end,所以要执行触发器之前要先修改终止符
 
delimiter //
create trigger t1 BEFORE INSERT on student for EACH ROW
BEGIN
INSERT into teacher(tname) values(sname);
END //
delimiter ;

#创建时自动插入:
drop trigger t1;    #结束上一个触发器
delimiter //
create trigger t1 BEFORE INSERT on student for EACH ROW
BEGIN
INSERT into teacher(tname) values(NEW.sname);
END //
delimiter ;
 
insert into student(gender,class_if,sname) values(‘女’,1,’abc’)

 


7.函数:

#自定义函数(有返回值)
#创建函数
delimiter \
create function f1(
    i1 int,
    i2 int)
returns int
BEGIN
    declare num int;    声明一个变量类型是整数
    set num = i1 + i2;
    return(num);
END \
delimiter ;
#运行函数
select f1(1,100);

内置函数:
时间重点

 


8.SQL存储过程:

1.简单存储过程

delimiter //
create PROCEDURE p1()
BEGIN
    select * from student;
    insert into teacher(tname) values(‘ct’);
END
delimiter ;
#调用存储过程
call p1;
cursor.callproc(‘p1’)

2.传参数(in,out,inout)

delimiter //
create PROCEDURE p2(
    in n1 int,
    in n2 int
)
BEGIN
    select * from student where sid>n1;
END
#调用
call p2(12,2);
cursor.callproc(‘p2’,(12,2))

delimiter //
create PROCEDURE p2(
    in n1 int,
    out n2 int    #out伪装返回值
)
BEGIN
    set n2 = 123123;
    select * from student where sid>n1;
END
#调用
set @vi = 0     #创建了一个session级的变量叫做v1,可以在外部接收
call p2(12,@v1)
select @v1;    接收变量
cursor.execute(‘select @_p2_0,@_p2_1’)    #pymysql中接收存储过程变量

存储过程的特性:
    a.可传参 (in out inout)
    b.pymysql
为什么有结果值又有out伪造的返回值:
    out的作用:用于标识存储过程的执行结果,如1为失败,2为成功,3为局部成功

 


9.事务:

delimiter //
create procedure p4(
    out status int
)
BEGIN
    1.声明如果出现异常则执行{
        set status = 1;
        rollback;    #回滚
    }
    开始事务
        –a账户减少100
        –b账户增加100
        commit;
    结束
    set status = 2;
    #如果这里的事务执行顺利,会得到变量等于2,不会执行回滚
END //
delimiter ;

delimiter \
create PROCESDURE p1(
    out p_return_code tinyint
)
BEGIN
    declare exit handler for sqlexception    #这样代码的意思是如果没有顺利执行,就执行下面的代码
    BEGIN
        — ERROR
        set p_return_code = 1;
        rollback;
    END;
    
    START TRANSACTION;
        DELETE from tb1;
        insert into tb2(name) values(‘seven’);
    COMMIT;
    
    –SUCCESS
    set p_return_code = 0;
    
    END\
delimiter ;
#正确的返回0,错误的返回1

 


10.游标:

delimiter //
create procedure p6()
begin
    declare row_id int;    –自定义变量1
    declare row_num varchar(50);    –自定义变量2
    declare done INT DEFAULT FALSE;  
 
    declare my_cursor CURSOR FOR select id,num from A;
    declare CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;  
 
open my_cursor;    #打开游标
    xxoo: LOOP    #开始循环
        fetch my_cursor into row_id,row_num;    #取一行数据赋值给row_id和row_num
        if done then
            leave xxoo;
        END IF;
        insert into teacher(tname) values(ssname);
    end loop xxoo;    #终止循环
close my cursor;    #关闭游标
 
end //
delimter;

 


11.动态执行SQL(防SQL注入):

delimiter //
create procefure p7(
    in tpl varchar(255),
    in arg int
)
begin
    1.预检测某个东西,SQL语句合法化
    2.SQL = 格式化 tp+arg
    3.执行SQL语句
    
   set @x0 = arg;   #声明变量
   PREPARE(准备) XXX(变量) FROM ‘select * from student where sid > ?’;
    EXECUTE(执行) xxx USING @arg(替换上面的?);
    DEALLOCATE prepare prod;(执行已经格式化完成的SQL语句)
 
end //
delimter;
 
call p7(‘select * from tb where id > ?’,9)

delimiter \
            CREATE PROCEDURE p8 (
                in nid int
            )
            BEGIN
                set @nid = nid;
                PREPARE prod FROM ‘select * from student where sid > ?’;
                EXECUTE prod USING @nid;
                DEALLOCATE prepare prod;
            END\
            delimiter ;