半学期前学了mysql数据库的各种基本操作,结果因为项目问题又跑去搞别的了…一大段时间没碰数据库的操作,啥都忘了。因此整理了一下一些比较基础、常用的操作,以便于自己以后查看。
像视图、索引、引擎、性能优化这部分…目前还很菜的我就先不整理,之后再去深入了解
用于存储和管理数据的仓库
特点
1、持久化存储数据( 类似一个文件系统)
2、方便存储和管理数据
3、使用了统一的方式操作数据库 – SQL语句
win + r弹出运行窗口,输入 services.msc 打开服务窗口,找到你的数据库名(默认为MySQL),将启动类型设为自动后,一般开机就会自动启动
也可以调成手动,这样每次开机使用都必须在cmd(管理员身份)中启动服务
cmd – > net start mysql
cmd --> net stop mysql
(以上的两个mysql为你一开始安装mysql时设定的数据库名)
前者启动mysql服务,后者关闭mysql服务
在cmd中登录MySQL
1、mysql -uroot -p密码
2、mysql -hip -urrot -p连接目标的密码
3、mysql --host=ip --user=root --password=连接目标的密码
在cmd中退出MySQL
1、exit
2、quit
bin目录:二进制的可执行文件
data目录:数据目录,存放了MySQL的一些日志文件,数据文件
include目录:c语言的头文件信息
lib目录:mysql需要的一些jar包,用于支持mysql的运行
share目录:放置的是mysql的一些的错误的信息
my.ini 文件:mysql的配置文件
…此处可看其他人的博客对该文件内容的具体解析
改变数据库的默认存储位置( 一般是C盘),有利于用户自身管理,其次防止C盘文件凌乱、更改频繁,导致磁盘读取速度下降。
1、先找到你的my.ini文件,该文件一般在你的MySQL根目录下能找到( 根据个别人的安装情况不同,位置可能不同,有人的my.ini位置在C盘下ProgramData–>MySQL–>my.ini ,视个人情况决定,不过也建议将该文件移至MySQL的根目录下,以确保服务器使用startup选项读取配置文件 ----来自my.ini中注释)
2、找到后用记事本打开该文件,Ctrl+f 查找 datadir,datadir所对应的的路径即是数据库存储的位置
3、找到该路径下的数据存储的文件夹,并将其移动到将要放置的新的位置,并重写datadir对应的位置
例如 :原本我的 datadir = C:\ProgramData\MySQL\MySQL Server 8.0\data,我将MySQL Server 8.0整个文件夹移到了D盘根目录下,然后我再在my.ini中更改datadir=D:\ MySQL Server 8.0\data
这样就大功告成了
SQL语句可以单行或多行书写,以分号结尾
MySQL数据库和SQL语句不区分大小写,关键字建议使用大写
三种注释:
1、单行注释:-- 注释内容
2、单行注释:# 注释内容
3、多行注释:/* 注释内容 */
SQL按照功能分类为以下四类
1、DDL(Data Definition Language)数据定义语言
用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
2、DML(Data Manipulation Language)数据操作语言
用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
3、DQL(Data Query Language)数据查询语言
用来查询数据库中表的记录(数据)。关键字:select, where 等
4、DCL(Data Control Language)数据控制语言(了解)
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等
区分四类SQL可以通过其针对的对象:DDL的使用对象是 库、表、列等;DML和DQL的使用对象是表中的记录;DCL的用于权限和安全等
C( Create) :创建
1、创建数据库
create database 数据库名称;
2、创建数据库,判断不存在再创建
create database if not exists 数据库名称;
3、创建数据库,指定字符集为其他编码格式
create database 数据库名称 character set 字符集名;
R( Retrieve) :查询
1、查询所有数据库的名称
show databases;
2、查询某个数据库的创建语句( 可用于查询某个数据库的字符集)
show create database 数据库名称;
U(Update) :修改
修改数据库的字符集
alter database 数据库名称 character set 字符集名;
D( Delete) :删除
1、删除数据库
drop database 数据库名称;
2、判断数据库存在则删除该数据库
drop database if exists 数据库名称;
使用数据库
1、使用数据库
use 数据库名;
2、查询当前正在使用的数据库
select database();
C( Create) :创建
1、语法:
create table 表名(
列名 数据类型,
…
列名n 数据类型n (此处不需要加逗号!)
);
2、复制表
create table 表名 like 被复制的表名
3、常用数据类型
int 整数类型
double 双精度浮点型
data 日期,只包含年月日,格式:yyyy-MM-dd
datatime 日期,包含年月日时分秒,格式:yyyy-MM-dd HH:mm:ss
timestamp 时间戳类型,包含年月日时分秒,格式:yyyy-MM-dd HH:mm:ss
varchar:字符串类型
varchar中,一个汉字算一个字符,如:你好–>两个字符; world算5个字符
R( Retrieve) :查询
1、查询某个数据库中所有的表的名称
show tables;
2、查询表结构
desc 表名;
3、查询某个表的具体情况
show create table 表名;
U(Update) :修改
1、修改表名
alter table 表名 rename to 新表名;
2、修改表的字符集
alter table 表名 character set 字符集名;
3、添加一列
alter table 表名 add 列名 数据类型;
alter table 表名 add 列名 数据类型 first 已存在的某一字段名;
alter table 表名 add 列名 数据类型 after 已存在的某一字段名;
4、修改列名称 类型
alter table 表名 change 列名 新列名 数据类型;
5、只改列类型
alter table 表名 modify 列名 新数据类型;
6、修改字段的排列位置
alter table 表名 modify 列名1 数据类型 first/after 列名2
7、删除列
alter table 表名 drop 列名
D( Delete) :删除
1、drop table 表名;
2、drop table if exists 表名;
添加数据
1、语法:
insert into 表名( 列名1,列名2,…,列名n) value( 值1,值2,…,值n)
2、注意:
列名和值要一一对应
如果表名后没有定义列名,则默认给所有列添加值
除了数字类型,其他类型需要使用引号(单双引号都可)
删除数据
1、语法:
delete from 表名 [where 条件]
2、注意:
如果不加条件则删除表中所有记录
删除所有记录有两种方法
①delete from 表名 – 不推荐,有多少条记录就执行多少次
②truncate table 表名 – 推荐,效率更高,先删除一张表再创建一张表
修改数据
1、语法:
update 表名 set 列名1 = 值1, 列名2 = 值2, …,[where 条件];
2、注意:
如果不加条件则表中所有记录更改
语法:
select 列名 from 表名 where 条件 group by 分组字段 having 分组之后的条件限定 order by 排序 limit 分页限定;
去重
select distinct 列名 from 表名
起别名
select 列名 as 别名 from 表名
where子句后跟条件
运算符
1、< 、<= 、>= 、= 、<>
2、BETWEEN…AND
3、 IN( 集合)
4、 LIKE:模糊查询
5、 占位符:
_:单个任意字符
%:多个任意字符
6、IS NULL
7、 and 或 &&
8、or 或 ||
9、not 或 !
示例
-- 查询年龄等于20岁
SELECT * FROM student WHERE age = 20;
-- 查询年龄不等于20岁
SELECT * FROM student WHERE age != 20;
SELECT * FROM student WHERE age <> 20;
-- 查询年龄大于等于20 小于等于30
SELECT * FROM student WHERE age >= 20 && age <=30;--在SQL中不太建议使用这种写法
SELECT * FROM student WHERE age >= 20 AND age <=30;
SELECT * FROM student WHERE age BETWEEN 20 AND 30;
-- 查询年龄22岁,18岁,25岁的信息
SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
SELECT * FROM student WHERE age IN (22,18,25);
-- 查询英语成绩为null
SELECT * FROM student WHERE english = NULL; -- 不对的。null值不能使用 = 或(!=) 判断
SELECT * FROM student WHERE english IS NULL;
-- 查询英语成绩不为null
SELECT * FROM student WHERE english IS NOT NULL;
/*
4、 LIKE:模糊查询
5、 占位符:
_:单个任意字符
%:多个任意字符
-*/
-- 查询姓马的有哪些? like
SELECT * FROM student WHERE NAME LIKE '马%';
-- 查询姓名第二个字是化的人
SELECT * FROM student WHERE NAME LIKE "_化%";
-- 查询姓名是3个字的人
SELECT * FROM student WHERE NAME LIKE '___';
-- 查询姓名中包含德的人
SELECT * FROM student WHERE NAME LIKE '%德%';
语法:order by子句
order by 排序字段1 排序方式1, 排序字段2 排序方式2…
排序方式:
ASC:升序,默认排序方式
DESC:降序
注意:
若有多个排序条件,则当前面的条件值相同才会判断第二个条件
作用:将一列数据作为一个整体,进行纵向的计算( 列的和的计算)
count():计算该列个数
1、一般选择非空的列:主键
2、count( *) --count( )括号中填*,不推荐这样使用
max():取该列最大值
min():取该列最小值
sum():计算该列数值和
avg():计算平均值
注意:聚合函数的计算中会排除null值
解决方案:1、选择不包含非空的列进行计算
2、ifnull函数 eg: count( ifnull(列名, 0)) 如果列为null则将null替换成0
语法:select 列名 from 表名 group by 分组字段; --按某个字段进行分组
注意:
1、分组之后查询的字段:分组字段、聚合函数
2、where和having的区别:
--例子
--按照性别分组。分别查询男、女同学的平均分,人数 要求:分数低于70分的人,不参与分组,分组之后。人数要大于2个人
CREATE TABLE student(
id int,
name varchar(17),
math double(4,1),
sex varchar(5),
);
INSERT INTO student values
(4, '临海', 110.7, 'M'),
(7,'ALen', 107.4, 'M'),
(9, 'Victora', 101, 'F'),
(1, 'Miss', 102, 'F'),
(2,'Leant', 99, 'M'),
(5, 'Jessica', 100, 'F')
;
SELECT sex, AVG(math), COUNT(id) FROM student WHERE math >= 70 group by sex HAVING COUNT(id) > 2
语法:
select 列名 from 表名 limit 开始的索引,每页查询的条数
公式:开始的索引 = (当前页码-1) * 每页显示的条数
SELECT * FROM student LIMIT 0,3; -- 第1页
SELECT * FROM student LIMIT 3,3; -- 第2页
SELECT * FROM student LIMIT 6,3; -- 第3页
注意:其他数据库的分页操作不一定是limit
概念:对表中的数据进行限定,保证数据的正确性、有效性和完整性
分类:
1、主键约束:primary key
2、非空约束:not null
3、唯一约束:unique
4、外键约束:foreign key
not null,值不能为null
创建表时添加约束
CREATE TABLE stu(
id INT,
NAME VARCHAR(20) NOT NULL -- name为非空
);
创建表完后,添加非空约束
ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;
删除name的非空约束
ALTER TABLE stu MODIFY NAME VARCHAR(20);
unique, 值不能重复
创建表时,添加唯一约束
CREATE TABLE stu(
id INT,
phone_number VARCHAR(20) UNIQUE -- 添加了唯一约束
);
注意:mysql中,唯一约束限定的列的值可以有多个null
删除唯一约束
-- 错误做法 ALTER TABLE stu MODIFY phone_number VARCHAR(30);
ALTER TABLE stu DROP INDEX phone_number;
在创建表后,添加唯一约束
ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;
基础:
1、主键非空且唯一
2、一张表只能有一个字段为主键
3、主键就是表中记录的唯一标识
在创建表时,添加主键约束
create table stu(
id int primary key, -- 给id添加主键约束
name varchar(20)
);
删除主键
– 错误 alter table stu modify id int ;
ALTER TABLE stu DROP PRIMARY KEY;
创建完表后,添加主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY;
自动增长:
1、概念:如果某一列是数值类型的,使用 auto_increment 可以来完成值得自动增长
2、在创建表时,添加主键约束,并且完成主键自增长
create table stu(
id int primary key auto_increment, -- 给id添加主键约束
name varchar(20)
);
3、删除自动增长
ALTER TABLE stu MODIFY id INT;
4、添加自动增长
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
foreign key,让表与表产生关系,从而保证数据的正确性
语法:
create table 表名(
…
外键列
constraint 外键名称(即索引名) foreign key (外键列名称) references 主表名称(主表列名称)
);
删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称( 非列名)
创建表之后,添加外键
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FORRIGN KEY( 外键字段名) REFERENCES 主表名(主表列名)
级联操作
1、添加级联操作
语法:ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE;
2、分类:
①级联更新:ON UPDATE CASCADE
②级联删除:ON DELETE CASCADE
分类
1、一对一
举例:人与身份证
实现:可以在任意一方添加唯一(unique)外键指向另一方的主键
2、一对多
举例:部门和员工
实现:在多的一方建立外键,指向一的一方的主键
3、多对多
举例:学生和教师
实现:多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
多表间关系实现的案例
-- 创建旅游线路分类表 tab_category
-- cid 旅游线路分类主键,自动增长
-- cname 旅游线路分类名称非空,唯一,字符串 100
CREATE TABLE tab_category (
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(100) NOT NULL UNIQUE
);
-- 创建旅游线路表 tab_route
/*
rid 旅游线路主键,自动增长
rname 旅游线路名称非空,唯一,字符串 100
price 价格
rdate 上架时间,日期类型
cid 外键,所属分类
*/
CREATE TABLE tab_route(
rid INT PRIMARY KEY AUTO_INCREMENT,
rname VARCHAR(100) NOT NULL UNIQUE,
price DOUBLE,
rdate DATE,
cid INT,
FOREIGN KEY (cid) REFERENCES tab_category(cid)
);
/*创建用户表 tab_user
uid 用户主键,自增长
username 用户名长度 100,唯一,非空
password 密码长度 30,非空
name 真实姓名长度 100
birthday 生日
sex 性别,定长字符串 1
telephone 手机号,字符串 11
email 邮箱,字符串长度 100
*/
CREATE TABLE tab_user (
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) UNIQUE NOT NULL,
PASSWORD VARCHAR(30) NOT NULL,
NAME VARCHAR(100),
birthday DATE,
sex CHAR(1) DEFAULT '男',
telephone VARCHAR(11),
email VARCHAR(100)
);
/*
创建收藏表 tab_favorite
rid 旅游线路 id,外键
date 收藏时间
uid 用户 id,外键
rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次
*/
CREATE TABLE tab_favorite (
rid INT, -- 线路id
DATE DATETIME,
uid INT, -- 用户id
-- 创建复合主键
PRIMARY KEY(rid,uid), -- 联合主键
FOREIGN KEY (rid) REFERENCES tab_route(rid),
FOREIGN KEY(uid) REFERENCES tab_user(uid)
);
定义:每一列都是不可分割的原子数据项
即列名下不再分更细致的列名
如:列名写作电器,不细分即可满足第一范式;若再细分为各种电器则不满足第一范式
只满足第一范式的缺点:
1、存在非常严重的数据冗余( 重复)
2、数据添加存在问题,可能导致数据不合法
3、数据删除存在问题
定义:在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖
函数依赖:A–>B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
如:通过学号(A)我们可以确认学生姓名(B),则称A为属性(属性组),B依赖于A
完全函数依赖:A–>B, 如果A是一个属性组,则B属性值的确定需要依赖于A属性组中所有的属性值
如:确认学生的分数(B),我们需要先了解学生的学号和课程名称(二者即A,一个属性组),即指A属性组被B完全依赖
部分函数依赖:A–>B, 如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可
如:假设学生的学号和课程名称二者一同被称为A( 属性组),而要确定该学生的姓名,只需要学生的学号而不需要课程名称,这就是A被B部分依赖
传递函数依赖:A–>B, B – >C . 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A
码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
如:学生的学号
主属性:码属性组中的所有属性
非主属性:除过码属性组的属性
仍然存在的问题:
2、数据添加存在问题,可能导致数据不合法
3、数据删除存在问题
命令行操作
语法:
1、备份:
mysqldump -u用户名 -p密码 > 保存路径
2、还原:
① 登录数据库
② 创建数据库
③ 使用数据库
④ 执行文件 -> source文件路径
可视化软件
备份/导出
添加用户
CREATE USER ‘用户名’@‘主机名’ IDENTIFIED BY ‘密码’;
删除用户
DROP USER ‘用户名’@‘主机名’;
修改用户密码
1、UPDATE USER SET PASSWORD = PASSWORD(‘新密码’) WHERE USER = ‘用户名’;
2、SET PASSWORD FOR ‘用户名’@‘主机名’ = PASSWORD(‘新密码’);
3、注,新加密码需要加密,因此我们使用PASSWORD()函数
查询用户
第一步:
切换到mysql数据库 USE mysql;
第二步:
SELECT * FROM USER;
--添加用户
CREATE USER 'hello'@'localhost' IDENTIFIED BY 'hello';
CREATE USER 'world'@'%' IDENTIFIED BY 'world';
--删除用户
DROP USER 'hello'@'localhost';
--修改用户密码
UPDATE USER SET PASSWORD = PASSWORD('123') WHERE USER = 'world';
SET PASSWORD FOR 'world'@'%' = PASSWORD('abc');
通配符 : % 表示可以在任意主机使用用户登录数据库
查询权限
SHOW GRANTS FOR ‘用户名’@‘主机名’;
授予权限
GRANT 权限列表 ON 数据库名.表名 TO ‘用户名’@‘主机名’;
撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM ‘用户名’@‘主机名’;
--查询权限
SHOW GRANTS FOR 'world'@'%';
--授予权限
GRANT SELECT, DELETE, UPDATE ON db2.emp TO 'world'@'%';
GRANT ALL ON *.* TO 'world'@'%'; --授予全部权限
--撤销权限
REVOKE UPDATE ON db3.emp FROM 'world'@'%';