MySQL操作命令
2022年9月29日大约 15 分钟
MySQL操作命令
数据库
创建数据库
create database h_test;
#查看数据库
show databases;
#查看数据库信息
show create database h_test;
#修改数据库的编码,可使用上一条语句查看是否修改成功
alter database h_test default character set gbk collate gbk_bin;
#删除数据库
drop database h_test;
#综上,可以直接创建数据库且设置编码方式
CREATE DATABASE h_test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
数据类型(列类型)
1. 数值类型
-- a. 整型 ----------
类型 字节 范围(有符号位)
tinyint 1字节 -128 ~ 127 无符号位:0 ~ 255
smallint 2字节 -32768 ~ 32767
mediumint 3字节 -8388608 ~ 8388607
int 4字节
bigint 8字节
int(M) M表示总位数
- 默认存在符号位,unsigned 属性修改
- 显示宽度,如果某个数不够定义字段时设置的位数,则前面以0补填,zerofill 属性修改
例:int(5) 插入一个数'123',补填后为'00123'
- 在满足要求的情况下,越小越好。
- 1表示bool值真,0表示bool值假。MySQL没有布尔类型,通过整型0和1表示。常用tinyint(1)表示布尔型。
-- b. 浮点型 ----------
类型 字节 范围
float(单精度) 4字节
double(双精度) 8字节
浮点型既支持符号位 unsigned 属性,也支持显示宽度 zerofill 属性。
不同于整型,前后均会补填0.
定义浮点型时,需指定总位数和小数位数。
float(M, D) double(M, D)
M表示总位数,D表示小数位数。
M和D的大小会决定浮点数的范围。不同于整型的固定范围。
M既表示总位数(不包括小数点和正负号),也表示显示宽度(所有显示符号均包括)。
支持科学计数法表示。
浮点数表示近似值。
-- c. 定点数 ----------
decimal -- 可变长度
decimal(M, D) M也表示总位数,D表示小数位数。
保存一个精确的数值,不会发生数据的改变,不同于浮点数的四舍五入。
将浮点数转换为字符串来保存,每9位数字保存为4个字节。
2. 字符串类型
-- a. char, varchar ----------
char 定长字符串,速度快,但浪费空间
varchar 变长字符串,速度慢,但节省空间
M表示能存储的最大长度,此长度是字符数,非字节数。
不同的编码,所占用的空间不同。
char,最多255个字符,与编码无关。
varchar,最多65535字符,与编码有关。
一条有效记录最大不能超过65535个字节。
utf8 最大为21844个字符,gbk 最大为32766个字符,latin1 最大为65532个字符
varchar 是变长的,需要利用存储空间保存 varchar 的长度,如果数据小于255个字节,则采用一个字节来保存长度,反之需要两个字节来保存。
varchar 的最大有效长度由最大行大小和使用的字符集确定。
最大有效长度是65532字节,因为在varchar存字符串时,第一个字节是空的,不存在任何数据,然后还需两个字节来存放字符串的长度,所以有效长度是64432-1-2=65532字节。
例:若一个表定义为 CREATE TABLE tb(c1 int, c2 char(30), c3 varchar(N)) charset=utf8; 问N的最大值是多少? 答:(65535-1-2-4-30*3)/3
-- b. blob, text ----------
blob 二进制字符串(字节字符串)
tinyblob, blob, mediumblob, longblob
text 非二进制字符串(字符字符串)
tinytext, text, mediumtext, longtext
text 在定义时,不需要定义长度,也不会计算总长度。
text 类型在定义时,不可给default值
-- c. binary, varbinary ----------
类似于char和varchar,用于保存二进制字符串,也就是保存字节字符串而非字符字符串。
char, varchar, text 对应 binary, varbinary, blob.
3. 日期时间类型
一般用整型保存时间戳,因为PHP可以很方便的将时间戳进行格式化。
datetime 8字节 日期及时间 1000-01-01 00:00:00 到 9999-12-31 23:59:59
date 3字节 日期 1000-01-01 到 9999-12-31
timestamp 4字节 时间戳 19700101000000 到 2038-01-19 03:14:07
time 3字节 时间 -838:59:59 到 838:59:59
year 1字节 年份 1901 - 2155
datetime “YYYY-MM-DD hh:mm:ss”
timestamp “YY-MM-DD hh:mm:ss”
“YYYYMMDDhhmmss”
“YYMMDDhhmmss”
YYYYMMDDhhmmss
YYMMDDhhmmss
date “YYYY-MM-DD”
“YY-MM-DD”
“YYYYMMDD”
“YYMMDD”
YYYYMMDD
YYMMDD
time “hh:mm:ss”
“hhmmss”
hhmmss
year “YYYY”
“YY”
YYYY
YY
4. 枚举和集合
-- 枚举(enum) ----------
enum(val1, val2, val3...)
在已知的值中进行单选。最大数量为65535.
枚举值在保存时,以2个字节的整型(smallint)保存。每个枚举值,按保存的位置顺序,从1开始逐一递增。
表现为字符串类型,存储却是整型。
NULL值的索引是NULL。
空字符串错误值的索引值是0。
-- 集合(set) ----------
set(val1, val2, val3...)
create table tab ( gender set('男', '女', '无') );
insert into tab values ('男, 女');
最多可以有64个不同的成员。以bigint存储,共8个字节。采取位运算的形式。
当创建表时,SET成员值的尾部空格将自动被删除。
/* 选择类型 */
-- PHP角度
1. 功能满足
2. 存储空间尽量小,处理效率更高
3. 考虑兼容问题
-- IP存储 ----------
1. 只需存储,可用字符串
2. 如果需计算,查找等,可存储为4个字节的无符号int,即unsigned
1) PHP函数转换
ip2long可转换为整型,但会出现携带符号问题。需格式化为无符号的整型。
利用sprintf函数格式化字符串
`sprintf("%u", ip2long('192.168.3.134'));`
然后用long2ip将整型转回IP字符串
2) MySQL函数转换(无符号整型,UNSIGNED)
INET_ATON('127.0.0.1') 将IP转为整型
INET_NTOA(2130706433) 将整型转为IP
数据表建表规范
-- Normal Format, NF
- 每个表保存一个实体信息
- 每个具有一个ID字段作为主键
- ID主键 + 原子表
-- 1NF, 第一范式
字段不能再分,就满足第一范式。
-- 2NF, 第二范式
满足第一范式的前提下,不能出现部分依赖。
消除符合主键就可以避免部分依赖。增加单列关键字。
-- 3NF, 第三范式
满足第二范式的前提下,不能出现传递依赖。
某个字段依赖于主键,而有其他字段依赖于该字段。这就是传递依赖。
将一个实体信息的数据放在一个表内实现。
数据表
#首先选定操作的数据库
use h_test;
#创建表student
create table student(
id int(11),
name varchar(20),
age int(11)
);
#查看数据表
show tables;
#查看数据表信息,后面加上参数/G可使结果更加美观
show create table student;
#查看表的的字段信息
desc student;
#修改表名
alter table student rename [to] h_student;
#修改字段名
alter table h_student change name stu_name varchar(20);
#修改字段的数据类型
alter table h_student modify id int(20);
#添加字段
alter table h_student add grade float;
#删除字段
alter table h_student drop grade;
#修改字段的位置
alter table h_student modify stu_name varchar(20) first;
alter table h_student modify id int(11) after age;
#删除数据表
drop table h_student;
表的约束
约束条件 | 说明 |
---|---|
PRIMARY KEY | 主键约束,用于唯一标识对应的记录 |
FOREIGN KEY | 外键约束 |
NOT NULL | 非空约束 |
UNIQUE | 唯一性约束 |
DEFAULT | 默认值约束,用于设置字段的默认值 |
索引
#创建索引
#一.创建表的时候创建索引
create table 表名(
字段名 数据类型[完整性约束条件],
...
字段名 数据类型,
[UNIQUE|FULLTEXT|SPATIAL] INDEX|KEY
);
#1-1.创建普通索引
create table test1(
id INT,
name VARCHAR(20),
age INT,
INDEX (id)
);
#可以插入一条数据,查看索引是否被使用
explain select * from test1 where id=1 \G;
#1-2.创建唯一性索引
create table test2(
id INT,
name VARCHAR(20),
age INT,
UNIQUE INDEX unique_id(id asc)
);
#1-3.创建全文索引
create table test3(
id INT,
name VARCHAR(20),
age INT,
FULLTEXT INDEX fulltext_name(name)
)ENGINE=MyISAM;
#1-4.创建单列索引
create table test4(
id INT,
name VARCHAR(20),
age INT,
INDEX single_name(name(20))
);
#1-5.创建多列索引
create table test5(
id INT,
name VARCHAR(20),
age INT,
INDEX multi(id,name(20))
);
#1-6.创建空间索引
create table test6(
id INT,
space GEOMETRY NOT NULL,
SPATIAL INDEX sp(space)
)ENGINE=MyISAM;
---------------------------------------------------
#二.使用create index语句在已经存在的表上创建索引
#首先新建一个表,这个表没有索引
create table student(
id int,
age int,
name varchar(20),
intro varchar(40),
g GEOMETRY NOT NULL
)ENGINE=MyISAM;
#2-1.创建普通索引
create index index_id on student(id);
#2-2.创建唯一性索引
create unique index uniqueidx on student(id);
#2-3.创建单列索引
create index singleidx on student(age);
#2-4.创建多列索引
create index mulitidx on student(name(20),intro(40));
#2-5.创建全文索引
create fulltext index fulltextidx on student(name);
#2-6.创建空间索引
create spatial index spatidx on student(g);
#三.使用alter table语句在已经存在的表上创建索引
#删除student表,重新创建
drop table student;
create table student(
id int,
age int,
name varchar(20),
intro varchar(40),
space GEOMETRY NOT NULL
)ENGINE=MyISAM;
#3-1.创建普通索引
alter table student add index index_id(id);
#3-2.创建唯一性索引
alter table student add unique uniqueidx(id);
#3-3.创建单列索引
alter table student add index singleidx (age);
#3-4.创建多列索引
alter table student add index multidx(name(20),intro(40));
#3-5.创建全文索引
alter table student add fulltext index fulltextidx(name);
#3-6.创建空间索引
alter table student add spatial index spatidx(space);
#删除索引,有下面两种方式
#1.使用alter table删除索引fulltextidx
alter table student drop index fulltextidx;
#2.使用drop index删除索引spatidx
drop index spatidx on student;
添加数据
#重新建立表student
drop table student;
create table student(
id int,
name varchar(20) not null,
grade float
);
#插入一条数据,也可以少某个字段的同时也少对应的数据
insert into student(id,name,grade) values(1,'howie',70);
#也可以不指定字段名,但要注意顺序
insert into student values(2,'howie',80);
#也可以这样添加数据
insert into student set id=3,name="howie",grade=90;
#同时添加多条数据
insert into student values
(4,'howie',80),
(5,'howie',80),
(6,'howie',80);
更新数据
#更新id=1的数据
update student set name="howie1",grade=60 where id=1;
#批量更新,如果没有where子句,会更新表中所有对应数据
update student set grade=100 where id<4;
删除数据
#删除id=6的数据
delete from student where id=6;
#批量删除数据
delete from student where id>3;
#删除所有数据,DDL(数据定义语言)语句 truncate table student也可以删除表内所有数据
delete from student;
单表查询和多表操作
单表查询
#建立表student
create table student(
id int not null auto_increment,
name varchar(20) not null,
grade float,
primary key(id)
);
#插入数据
insert into student (name,grade) values
("howie1",40),
("howie1",50),
("howie2",50),
("howie3",60),
("howie4",70),
("howie5",80),
("howie6",null);
#查询全部
select * from student;
#查询某个字段
select name from student;
#条件查询,查询id=2学生的信息
select * from student where id=2;
#in关键字查询,也可以使用not in
select * from student where id IN(1,2,3);
#between and关键字查询
select * from student where id between 2 and 5;
#空值(NULL)查询,使用IS NULL来判断
select * from student where grade is null;
#distinct关键字查询
select distinct name from student;
#like关键字查询,查询以h开头,e结尾的数据
select * from student where name like "h%e";
#and关键字多条件查询,or关键字的使用也是类似
select * from student where id>5 and grade>60;
高级查询
#聚合函数
#count()函数,sum()函数,avg()函数,max()函数,min()函数
select count(*) from student;
select sum(grade) from student;
select avg(grade) from student;
select max(grade) from student;
select min(grade) from student;
#对查询结果进行排序
select * from student order by grade;
#分组查询
#1.单独使用group by分组
select * from student group by grade;
#2.和聚合函数一起使用
select count(*),grade from student group by grade;
#3.和having关键字一起使用
select sum(grade),name from student group by grade having sum(grade) >100;
#使用limit限制查询结果的数量
select * from student limit 5;
select * from student limit 2,2;
select * from student order by grade desc limit 2,2;
#函数,mysql提供了许多函数
select concat(id,':',name,':',grade) from student;
#为表取别名
select * from student as stu where stu.name="howie";
#为字段取别名,as关键字也可以不写
select name as stu_name,grade stu_grade from student;
多表操作
外键
#创建表class,student
create table class(
id int not null primary key,
classname varchar(20) not null
)ENGINE=InnoDB;
create table student(
stu_id int not null primary key,
stu_name varchar(20) not null,
cid int not null -- 表示班级id,它就是class表的外键
)ENGINE=InnoDB;
#添加外键约束
alter table student add constraint FK_ID foreign key(cid) references class(id);
#删除外键约束
alter table student drop foreign key FK_ID;
操作关联表
#数据表有三种关联关系,多对一、多对多、一对一
#学生(student)和班级(class)是多对一关系,添加数据
#首选添加外键约束
alter table student add constraint FK_ID foreign key(cid) references class(id);
#添加数据,这两个表便有了关联若插入中文在终端显示空白,可设置set names 'gbk';
insert into class values(1,"软件一班"),(2,"软件二班");
insert into student values(1,"howie",1),(2,"howie1",2),(3,"howie2",1),(4,"howie3",2);
#交叉连接
select * from student cross join class;
#内连接,该功能也可以使用where语句实现
select student.stu_name,class.classname from student join class on class.id=student.cid;
#外连接
#首先在student,class表中插入数据
insert into class values(3,"软件三班");
#左连接,右连接
select s.stu_id,s.stu_name,c.classname from student s left join class c on c.id=s.cid;
select s.stu_id,s.stu_name,c.classname from student s right join class c on c.id=s.cid;
#复合条件连接查询就是添加过滤条件
#子查询
#in关键字子查询跟上面的in关键字查询类似
select * from student where cid in(select id from class where id=2);
#exists关键字查询,相当于测试,不产生数据,只返回true或者false,只有返回true,外层才会执行,具体看下图
select * from student where exists(select id from class where id=12); -- 外层不会执行
select * from student where exists(select id from class where id=1); -- 外层会执行
#any关键字查询
select * from student where cid>any(select id from class);
#all关键字查询
select * from student where cid=any(select id from class);
事务与存储过程
事务管理
start transaction; -- 开启事务
commit; -- 提交事务
rollback; -- 取消事务(回滚)
#创建表account,插入数据
create table account(
id int primary key auto_increment,
name varchar(40),
money float
);
insert into account(name,money) values('a',1000),('b',2000),('c',3000);
#利用事务实现转账功能,首先开启事务,然后执行语句,提交事务
start transaction;
update account set money=money-100 where name='a';
update account set money=money+100 where name='b';
commit;
#事务的提交,通过这个命令查看mysql提交方式
select @@autocommit; -- 若为1,表示自动提交,为0,就要手动提交
#若事务的提交方式为手动提交
set @@autocommit = 0; -- 设置为手动提交
start transaction;
update account set money=money+100 where name='a';
update account set money=money-100 where name='b';
#现在执行select * from account 可以看到转账成功,若此时退出数据库重新登录,会看到各账户余额没有改变,所以一定要用commit语句提交事务,否则会失败
#事务的回滚,别忘记设置为手动提交的模式
start transaction;
update account set money=money-100 where name='a';
update account set money=money+100 where name='b';
#若此时a不想转账给b,可以使用事务的回滚
rollback;
#事务的隔离级别
read uncommitted;
read committed;
repeatable read;
serializable;
存储过程
#创建查看student表的存储过程
#创建student表
create table student(
id int not null primary key auto_increment,
name varchar(4),
grade float
)ENGINE=InnoDB default character set utf8;
delimiter // -- 将mysql的结束符设置为//
create procedure Proc()
begin
select * from student;
end //
delimiter ; -- 将mysql的结束符设置为;
call Proc(); -- 这样就可以调用该存储过程
#变量的使用,mysql中变量不用事前申明,在用的时候直接用“@变量名”使用就可以
set @number=100; -- 或set @num:=1;
#定义条件和处理程序
#光标的使用
#1.声明光标
DECLARE * cursor_name* CURSOR FOR select_statement
2. 光标OPEN语句
OPEN cursor_name
3. 光标FETCH语句
FETCH cursor_name INTO var_name [, var_name] ...
4. 光标CLOSE语句
CLOSE cursor_name
调用存储过程
#定义存储过程
delimiter //
create procedure proc1(in name varchar(4),out num int)
begin
select count(*) into num from student where name=name;
end//
delimiter ;
#调用存储过程
call proc1("tom",@num) -- 查找名为tom学生人数
#查看存储过程
show procedure status like 'p%' \G -- 获得以p开头的存储过程信息
#修改存储过程
alter {procedure|function} sp_name[characteristic...]
#删除存储过程
drop procedure proc1;
视图的基本操作
#在单表上创建视图,重新创建student表,插入数据
create table student(
id int not null primary key auto_increment,
name varchar(10) not null,
math float,
chinese float
);
insert into student(name,math,chinese) values
('howie1',66,77),
('howie2',66,77),
('howie3',66,77);
#开始创建视图
create view stu_view as select math,chinese,math+chinese from student; -- 下图可看出创建成功
#也可以创建自定义字段名称的视图
create view stu_view2(math,chin,sum) as select math,chinese,math+chinese from student;
#在多表上创建视图,创建表stu_info,插入数据
create table stu_info(
id int not null primary key auto_increment,
class varchar(10) not null,
addr varchar(100)
);
insert into stu_info(class,addr) values
('1','anhui'),
('2','fujian'),
('3','guangdong');
#创建视图stu_class
create view stu_class(id,name,class) as
select student.id,student.name,stu_info.class from
student,stu_info where student.id=stu_info.id;
#查看视图
desc stu_class;
show table status like 'stu_class'\G
show create view stu_class\G
#修改视图
create or replace view stu_view as select * from student;
alter view stu_view as select chinese from student;
#更新视图
update stu_view set chinese=100;
insert into student values(null,'haha',100,100);
delete from stu_view2 where math=100;
#删除视图
drop view if exists stu_view2;