文章目录
数据库操作
1.查看已有库
show databases;
2.创建库
create database 库名 [character set utf8];
create database stu character set utf8;
create database stu charset=utf8;
3.查看创建库的语句
show create database 库名;
4.查看当前所在库
select database();
5.切换库
use 库名;
6.删除库
drop database 库名;
数据表的管理
表结构设计初步
【1】 分析存储内容
【2】 确定字段构成
【3】 设计字段类型
数据类型支持
数字类型:
整数类型(精确值) - INTEGER,INT,SMALLINT,TINYINT,MEDIUMINT,BIGINT
定点类型(精确值) - DECIMAL
浮点类型(近似值) - FLOAT,DOUBLE
比特值类型 - BIT
对于精度比较高的东西,比如money,用decimal类型提高精度减少误差。列的声明语法是DECIMAL(M,D)。
M是数字的最大位数(精度)。其范围为1~65,M 的默认值是10。
D是小数点右侧数字的数目(标度)。其范围是0~30,但不得超过M。
比如 DECIMAL(6,2)最多存6位数字,小数点后占2位,取值范围-9999.99到9999.99。
比特值类型指0,1值表达2种情况,如真,假
字符串类型:
CHAR和VARCHAR类型
BLOB和TEXT类型
ENUM类型和SET类型
•char 和 varchar
char:定长,效率高,一般用于固定长度的表单提交数据存储,默认1字符
varchar:不定长,效率偏低 ,但是节省空间。
•text 和blob
text用来存储非二进制文本
blob用来存储二进制字节串
•enum 和 set
enum用来存储给出的一个值
set用来存储给出的值中一个或多个值
1.表的基本操作
创建表
create table 表名(
字段名 数据类型,
字段名 数据类型,
…
字段名 数据类型
);
•如果你想设置数字为无符号则加上 unsigned
•如果你不想字段为 NULL 可以设置字段的属性为 NOT NULL, 在操作数据库时如果输入该字段的数据为NULL ,就会报错。
•DEFAULT 表示设置一个字段的默认值
•AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1。
•PRIMARY KEY 关键字用于定义列为主键。主键的值不能重复,且不能为空。
e.g. 创建班级表
create table class_1 (id int primary key auto_increment,name varchar(32) not null,age tinyint unsigned not null,sex enum('w','m'),score float default 0.0);
e.g. 创建兴趣班表
create table interest (id int primary key auto_increment,name varchar(32) not null,hobby set('sing','dance','draw'),level char not null,price decimal(6,2),remark text);
查看数据表
show tables;
查看已有表的字符集
show create table 表名;
查看表结构
desc 表名;
删除表
drop table 表名;
数据操作基础
插入(insert)
insert into 表名 values(值1),(值2),...;
insert into 表名(字段1,...) values(值1),...;
insert into class_1 values (2,'Baron',10,'m',91),(3,'Jame',9,'m',90);
查询(select)
select * from 表名 [where 条件];
select 字段1,字段2 from 表名 [where 条件];
select * from class_1;
select name,age from class_1;
where子句
where子句在sql语句中扮演了重要角色,主要通过一定的运算条件进行数据的筛选
MySQL 主要有以下几种运算符:
算术运算符
比较运算符
逻辑运算符
算数运算符
select * from class_1 where age % 2 = 0;
比较运算符
select * from class_1 where age > 8;
select * from class_1 where between 8 and 10;
select * from class_1 where age in (8,9);
逻辑运算符
select * from class_1 where sex='m' and age>9;
更新表记录(update)
update 表名 set 字段1=值1,字段2=值2,... where 条件;
注意:update语句后如果不加where条件,所有记录全部更新
update class_1 set age=11 where name='Abby';
删除表记录(delete)
delete from 表名 where 条件;
注意:delete语句后如果不加where条件,所有记录全部清空
delete from class_1 where name='Abby';
表字段的操作(alter)
语法 :alter table 表名 执行动作;
* 添加字段(add)
alter table 表名 add 字段名 数据类型;
alter table 表名 add 字段名 数据类型 first;
alter table 表名 add 字段名 数据类型 after 字段名;
* 删除字段(drop)
alter table 表名 drop 字段名;
* 修改数据类型(modify)
alter table 表名 modify 字段名 新数据类型;
* 修改字段名(change)
alter table 表名 change 旧字段名 新字段名 新数据类型;
* 表重命名(rename)
alter table 表名 rename 新表名;
alter table interest add tel char(11) after name;
时间类型数据
时间和日期类型:
日期DATE,日期时间DATETIME,时间戳TIMESTAMP
时间TIME
年份YEAR
时间格式
date :“YYYY-MM-DD”
time :“HH:MM:SS”
datetime :“YYYY-MM-DD HH:MM:SS”
timestamp :“YYYY-MM-DD HH:MM:SS”
注意
1、datetime :以系统时间存储
2、timestamp :以标准时间存储但是查看时转换为系统时区,所以表现形式和datetime相同
create table marathon (id int primary key auto_increment,athlete varchar(32),birthday date,registration_time datetime,performance time);
日期时间函数
•now() 返回服务器当前日期时间,格式对应datetime类型
•curdate() 返回当前日期,格式对应date类型
•curtime() 返回当前时间,格式对应time类型
时间操作
•查找操作
select * from marathon where birthday>='2000-01-01';
select * from marathon where birthday>="2000-07-01" and performance<="2:30:00";
高级查询语句
模糊查询和正则查询
LIKE用于在where子句中进行模糊查询,SQL LIKE 子句中使用百分号 %来表示任意0个或多个字符,下划线_表示任意一个字符。
使用 LIKE 子句从数据表中读取数据的通用语法:
SELECT field1, field2,...fieldN
FROM table_name
WHERE field1 LIKE condition1
mysql> select * from class_1 where name like 'A%';
mysql中对正则表达式的支持有限,只支持部分正则元字符
select * from class_1 where name regexp '^B.+';
as 用法
在sql语句中as用于给字段或者表重命名
select name as 姓名,age as 年龄 from class_1;
select * from class_1 as c where c.age > 17;
排序
ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。
使用 ORDER BY 子句将查询数据排序后再返回数据:
SELECT field1, field2,...fieldN from table_name1 where field1
ORDER BY field1 [ASC [DESC]]
默认情况ASC表示升序,DESC表示降序
select * from class_1 where sex='m' order by age;
分页(限制)
LIMIT 子句用于限制由 SELECT 语句返回的数据数量 或者 UPDATE,DELETE语句的操作数量
带有 LIMIT 子句的 SELECT 语句的基本语法如下:
SELECT column1, column2, columnN
FROM table_name
WHERE field
LIMIT [num]
联合查询
UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。
UNION 操作符语法格式:
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];
expression1, expression2, … expression_n: 要检索的列。
tables: 要检索的数据表。
WHERE conditions: 可选, 检索条件。
DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。
ALL: 可选,返回所有结果集,包含重复数据。
select * from class_1 where sex='m' UNION ALL select * from class_1 where age > 9;
子查询
定义 : 当一个select语句中包含另一个select 查询语句,则称之为有子查询的语句
子查询出现的位置:
1.from 之后 ,此时子查询的内容作为一个新的表内容,再进行外层select查询
select name from (select * from class_1 where sex='m') as s where s.score > 90;
•需要将子查询结果集重命名一下,方便where子句中的引用操作
2.where字句中,此时select查询到的内容作为外层查询的条件值
select * from class_1 where age = (select age from class_1 where name='Tom');
•子句返回的结果需要一个明确值,即需要时某个记录的某个元素,不能是多行或者多列
聚合操作
聚合操作指的是在数据查找基础上对数据的进一步整理筛选行为,在认识聚合之前先看一个更完整的sql语句
•select语句执行顺序
(7) SELECT
(8) [DISTINCT] <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>
聚合函数
方法
功能
avg(字段名) 该字段的平均值
max(字段名) 该字段的最大值
min(字段名) 该字段的最小值
sum(字段名) 该字段所有记录的和
count(字段名) 统计该字段记录的个数
eg1 : 找出表中的最大攻击力的值?
select max(attack) from sanguo;
eg2 : 表中共有多少个英雄?
select count(name) as number from sanguo;
eg3 : 蜀国英雄中攻击值大于200的英雄的数量
select count(*) from sanguo where attack > 200;
注意: 此时select 后只能写聚合函数,无法查找其他字段。
聚合分组
•group by
给查询的结果进行分组
e.g. : 计算每个国家的平均攻击力
select country,avg(attack) from sanguo
group by country;
e.g. : 对多个字段创建索引,此时多个字段都相同时为一组
select age,sex,count(*) from class1 group by age,sex;
e.g. : 所有国家的男英雄中 英雄数量最多的前2名的 国家名称及英雄数量
select country,count(id) as number from sanguo
where gender=‘M’ group by country
order by number DESC
limit 2;
使用分组时select 后的字段为group by分组的字段和聚合函数,不能包含其他内容。group by也可以同时依照多个字段分组,如group by A,B 此时必须A,B两个字段值均相同才算一组。
聚合筛选
having语句
对分组聚合后的结果进行进一步筛选
eg1 : 找出平均攻击力大于105的国家的前2名,显示国家名称和平均攻击力
select country,avg(attack) from sanguo
group by country
having avg(attack)>105
order by avg(attack) DESC
limit 2;
注意
•having语句通常与group by联合使用。
•having语句存在弥补了where关键字不能与聚合函数联合使用的不足,where只能操作表中实际存在的字段,having操作的是聚合函数生成的显示列
去重语句
distinct语句
不显示字段重复值
eg1 : 表中都有哪些国家
select distinct name,country from sanguo;
eg2 : 计算一共有多少个国家
select count(distinct country) from sanguo;
注意
•distinct和from之间所有字段都相同才会去重
聚合运算
查询表记录时做数学运算
运算符 : + - * / %
eg1: 查询时显示攻击力翻倍
select name,attack2 from sanguo;
eg2: 更新蜀国所有英雄攻击力 * 2
update sanguo set attack=attack2 where country=‘蜀国’;
索引操作
索引概述
•定义
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
•优点
加快数据检索速度,提高查找效率
•缺点
占用数据库物理存储空间
当对表中数据更新时,索引需要动态维护,降低数据写入效率
索引分类
•普通(MUL)
普通索引 :字段值无约束,KEY标志为 MUL
•唯一索引(UNI)
唯一索引(unique) :字段值不允许重复,但可为 NULL,KEY标志为 UNI
•主键索引(PRI)
一个表中只能有一个主键字段, 主键字段不允许重复,且不能为NULL,KEY标志为PRI。通常设置记录编号字段id,能唯一锁定一条记录
索引创建
主键索引的创建方法已经在数据表中介绍过了,下面是普通索引和唯一索引的创建方法:
•创建表时直接创建索引
create table 表名(
字段名 数据类型,
字段名 数据类型,
index(字段名),
index(字段名),
unique(字段名)
);
•在已有表中创建索引:
create [unique] index 索引名 on 表名(字段名);
查看索引
1、desc 表名; --> KEY标志为:MUL 、UNI。
2、show index from 表名;
•扩展: 借助性能查看选项去查看索引性能
show variables like 'profiling';
set profiling = 1; 打开功能 (项目上线一般不打开)
show profiles 查看语句执行信息
删除索引
drop index 索引名 on 表名;
已有表添加主键索引或自增长属性
alter table 表名 add primary key(id);
alter table 表名 modify id int auto_increment;
创建复合主键
primary key(uid,pid)
此时两个字段只要不都相同即可。
删除主键索引或自增长属性
alter table 表名 modify id int; 要先删除自增长,因为它只作用于主键字段
alter table 表名 drop primary key;
外键约束和表关联关系
外键约束
•约束 : 约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性
•foreign key 功能 : 建立表与表之间的某种约束的关系,由于这种关系的存在,能够让表与表之间的数据,更加的完整,关连性更强,为了具体说明创建如下部门表和人员表。
创建部门
CREATE TABLE dept (id int PRIMARY KEY auto_increment,dname VARCHAR(50) not null);
创建人员
CREATE TABLE `person` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`age` tinyint DEFAULT 0,
`sex` enum('m','w','o') DEFAULT 'o',
`salary` decimal(8,2) DEFAULT 250.00,
`hire_date` date NOT NULL,
`dept_id` int DEFAULT NULL
) ;
上面两个表中每个人员都应该有指定的部门,但是实际上在没有约束的情况下人员是可以没有部门的或者也可以添加一个不存在的部门,这显然是不合理的。当然并不是任何情况都需要建立外键关系,如果没有这种约束时也可以不建立,但是当表与表之间存在这种约束时最好建立。
•主表和从表:若同一个数据库中,B表的外键与A表的主键相对应,则A表为主表,B表为从表。
•foreign key 外键的定义语法:
建立表时直接建立外键关联,注意本表的外键列类型与指定的主表列相同,且主表指定列需为主键
CREATE TABLE `person` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`age` tinyint DEFAULT 0,
`sex` enum('m','w','o') DEFAULT 'o',
`salary` decimal(10,2) DEFAULT 250.00,
`hire_date` date NOT NULL,
`dept_id` int DEFAULT NULL,
constraint dept_fk foreign key(dept_id) references dept(id));
建立表后增加外键
alter table person add constraint dept_fk foreign key(dept_id) references dept(id);
通过外键名称解除外键约束
alter table person drop foreign key dept_fk;
删除外键后发现desc查看索引标志还在,其实外键也是一种索引,需要将外键名称的索引删除之后才可以。
•restrict(默认) : on delete restrict on update restrict ◦当主表删除记录时,如果从表中有相关联记录则不允许主表删除
◦当主表更改主键字段值时,如果从表有相关记录则不允许更改
•cascade :数据级联更新 on delete cascade on update cascade ◦当主表删除记录或更改被参照字段的值时,从表会级联更新
•set null : on delete set null on update set null ◦当主表删除记录时,从表外键字段值变为null
◦当主表更改主键字段值时,从表外键字段值变为null
表关联设计
•一对一关系
一张表的一条记录一定只能与另外一张表的一条记录进行对应,反之亦然。
举例 : 学生信息和学籍档案,一个学生对应一个档案,一个档案也只属于一个学生
create table student(id int primary key auto_increment,name varchar(50) not null);
create table record(id int primary key auto_increment,
comment text not null,
st_id int unique,
foreign key(st_id) references student(id)
on delete cascade
on update cascade
);
•一对多关系
一张表中有一条记录可以对应另外一张表中的多条记录;但是反过来,另外一张表的一条记录
只能对应第一张表的一条记录,这种关系就是一对多或多对一
举例: 一个人可以拥有多辆汽车,每辆车登记的车主只有一人。
create table person(
id varchar(32) primary key,
name varchar(30),
sex char(1),
age int
);
create table car(
id varchar(32) primary key,
name varchar(30),
price decimal(10,2),
pid varchar(32),
constraint car_fk foreign key(pid) references person(id)
);
•多对多关系
一对表中(A)的一条记录能够对应另外一张表(B)中的多条记录;同时B表中的一条记录
也能对应A表中的多条记录
举例:一个运动员可以报多个项目,每个项目也会有多个运动员参加,这时为了表达多对多关系需要单独创建关系表。
CREATE TABLE `athlete` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` tinyint NOT NULL,
`country` varchar(30) NOT NULL,
`description` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `item` (
`id` int NOT NULL AUTO_INCREMENT,
`rname` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `athlete_item` (
`aid` int NOT NULL,
`tid` int NOT NULL,
PRIMARY KEY (`aid`,`tid`),
CONSTRAINT `athlete_fk` FOREIGN KEY (`aid`) REFERENCES `athlete` (`id`),
CONSTRAINT `item_fk` FOREIGN KEY (`tid`) REFERENCES `item` (`id`)
);
表关联查询
如果多个表存在一定关联关系,可以多表在一起进行查询操作,其实表的关联查询与外键约束之间并没有必然联系,但是基于外键约束设计的具有关联性的表往往会更多使用关联查询查找数据。
多表查询
多个表数据可以联合查询,语法格式如下:
select 字段1,字段2... from 表1,表2... [where 条件]
select * from dept,person where dept.id = person.dept_id;
内连接
内连接查询只会查找到符合条件的记录,其实结果和表关联查询是一样的,官方更推荐使用内连接查询。
SELECT 字段列表
FROM 表1 INNER JOIN 表2
ON 表1.字段 = 表2.字段;
select * from person inner join dept on person.dept_id =dept.id;
•笛卡尔积
笛卡尔积就是将A表的每一条记录与B表的每一条记录强行拼在一起。所以,如果A表有n条记录,B表有m条记录,笛卡尔积产生的结果就会产生n*m条记录。
select * from person inner join dept;
外链接
•左连接 : 左表为主表,显示右表中与左表匹配的项
SELECT 字段列表
FROM 表1 LEFT JOIN 表2
ON 表1.字段 = 表2.字段;
select * from person left join dept on person.dept_id =dept.id;
•右连接 :右表为主表,显示左表中与左表匹配的项
SELECT 字段列表
FROM 表1 RIGHT JOIN 表2
ON 表1.字段 = 表2.字段;
select * from person right join dept on person.dept_id =dept.id;
•注意:我们尽量使用数据量大的表作为基准表,即左连接做左表,右连接做右表
视图
视图概念
视图是存储的查询语句,当调用的时候,产生结果集,视图充当的是虚拟表的角色。其实视图可以理解为一个表或多个表中导出来的表,作用和真实表一样,包含一系列带有行和列的数据 视图中,用户可以使用SELECT语句查询数据,也可以使用INSERT,UPDATE,DELETE修改记录,视图可以使用户操作方便,并保障数据库系统安全,如果原表改名或者删除则视图也失效。
视图操作
•创建视图
语法结构:
CREATE [OR REPLACE] VIEW [view_name] AS [SELECT_STATEMENT];
释义:
CREATE VIEW: 创建视图
OR REPLACE : 可选,如果添加原来有同名视图的情况下会覆盖掉原有视图
view_name : 视图名称
SELECT_STATEMENT :SELECT语句
e.g.
create view c1 as select name,age from class_1;
•视图表的增删改查操作
视图的增删改查操作与一般表的操作相同,使用insert update delete select即可,但是原数据表的约束条件仍然对视图产生作用。
•查看所有视图
show full tables in stu where table_type like 'VIEW';
•删除视图
drop view [IF EXISTS] 视图名;
IF EXISTS 表示如果存在,这样即使没有指定视图也不会报错。
drop view c1;
•修改视图
参考创建视图,将create关键字改为alter
alter view c1 as select name,age,score from class_1;
视图作用
•作用 1.是对数据的一种重构,不影响原数据表的使用。
2.简化高频复杂操作的过程,就像一种对复杂操作的封装。
3.提高安全性,可以给不同用户提供不同的视图
4.让数据更加清晰
•缺点 1.视图的性能相对较差,从数据库视图查询数据可能会很慢
2.表依赖关系处理麻烦,根据数据库的基础表创建一个视图。每当更改视图或者原表时,另一个也会修改。
函数和存储过程
存储过程和函数是事先经过编译并存储在数据库中的一段sql语句集合,调用存储过程和函数可以简化应用开发工作,提高数据处理的效率。
函数创建
delimiter 自定义符号 -- 如果函数体只有一条语句, begin和end可以省略, 同时delimiter也可以省略
create function 函数名(形参列表) returns 返回类型 -- 注意是retruns
begin
函数体 -- 函数语句集,set @a 定义变量
return val
end 自定义符号
delimiter ;
释义:
delimiter 自定义符号 是为了在函数内些语句方便,制定除了;之外的符号作为函数书写结束标志,一般用$$或者//
形参列表 : 形参名 类型 类型为mysql支持类型
返回类型: 函数返回的数据类型,mysql支持类型即可
函数体: 若干sql语句组成,如果只有一条语句也可以不写delimiter和begin,end
return: 返回指定类型返回值
e.g. 无参数的函数调用
delimiter $$
create function st() returns int
begin
return (select score from class_1 order by score desc limit 1);
end $$
delimiter ;
select st();
e.g. 含有参数的函数调用
delimiter $$
create function queryNameById(uid int(10))
returns varchar(20)
begin
return (select name from class_1 where id=uid);
end $$
delimiter ;
select queryNameById(1);
存储过程创建
创建存储过程语法与创建函数基本相同,但是没有返回值。
delimiter 自定义符号
create procedure 存储过程名(形参列表)
begin
存储过程 -- 存储过程语句集,set @a 定义变量
end 自定义符号
delimiter ;
释义:
delimiter 自定义符号 是为了在函数内些语句方便,制定除了;之外的符号作为函数书写结束标志
形参列表 :[ IN | OUT | INOUT ] 形参名 类型
in 输入,out 输出,inout 可以输入也可以输出
存储过程: 若干sql语句组成,如果只有一条语句也可以不写delimiter和begin,end
e.g. 存储过程创建和调用
delimiter $$
create procedure st()
begin
select name,age from class_1;
select name,score from class_1 order by score desc;
end $$
delimiter ;
call st();
•存储过程三个参数的区别 ◦IN 类型参数可以接收变量也可以接收常量,传入的参数在存储过程内部使用即可,但是在存储过程内部的修改无法传递到外部。
◦OUT 类型参数只能接收一个变量,接收的变量不能够在存储过程内部使用(内部为NULL),但是可以在存储过程内对这个变量进行修改。因为定义的变量是全局的,所以外部可以获取这个修改后的值。
◦INOUT类型参数同样只能接收一个变量,但是这个变量可以在存储过程内部使用。在存储过程内部的修改也会传递到外部。
◦设置变量方法: set @[变量名] = 值; 表示这是一个用户变量,使用时用@[变量名]。 在函数内部设置declare [变量名] [变量类型]为局部变量,局部变量可以使用set赋值或者着使用into关键字,局部变量要定义在语句块开始的位置。
e.g. : 分别将参数类型改为IN OUT INOUT 看一下结果区别
delimiter $$
create procedure p_out ( OUT num int )
begin
select num;
set num=100;
select num;
end $$
delimiter ;
set @num=10;
call p_out(@num)
存储过程和存储函数操作
1.调用存储过程
语法:
call 存储过程名字([存储过程的参数[,……]])
2.调用存储函数
语法:
select 存储函数名字([存储过程的参数[,……]])
3.使用show status语句查看存储过程和函数的信息
语法:
show {procedure|function} status [like’存储过程或存储函数的名称’]
显示内容:数据库、名字、类型、创建者、创建和修改日期
4.使用show create语句查看存储过程和函数的定义
语法:
show create {procedure|function} 存储过程或存储函数的名称
5.查看所有函数或者存储过程
select name from mysql.proc where db=‘stu’ and type=’[procedure/function]’;
6.删除存储过程或存储函数
语法:
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
函数和存储过程区别
1.函数有且只有一个返回值,而存储过程不能有返回值。
2.函数只能有输入参数,而存储过程可以有in,out,inout多个类型参数。
3.存储过程中的语句功能更丰富,实现更复杂的业务逻辑,可以理解为一个按照预定步骤调用的执行过程,而函数中不能展示查询结果集语句,只是完成查询的工作后返回一个结果,功能针对性比较强。
4.存储过程一般是作为一个独立的部分来执行(call调用)。而函数可以作为查询语句的一个部分来调用。