MySQL自增列的步长问题

  1. 唯一索引和联合唯一
  2. 外键的变种
  3. SQL数据行的增删改查
  4. 视图
  5. 触发器
  6. 函数
  7. 存储过程
  8. 事务
  9. 游标
  10. 动态执行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.多对多:用户主机关系表


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 ;

原文地址:https://www.cnblogs.com/changwoo/p/9568534.html

时间: 2025-01-14 07:56:33

MySQL自增列的步长问题的相关文章

Mysql 自增列 主键

Mysql中假如有 ID Int auto_increment, CID varchar(36). 通常情况下都是 ID设置为主键. 假如要设置CID为主键.自增列ID必需是唯一索引. create table Temp ( ID bigint not null auto_increment comment '编号', CID varchar(36) not null, CreateTime datetime not null default now() comment '创建时间', uniq

怎么重置mysql的自增列AUTO_INCREMENT初时值

重置 MySQL 自增列 AUTO_INCREMENT 初时值 注意, 使用以下任意方法都会将现有数据删除. 方法一: delete from tb1; ALTER TABLE tbl AUTO_INCREMENT = 100; 1 2 (好处, 可以设置 AUTO_INCREMENT 为任意值开始) 提示:如果表列和数据很多, 速度会很慢, 如90多万条, 会在10分钟以上. 方法二: truncate tb1; 1 (好处, 简单, AUTO_INCREMENT 值重新开始计数.) 怎么重置

开发人员改主键自增列起始值多了个0 !!!

2017-07-23 晚21:21接到开发打来的电话说mysql自增列改大后还能修改吗? 原由:因领导说要保留id 99999和 98888这样的id号 自己用,然后开发就自己改了user_login_account表自增列起始值,开发本想改成100002,然而他多加了一个0,搞成了1000002,这就有点杯具了, 于是开发想试图搞这个值改小成100002,结果改不回来了,他就找到我处理.本想 1 首先和开发沟通后确定影响到了2张表,一个表是user_login_account的自增id列,另一

MySQL AutoIncrement--自增锁模式

自增锁模式 在MYSQL 5.1.22版本前,自增列使用AUTO_INC Locking方式来实现,即采用一种特殊的表锁机制来保证并发插入下自增操作依然是串行操作,为提高插入效率,该锁会在插入语句完成后立即释放,而不是插入语句所在事务提交时释放.该设计并发性能太差,尤其在大批量数据在一条语句中插入时(INSERT SELECT ), 会导致该语句长时间持有这个“表锁”,从而阻塞其他事务的插入操作. 在MYSQL 5.1.22版本开始,InnoDB存储引使用一种轻量级互斥锁(Mutex)来控制自增

mysql 清空或删除表数据后,控制表自增列值的方法

http://blog.sina.com.cn/s/blog_68431a3b0100y04v.html 方法1: truncate table 你的表名 //这样不但将数据全部删除,而且重新定位自增的字段 方法2: delete from 你的表名 dbcc checkident(你的表名,reseed,0) //重新定位自增的字段,让它从1开始 方法3: 如果你要保存你的数据,介绍你第三种方法,by QINYI 用phpmyadmin导出数据库,你在里面会有发现哦 编辑sql文件,将其中的自

mysql中InnoDB表为什么要建议用自增列做主键

InnoDB引擎表的特点 1.InnoDB引擎表是基于B+树的索引组织表(IOT) 关于B+树 (图片来源于网上) B+ 树的特点: (1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的; (2)不可能在非叶子结点命中; (3)非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层; 2.如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引.如果没有显式定义主键,则InnoDB会选择第一个不包含有NU

[MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键

[MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键 http://imysql.com/2014/09/14/mysql-faq-why-innodb-table-using-autoinc-int-as-pk.shtml 我们先了解下InnoDB引擎表的一些关键特征: InnoDB引擎表是基于B+树的索引组织表(IOT): 每个表都需要有一个聚集索引(clustered index): 所有的行记录都存储在B+树的叶子节点(leaf pages of the tree):

MySQL使用AUTO_INCREMENT列的表注意事项之update自增列篇

1. 说明 (1)对于MyISAM表,如果用UPDATE更新自增列,如果列值与已有的值重复,则会出错:如果大于已有的最大值,则会自动更新表的AUTO_INCREMENT,操作是安全的. (2)对于innodb表,update auto_increment字段,如果列值与已有的值重复,则会出错:如果大于已有的最大值,可能会引入一个坑,会造成编号重复错误,插入数据失败的情况,可见在update自增列值是要注意. 环境描述:RHEL 6.4 x86_64 + MySQL 5.6.19 blog地址:h

mysql插入数据 报错[Err] 1136 - Column count doesn&#39;t match value count at row 1(表中有自增列)

版本:8.0.16 创建了一张表:create table user_table(uid int primary key auto_increment,uname varchar(10))auto_increment=1 插入数据报错: 经查找 ,有三种方式可以解决这个问题: 1.插入数据得时候,带入列名: insert into user_table("uname") values ("刘一") 2.自增键这列设置为0 insert into user_table