前言
本篇博客是本人在学习mysql时做的笔记,带有案例。适用与初学mysql的朋友
MySQL 基础
1.数据库的概念
1.数据库的英文单词:DataBase 简称:DB
2.什么是数据库:用来储存数据的仓库
3.数据库的特点:
a.持久化储存数据,其实数据库就是一个文件系
b.方便储存和管理数据
c.使用了统一的方式操作数据库 - - SQL
2.常见的数据库
a.MySQl:开源免费的数据库,小型的数据库,已经被Oracle公司收购了,MySQL6.X也开始收费
b.Oracle:收费的大型数据库,Oracle公司产品
c.DB2:IBM公司的数据库产品,收费的,常用在银行系统中
d.SQLServlet:MicroSoft公司收费的中型数据库,C# .net等语言常用
e.SQLite:嵌入式的小型数据库,应用在手机端
f.常用的数据库:MySQL,Oracle
3.SQL
a.SQL的概念:Structured Query Language ->结构化查询语言
其实就是定义了操作所有关系类型数据库的规则,每一种数据库操作的方式存在不一样的地方称为“方言”
b.SQL通用语法
1.SQL 语句可以单行或多行书写,以分号结尾
2.可以使用空格和缩进来增强语句的可读性
3.MySQL数据库和SQL语句不区分大小写,关键字建议使用大写
4.三种注解
4.1.单行注释 --(加空格)注释内容
4.2.单行注释 #(可加空格可不加空格)注释内容 MySQL 特有的注释方式
4.3.多行注释 /* */
SQL分类
1.DDL(Data Definition Language)数据定义语言
用来定义数据库对象:数据库,表,列。关键字:create,drop,alter等
2.DML(Data Query Manipulation Language)数据操作语言
用来对数据库中的表数据进行增删改操作。关键字:insert,delete,update等
3.DQL(Data Query Language)数据查询语言
用来查询数据库中的表的记录(数据)。关键字:select,where等
4.DCL(Data Control Language)数据控制语言(了解内容)
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRABT,REVOKE等
DDL
操作数据库:CRUD
1.C(Create):创建
创建数据库:
create database TestOne;(创建了一个叫TestOne的数据库)
判断数据库是否存在,如果不存在就创建数据库,否则就不创建:
create database if not exists TestOne;-- 如果TestOne数据库不存在就创建数据库,如果存在就不创建
判断数据库是否存在,如果不存在就创建数据库,并制定字符集为GBK(默认字符集是UTF-8)
create database if not exists TestOne character set gbk; – 如果Test数据库不存在就 建数据,并将数据库的字符集修改成GBK
2.R(Retrieve):查询
查询所有数据库的名称:
show databases;
查询某个数据库的字符集:查询某个数据的创建语句
show create database 数据库名称;
3.U(Update):修改
修改数据库的字符集
alter database character set 字符集;
4.D(Delete):删除
删除数据库
drop databa 数据库名称;
判断数据库是否存在再删除
drop database if exists User;
5.使用数据库
查看当前正在使用的数据库的名称
select databases();
使用数据库
use 数据库名称;
操作表
1.C(Cerate):创建表
创建表的语法:
create table 表名(
列名1 数据类型1,
列名2 数据类型2,
列名3 数据类型3,
列名4 数据类型4
);
数据库里的数据类型:
1.int:整数类型2.double:小数类型
3.date:日期,只包含年月日 yyyy-MM-dd
4.datetime:日期,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
5.timestamp:时间错类型 包含年月日时分秒 yyyy-MM-dd HH:mm:ss
6.varchar:字符串类型
在指定数据库中创建一个表的案例:
//先创建一个数据库
create database StudentData;
//创建表 表中有姓名,年龄,性别
create table student(name varchar(30),age int,sex varchar(1));
//name varchar(30) 表示name有30个字符长度
复制表
create table 表名 like 被复制的表名;
2.R(Retrieve):查询表
查询某个数据库中的所有表
show tables;
查询表结构
desc 表名;
3.U(Update):修改表
修改表名
alter table 表名 rename to 新表名;
修改表字符集
alter table 表名 character set 字符集名称;
添加一列
alter table 表名 add 列名 数据类型;
修改列名称 类型
alter table 表名 change 列名 新列名 新数据类型;
修改数据类型
alter table 表名 modify 列名 数据类型;
删除列
alter table 表名 drop 列名;
4.D(Delete):删除表
删除表
drop tabel 表名;
判断表是否存在,如果存在删除
drop table if exists 表名;
DML增删改表中数据
1.添加数据
语法:
insert into 表名(列名1,列名2,列名3,列名4) values (值1,值2,值3,值4);
注意:
1.列名和值要一一对应
2.如果列名后,不定义列名,则默认给所有行添加值
insert into 表名 values (值1,值2,值3,值4)
3.除了数字类型,其他类型需要使用单引号(单双都可以)引起来
2.删除数据
语法:
delecte from 表名 where 条件 (where条件是可选的)
注意:
1.如果不添加条件,则会删除表中所有记录
2.如果删除所有记录
delecte from 表名; – 不推荐使用,因为有多少条记录就会执行多少次删除操作(效率低)
truncate table 表名; – 推荐使用,效率高,先删除表然后再创建一张一摸一样的表
3.修改数据
语法:
update 表名 set 列1 = 值1,… where 条件 (where条件是可选的)
注意:
如果不加任何条件,则会将表中的所有记录全部修改
DQL:查询表中的记录
1.语法:
select
字段列表(比如 name,age,sex)
form
表名列表(如果是多表查询就写多个表,表与表之间用逗号隔开)
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
2.基础查询
1.多个字段查询
select 字段名1,字段名2…from 表名;
注意:
如果查询所有字段,则可以使用*来替代字段列表 select * from 表名;
2.去除重复
distinct
3.计算列
一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
sql中的一个函数:
ifnull(表达式1,表达式2):null参与运算,计算结果都为null
表达式1:那个字段需要判断是否为null
表达式2:如果该字段为null后替换值
4.起别名
as
as也可以省略不写,用空格代替(空字符)
查询的小案例
SHOW DATABASES; -- 查看所有数据库 USE studentData; -- 使用 studentData这个数据库 SHOW tables; -- 查看数据库中的所有表 SELECT * FROM NewTable; -- 查询表中的所有记录 -- 需求一:查询地区,去除重复的结果集 SELECT DISTINCT region FROM NewTable; -- 查询地区并去除重复 -- 需求二:查询学生表中的所有同学的所在地区 name region SELECT name,region FROM NewTable; -- 查询姓名和地区 -- 需求三:计算三门学科的总分(有些同学的的学科成绩为null,null参与运算结果还是null,所以这里用到sql里面的一个函数 ifNULL(表达式1,表达式2)) SELECT name,chinese AS 语文,math AS 数学,english AS 英语,chinese + IFNULL(math,0) + english AS 总分 FROM NewTable;
3.条件查询
1.where子句后跟条件
2.运算符
(大于)> (小于)< (等于)= (小于等于)<= (大于等于)>= (等于)= (不等于)<>
between...and 在值1与值2之间的值,包含值1和值2
IN(集合)
LIKE(模糊查询)
占位符:
1._:单个任意字符
2.%:多个任意字符
IS NULL
and 或 &&
or 或 ||
not 或 |
3.小案例
# 需求一:查询年龄大于等于30岁的
SELECT * FROM NewTable WHERE age >= 30;
# 需求二:查询年龄不等于30的
# 两种方式:SELECT * FROM NewTable WHERE age != 30;
SELECT * FROM NewTable WHERE age <> 30;
# 需求三:查询年龄大于等于30小于等于40
#三种方式:SELECT * FROM NewTable WHERE age >= 30 AND age <= 40;
# SELECT * FROM NewTable WHERE age >= 30 && age <= 40;
SELECT * FROM NewTable WHERE age BETWEEN 30 AND 40;
# 需求四:年龄等于26或者27或者28
SELECT * FROM NewTable WHERE age IN(26,27,28);
# 需求五:查询数学成绩为null的
SELECT * FROM NewTable WHERE math IS NULL;
# 需求六:查询数学成绩不为null
SELECT * FROM NewTable WHERE math IS NOT NULL;
# 需求七:查询姓为马的所有人
SELECT * FROM NewTable WHERE name LIKE '马%';
# 需求八:查询第二个字为六的所有人
SELECT * FROM NewTable WHERE name LIKE '_六%';
# 需求九:查询名字为三个字的所有人
SELECT * FROM NewTable WHERE name LIKE "___";
# 需求十:查询名字中包含马的所有人
SELECT * FROM NewTable WHERE n ame LIKE "%马%";
1.DQL:查询语句
1.排序查询
语法:order by 子句
order by 排序字段1,排序方式1,排序字段2,排序方式2…
排序方式:
ASC:升序,默认的
DESC:降序
注意:
如果有多个排序条件,则当前面的条件值一样的,才会判断第二条件
排序的小案例 # 排序 # 需求一:将所有同学的语文成绩按升序排序 SELECT * FROM NewTable ORDER BY chinese; # 需求二:将所有同学的语文成绩按降序排序,如果语文成绩一样,则按英语成绩的升序排序 SELECT * FROM NewTable ORDER BY chinese DESC,english DESC;
2.聚合查询
概念:将一列数据作为一个整体,进行纵向的计算
a.count:计算个数
b.max:计算最大值
c.min:计算最小值
d.sum:计算和
e.avg:计算平均值
注意:
聚合函数的计算排除null值
解决方案:
1.选择不包含null的列进行计算
2.IFNULL函数
小案例演示 # 聚合函数 # 需求一:计算表中的个数 SELECT COUNT(name) FROM NewTable; -- 10 # 如果选择的列中包含非空(null),比如根据数学成绩统计个数 SELECT COUNT(math) FROM NewTable; -- 本来是十个,现在是八个了 聚合函数计算个数排除了非空(null) # 解决方案一: SELECT COUNT(IFNULL(math,0)) FROM NewTable; # 解决方案二: # 选择非空的一列进行计算个数 # 需求二:计算语文成绩的最大值 SELECT MAX(chinese) FROM NewTable; -- 100 # 需求三:计算语文成绩的最小值 SELECT MIN(chinese) FROM NewTable; -- 78 # 需求四:计算语文成绩的平均分 SELECT AVG(chinese) FROM NewTable; -- 87.1000
3.分组查询
语法:group by 分组字段
注意:
1.分组后查询的字段:分组字段,聚合函数
2.where 和 having 的区别·:
a.where在分组之前进行限定,如果不满足条件,则不参与分组。having在分组之后进行限定。如果不满足结果,则不会查询出来
b.where后不可用跟聚合函数,having可以进行聚合函数的判断
小案例 # 分组 # 需求一:按照性别分组,分别查询男,女同学的平均分,人数 SELECT sex,AVG(chinese),COUNT(name) FROM NewTable GROUP BY sex; # 需求二:按照性别分组,分别查询男,女同学的平均分,人数 要求:分数低于80分的人不参与查询 SELECT sex,AVG(chinese),COUNT(name) FROM NewTable WHERE chinese > 80 GROUP BY sex; # 需求三:按照性别分组,分别查询男,女同学的平均分,人数 要求:分数低于80分的人不参与查询,并且人数要大于2人 SELECT sex,AVG(chinese),COUNT(name) FROM NewTable WHERE chinese > 80 GROUP BY sex HAVING COUNT(name) > 2;
SELECT:查看结果的列,或者聚合函数相关计算
FROM:从哪个表中查数据
WHERE:根据条件,过滤表中的数据
GROUP BY:将WHERE过滤的数据行分组
HAVING:对分组的数据进行过滤
ORDER BY:按照什么顺序来排序最后的数据问题:这些sql中的关键字的执行顺序分别是什么?
select name ,age from tb where id>‘1’ group by name order by age limit 1,3;
看以上这条语句:
执行顺序 from tb(从那张表查询数学)select name ,age(查询那些字段) where id>‘1’(根据什么去查询这些字段)group by name (查询出来,根据name去进行分组)order by age(根据age去排序 默认排序asc 升序) limit 1,3(分页)
4.分页查询
1.语法:limit 开始索引,每页查询的条数
2.公式:开始索引 = (当前的页码 -1) * 每页显示的条数
3.limit是mysql的 “方言“
4.小案例
# 分页
# 需求:每页显示四条数据
# LIMIT 是mysql特有的方言
# LIMIT 开始索引,条数
# 开始索引 = 当前页数-1乘以每页的条数
SELECT * FROM NewTable LIMIT 0,4; -- 第一页
SELECT * FROM NewTable LIMIT 4,4; -- 第二页
SELECT * FROM NewTable LIMIT 8,4; -- 第三页
2.约束
1.约束的概念:对表中的数据进行限定,保证数据的正确性,有效性和完整性。
约束的分类:
1.主键约束:primary key
1.主键约束:primary key
注意:
a.含义:非空切为一
b.一张表只有一个主键
c.主键就是表中记录的唯一表示
#以下sql语句用来演示主键约束
#创建表,并给表中的指定列添加主键约束
CREATE TABLE stu(
id int PRIMARY KEY,
name varchar(20),
age int,
sex varchar(1)
);
#向表中添加一条数据
INSERT INTO stu(id,name,age,sex) VALUES (1,"张三",23,"男");
#向表中添加一条重复id的数据 sql语句编译报错
INSERT INTO stu(id,name,age,sex) VALUES (1,"李四",24,"男"); #Duplicate entry '1' for key 'PRIMARY' key 'PRIMARY'的重复条目'1'
#删除主键约束
ALTER TABLE stu DROP PRIMARY KEY;
#创建表时没有添加主键,可以通过下面这条sql语句给表中的指定列添加主键
ALTER TABLE stu MODIFY id int PRIMARY KEY;
自动增长(一般和主键配合使用)
1.概念:如果某一列是数值类型,可以使用 auto_increment关键字来完成值的自动增长
2.演示定义方式
#演示主键和自动增长
#创建表stu 给指定列设定主键约束,并自动增长
CREATE TABLE stu(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20),
age int,
sex varchar(1)
);
#向表中添加数据
INSERT INTO stu(id,name,age,sex) VALUES (1,"张三",23,"男");
INSERT INTO stu(id,name,age,sex) VALUES (NULL,"张三",23,"男"); #执行这条语句时id的值不为null而是为2
# 查看表中数据
SELECT * FROM stu;
# 删除自动增长 注意如果时配合主键一起使用的话 这条语句删除的只是自动增长,没有删除主键约束
ALTER TABLE stu MODIFY id int;
#添加自动增长
ALTER TABLE stu MODIFY id int AUTO_INCREMENT;
2.非空约束:not null
2.非空约束:某一列的值不能为null
#第一种方式,在创建表时对表种的列进行非约束
#在studentData这个数据库中创建一张新的表,并对表中的指定属性,name属性进行非空约束
CREATE TABLE NewStudentData(
id int,
name varchar(20) NOT NULL,
age int,
sex varchar(1)
);
SELECT * FROM NewStudentData;
INSERT INTO NewStudentData(id,name,age,sex) VALUES (1,NULL,23,"男"); #错误的添加方式
#指定了name这个值不为null 如果name的值为null,那么回sql语句执行就会报错
# Column 'name' cannot be null (列“name”不能为空)
INSERT INTO NewStudentData(id,name,age,sex) VALUES (1,"张三",23,"男"); #正确的添加方式
# 执行正确的sql语句后,查看表中所有的数据
SELECT * FROM NewStudentData;
#删除非空约束
ALTER TABLE NewStudentData MODIFY name varchar(20);
#第二种方式,在创建表后对指定列添加非空约束
ALTER TABLE NewStudentData MODIFY name varchar(20) NOT NULL;
#这条语句是测试 错误的演示
INSERT INTO NewStudentData(id,name,age,sex) VALUES (1,NULL,23,"男"); #Column
'name' cannot be null 添加非空约束成功
3.唯一约束:unique
3.唯一约束:unique,某一列的值不能重复
#创建一个表 用来演示唯一约束 (在创建表时对指定列限定唯一约束)
CREATE TABLE stu(
id int,
name varchar(20),
phone varchar(11) UNIQUE
);
#向表中添加数据 两条演示数据
INSERT INTO stu(id,name,phone) VALUES (1,"张三","110");
INSERT INTO stu(id,name,phone) VALUES (2,"李四","110"); #Duplicate entry '110' for key 'phone' 唯一约束错误提示信息
#删除唯一约束
ALTER TABLE stu DROP INDEX phone;
#在创建表后给指定列限定唯一约束
ALTER TABLE stu MODIFY phone varchar(11) UNIQUE;
#添加相同的数据进行测试
INSERT INTO stu(id,name,phone) VALUES (2,"李四","110"); #Duplicate entry '110' for key 'phone'
4.外键约束:foreign key
a.外键约束:foreign key,让表与表之间产生关系,从而保证数据的正确性
b.外键的作用:进行多表数据的关联
c.主表(父表):数据来源表/主键所在表
d.从表(子表):数据引用表/外键所在表
e.强制保证外键数据的完整性
f.即以下情况,外键约束会强制保护数据
1.从表尝试引用主键不存在的数据
2.主表尝试删除从表引用数据
1.在创建表时,可以添加外键
语法:
create table 表名(
...
#外键列
constraint 外键名称 foreign key(外键列的名称) references 主表名称(主表列名称)
);
2.删除外键
alter table 表名 drop foreign key 外键名称;
3.创建表之后,添加外键
alter table 表名 add constraint 外键名称 foreign key(外键字段名称) references 主表名称(主表列名称)
4.级联操作
1.添加级联操作
语法:
alter table 表名 add constraint 外键名称 foreign key(外键字段名称) references 主表名称(主表列名称) on update cascade on delete cascade;
2.分类:
2.1.联动更新: on update cascade
2.2.联动删除: on delete cascade
外键约束演示sql语句:
SHOW DATABASES;
USE studentData;
show tables;
#创建部门表 (id,dep_name,dep_location)
create table department(
id int primary key auto_increment,
dep_name varchar(20),
dep_location varchar(20)
);
-- 创建员工表(id,name,age,dep_id)
-- 多方,从表
create table employee(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int, -- 外键对应主表的主键
#在创建表时添加外键约束添加外键约束
CONSTRAINT emp_dep_id FOREIGN KEY(dep_id) REFERENCES department(id)
)
-- 添加2个部门
insert into department values(null, '研发部','广州'),(null, '销售部', '深圳');
select * from department;
-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2);
select * from employee;
#删除外键约束
ALTER TABLE employee DROP FOREIGN KEY emp_dep_id;
#在创建表后添加外键约束,并添加更新级联,删除级联
ALTER TABLE employee ADD CONSTRAINT emp_dep_id FOREIGN KEY(dep_id) REFERENCES
department(id) on update cascade on delete cascade;
3.数据库的设计
1.多表之间的关系
概念:设计数据库时,需要遵循的一些规范要求,必须先遵循前面的所有范式要求
设计数据库时,遵循不同的范式要求,设计出合理的关系型数据库,这些不同的范式要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库尘于越小
目前关系数据库有六种范式:第一范式(1NF),第二范式(2NF),第三范式(3NF),第四范式(巴斯-科德范式(BCNF)),第五范式(5NF,又称完美范式)
分类:
1.第一范式(1NF):每一列都是不可分割的原子数据项
2.第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF的基础上消除非主属性对主码的部分函数依赖)
几个概念:
1.函数依赖:A --> B,如果通过A属性(属性组)的值,可以确定唯一B属性的值,则称B依赖于A
例如:学号 --> 学生姓名 (学号,课程名称) --> 分数
2.完全函数依赖:A --> B,如果A是一个属性组,则B属性值得确定需要依赖于A属性组中的所有属性值
例如:(学号,课程名称) --> 分数
3.部分函数依赖:A --> B,如果A是一个属性组,则B属性值得确定需要依赖于A属性组中某一些值即可
例如:(学号,课程名称) --> 姓名
4.传递函数依赖:A --> B, B --> C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称C传递函数依赖于A
例如:学好 -->系名,系名 --> 系主任
5.码:如果在一张表中,一个属性或属性组,被其他所有属性完全依赖,则称这个属性(属性组)为该表的码
例如:该表中码为:(学号,课程名称)
主属性:码属性组中的所有属性
非主属性:除过码属性的属性
3.第三范式(3NF):在2NF基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)
2.数据库的备份和还原
备份和还原的两种方式
1.命令行
备份:
语法:mysqldump -u用户名(root) -p密码(root) 数据库名称 >>保存的路径
还原:
1.登录数据库
2.创建数据库
3.使用数据库
3.执行文件(xxx.sql文件)语法:source 文件路径;
2.图形化工具:(很简单!)