数据库(MySQL)的基本操作
1.简介
(1)数据库
1.数据库(Data Base,简称DB):长期保存在计算机的存储设备上,数据是按照一定的规则组织起来的,能被用户、应用平台共享的数据集合。(存储、维护和管理数据的集合)
2.数据库管理系统(Database Management System,简称DBMS):指的是一种用来管理和操作数据的大型软件,用于建立、使用、维护数据,对数据库进行统一的管理和控制,以保证数据的完整性和安全性。用户可以通过数据库管理系统访问数据库中的数据。(数据库软件,数据库是通过这些软件进行创建和操作的。)
3.常见的数据库管理系统:
关系型数据库的管理系统:Oracle,Mysql,SQLServer
DB2:是IBM的
4.关系型数据库、非关系型数据库:
-
非关系型数据库:
-
采用了没有特定关系模型来组织数据。
-
NOSQL基于键值对: not only sql
-
代表: HBase, MongoDB,Redis, Oracle NOSQL
-
-
关系型数据库:
-
依据所有存储数据的模型之间的关系建立的数据库。
-
所谓关系模型,指的是“一对一、一对多、多对多”等关系模型
-
(2)SQL简介
SQL(Structure Query Language(结构化查询语言))是一种标准化的语言,允许在数据库上进行操作,如:创建项目(Create)、查询内容(Read)、更新内容(update)和删除(Delete)内容等操作,这些操作通常被称为 CRUD操作。
(3)SQL分类
- DDL(Data Definition Language):数据定义语言,用来定义数据库对象(数据库、表、列)
创建数据库:create database 库名
修改数据库:alter database 库名 character set (修改编码集)
删除数据库:drop database 库名
创建表结构:create table 表名
修改表结构:alter table 表名
删除表结构:drop table 表名
- DML(Data Manipulation Language):数据操作语言,用于定义数据库记录(数据)(就是对表中的数据进行增、删、改、查)
增加数据:inseret into 表名 values(值1,值2..........)
删除数据:delete from 表名 [where 条件]
修改数据:update 表名 set .........
- DCL(Data Control Language):数据控制语言,用于定义访问权限和安全级别
- DQL(Data Query Language):数据查询语言,用于查询记录(数据)关键词:select ...... from 表名.......
- TCL (Transaction Control Language): 事务控制语言,用于保证数据的完整性约束。(commit,rollback)SQL语句大小写是不区分的。
CREATE / create / Create / CrEaTe
但是,一般情况下,我们会大写。
2.数据库的基本操作
(1)DDL语言的学习
1)介绍
DDL(Data definition Language):数据定义语言,用来定义数据库中相关的对象(库,表)的结构(库和表的创建、删除和修改) 关键字:create 、alter、drop
2)针对于库的DDL操作
(1)创建一个数据库
语法:create database 库名 ;
还可以指定编码集:
语法: create database 库名 character set 编码集(utf8、GBK.....);
(2)查看数据库
查看当前数据库服务器种有哪些数据库
语法:show 库名;
查看建库时的底层语句
语法:show create database 库名;
(3)使用库,切换库
语法:use 库名;
查询当前正在使用的库
语法:# 切换当前使用的数据库
(4)修改库的字符集
alter database 库名 character set 编码集(utf8、GBK.....)
(5)删除数据库
drop database 库名;
3)针对于表的DDL操作
(1)表的概念
数据在数据库中的存储是以表的形式存在的。一个表中有若干个字段,将数据按照这些字段进行存储。
1、数据表(table),是关系型数据库的基本存储结构。一个关系型数据库是由多个表组成的。
2、数据表是二维的,它由纵向的列和横向的行组成。
3、数据表的行(Row)是横排数据,也被称之为记录(Recond)。
4、数据表的列(Column)是竖排数据,也被称之为字段(Field)。
5、表与表之间也可能存在着关系。(一对一,一对多,多对多)
(2)数据类型
int :整型
double:浮点型 double(5,2) :表示最多有5位,其中必须有两位是小数,即最大值是 999.99
char:固定长度的字符串,如char(5) : 'aa' 占5位
varchar:可变长度的字符串,例如varchar(5):'aa' 占2位
text:字符串类型
blob:字节类型
date:日期类型,格式是:yyyy-MM-dd
time:时间类型,格式为:hh:mm:ss
timestamp:时间戳类型,yyyy-MM-dd hh:mm:ss,会自动赋值
datetime:时间类型,yyyy-MM-dd hh:mm:ss
(3)DDL操作表
1)创建表格结构
create table 表名( 字段1 类型 [default '默认值'],
字段2 类型 [comment '备注内容'],
.......
字段n 类型
);
2)删除表格结构
drop table 表名;
3)修改表结构
1.添加一个字段
语法:alter table 表名 add 添加的字段名 字段类型;
2.修改字段类型
语法:alter table 表名 modify 需要修改的字段名 新的字段类型;
3.#修改一张表的字段名,注意可以同时修改类型(但一定要加上字段类型)
语法:alter table 表名 change 原来的字段名 新的字段名 字段类型;4.修改一张表的字符集
语法:alter table 表名 character set charsetName;5.删除一张表中的字段
语法:alter table 表名 drop 要删除的字段名;
(4)查看表结构
语法: desc tableName;
查看建表时的底层语句
语法:show create table 表名;
(2)DML语言的学习
DML(Data Manipulation Language):数据操纵语言,指的是对表中的数据(记录)进行增、删、改的操作。不要和DDL搞混了。
关键字:insert into 、update、delete
注意事项:
-
在SQL中,字符串类型和日期类型需要用单引号括起来
-
空值操作: 在条件中使用 is null 或者is not null 。
1)增加数据
添加一条数据的写法:
写法1:
语法: insert into 表名 values(avl1,val2,val3,......);
写法2:
语法: insert into 表名
(colName1,colName2,colName3,.....)
values(avl1,val2,val3,......); 有多少个字段就有多少个值添加多条的写法:
写法1:
语法: insert into 表名 values
(avl1,val2,val3,......),
(avl1,val2,val3,......),
(avl1,val2,val3,......),
.......,
(avl1,val2,val3,......);写法2:
语法: insert into tableName
(colName1,colName2,colName3,.....)
values
(avl1,val2,val3,......),
(avl1,val2,val3,......),
(avl1,val2,val3,......),
.......,
(avl1,val2,val3,......);
3)删除数据
-- 删除数据
-- 关键字delete
-- 如果开启了事物,删除的数据可以回滚,即可以恢复。-- 普通删除数据
-- 语法:delete from tableName ;
-- 按照条件进行删除
-- 语法:delete from tableName where conditions;
delete 与 truncate的区别
-
delete删除表中的数据,表结构还在;删除的数据可以恢复。
-
truncate是直接将表DROP掉,然后再按照原来的结构重新创建一张表。数据不可恢复。
-
truncate删除效率比delete高。
-
语法 : truncate table 表名
3)修改数据
语法:update tableName set colName1 = value1,colName2 =value2,....[where conditions];
where的用法:
在进行数据的删除、修改、查询的时候,可以使用where对数据进行一个过滤。
= :相等比较(类似于java中的==)
!= <> : 表示不相等
> < >= <= : 大小比较
between...and... : 在xxx和xxx之间
in(set) :在括号中所有值之间取
IS [not] NULL
AND、OR
==注意==:如果没有使用where子句进行过滤筛选,则是对表中的所有记录进行更新 (==要小心了==)
(3)DQL的基本操作
DQL: SQL分类的一种,是Data Query language的简称。 用于对表中的记录进行查询操作。
1)基本查询语言的结构
from…子句: 用于指定要查询的表
select…子句:选择表中的哪些字段进行查询/显示
语法:select ...... from ..........
完整查询语句:select [distinct].....from....[where....][group by .....][having.....][order by.....][limit.....]
查询语句的执行顺序:
1. 先执行from子句:基于表进行查询操作
2. 再执行where子句:进行条件筛选或者条件过滤
3. 再执行group by子句:对剩下的数据进行分组查询。
4. 再执行having子句:分组后,再次条件筛选或过滤
5. 然后执行select子句:目的是选择业务需求的字段进行显示
6. 再执行order by子句:对选择后的字段进行排序
7. 最后执行limit子句:进行分页查询,或者是查询前n条记录
别名的用法:
有的时候,表名或者列名过长,或者在查询过程中涉及到的 虚拟表 或者是虚拟字段,我们就需要给他们起一个别称,也就是别名。
别名的命名:
-
虽然可以使用汉字,但是尽量还是要使用英文字母。
-
表别名,不能使用单双引号
-
列别名,可以加单双引号,也可不加。
(1)where子句的使用:对表中的数据进行条件筛选或者过滤
条件如下:
1)关系表达式: >,>=,<,<=,=,!=,<>
2)多条件连接符: and,or, [not] between ..and..
3)集合操作: [not] in (set),>all(set), <all(set), >any(set), <any(set)
注意:mysql不支持简单的集合查询操作,但是子查询里支持,是针对于all和any集合操作来说的。
4)模糊查询: like
_:占位符,表示匹配任意一个字符
%:表示匹配任意N个字符,大于等于0.
(2)group by 子句
有的时候,需要分组统计一些,最大值max(字段名),最小值min(字段名),平均值avg(常量|字段名),和sum(常量|字段名),总数count(*|常量|字段名)之类的这样的信息,此时需要分组查询。
注意:
- 所有的聚合函数,都会忽略字段为null的那条记录。
可以使用ifnull(colName, value). 求平均值时:avg(ifnull(colName, 0))
- ifnull(colName,value): 如果colName对应的值不为空,就使用本身的值,如果为null,使用value.
- count(*),不会忽略null值所在的行记录,即通常用于统计总行数。
(3)having子句
当使用了group by子句后,如果想再次对数据进行筛选和过滤,就需要使用having子句了。
注意: having子句 只能跟在groub by子句后面
(4)order by子句:用于查询排序的,通常放置在一个查询语句的最后部分
语法: order by colName [asc|desc] [,colName [asc|desc]]
asc:升序, 默认情况就是升序
desc:降序位于select子句后
(5)去重查询
的时候,我们需要查询表中有那些不同的数据。不需要重复出现,此时可以使用distinct关键字进行去重处理
注意:distinct关键字只能放在select关键字之后。
比如: 查询有那些部门号
(6)分页查询
- 需求:当一页的数据量过大时,我们可以进行分页显示操作。注意:分页查询时,一般都要进行先排序,再分页。
- 关键字limit.
- 语法:limit m[,n];
m 表示从index处开始查询,
n表示要查询的记录数目。注意:mysql的记录index从0开始。
一个参数的含义:limit n :表示从0开始查询n条记录
案例:分页查询,工资降序,规定每页pageSize条记录,查询第page页的数据。
select * from emp order by sal desc limit (page-1)*pageSize ,pageSize;
3.约束constraint
(1)概念
完整性约束条件,用于对表中的字段值进行限制,必须随时遵守指定的约束规则。 这样可以保证数据的一致性和正确性。
-
完整性约束条件,简称约束。
-
是一种强制性的校验手段
-
只针对于DML操作。不符合约束条件,直接报错不执行。
-
这些约束,尽量在建表期间指定好,避免在表中已经有数据的情况下修改(可能修改失败)
定义期间,约束定义在指定列的后面,称之为列级约束,定义在表的最后,称之为表级约束
(2)默认值约束:给字段设置有默认值
这样在插入数据时,该字段如果没有指定新的值,数据库就会自动为这个字段插入默认值。
1. 建表时的写法:
create table 表名(
...
字段名 字段类型 default 值,
...
);
2.建表后修改
alter table 表名 modify 字段名 字段类型 default value;
3.建表后取消默认值约束
alter table 表名 modify 字段名 字段类型;
(3)非空约束:限定字段的值不能为null
关键字:not null ,简称NN
1.建表时写法:
create table 表名(
...
字段名 字段类型 not null,
...
);
2.表后修改
alter table 表名 modify 字段名 字段类型 not null;
3.取消非空约束
alter table 表名 modify 字段名 字段类型;
(4)唯一性约束:限定字段的值不能重复
注意:设置唯一性约束后,可以为null,可以理解为无穷大不等于无穷大。
unique ,简称UK
1.建表时列级约束写法
create table 表名(
...
字段名 字段类型 unique,
...
);
2.建表时表级约束写法
create table table_UK_1(
...
...
constraint 约束名字 unique(字段,...)
);
3.建表后修改
alter table 表名 modify 字段名 字段类型 unique;
4.取消唯一约束的写法
alter table 表名 drop index 约束名称
建表时或者建表后添加的,可以使用 show create table 表名 查看约束的名字
(5)主键约束:用于标识表中的每一条记录都是唯一的
主要目的是帮助数据库管理系统以最快的速度查找到表的某一条信息。
-
primary key,简称PK
-
唯一且非空
-
主键可以由一个字段组成,也可以由多个字段组成
-
如果主键可以由一个字段组成既可以添加到列级也可以添加到表级,但是如果由多个字段组成只能添加到表级
1.(只有一个字段)建表时列级约束写法:
create table 表名(
...
字段名 primary key,
...
);
2.建表时表级约束语法
create table 表名(
...
...
constraint 主键约束名字 primary key(字段1,....)
);
3.建表后添加
1. alter table 表名 modify 字段名 字段类型 primary key; 只有一个字段为主键
2.alter table 表名 add primary key(字段名)
4.取消主键约束,但是非空约束还在
alter table 表名 drop primary key;
(6)自增键约束 :关键字auto_increment
能设置自增约束的条件如下:
-
列的类型必须是整型
-
该列必须设置为主键约束或者唯一性约束
-
向数据库表中插入新记录时,字段上的值默认的初始值1,每增加一条记录,该字段的值会增加1;
-
一个表中只能有一个自增约束
1.建表时添加约束
create table 表名(
...
字段名 int primary key auto_increment,
...
);
2.建表后添加约束
alter table 表名 modify 字段名 字段类型 auto_increment;
3.取消自增约束
alter table 表名 modify 字段名 字段类型;
4.设置初始值
alter table 表名 auto_increment = 8;
(7)外键约束:保证多个表(通常为两个表)之间的参照完整性
外键约束,指字段A的值,依赖于字段B的值。这两个字段可以在同一张表中,也可以在不同的表中。字段A所在的表称之为子表,字段B所在的表称之为父表。字段A的值也可以为null. 字段B必须为主键约束。
foreign key,简称FK
1.建表时的写法
create table tableName(
...
constraint 外键约束名称 foreign key(字段A) references 表名2(字段B)
); 该表的字段A依赖于表2的字段B,字段B必须为主键约束
2.建表后的写法
alter table 表名1 add constraint 约束名称 foreign key(字段A) references 表名2(字段B)
3.取消外键约束
alter table 表名 drop foreign key 外键约束名;
(8).检查约束:对表中的字段进行条件限制
比如余额不能小于0,性别必须是f和m等
check ,简称CK
1.建表时写法
create table tableName(
........
tgender char(1) check(tgender in('f','m')) 必须满足条件才可以插入--gender char(1) check(gender ='f' or gender = 'm')
);
2.删除检查性约束
alter table 表名 drop check ;
4.关联查询(多表查询)
案例:最简单的关联查询 但是这种查询的结果大多数的记录是没有意义的
表A有M条记录,表B有N条记录,在查询时没有指定关联字段和关联条件, 查询出来的数据总条数就是M*N条。
select * from emp,dept;
select * from emp join dept;
(1)写法分类
第一种:在from子句中,直接写多个表名,表名之间使用逗号分隔开,用where来指定关联条件
select A.*,B.*,C.* from A,B,C where A.字段=B.字段 and A.字段=C.字段
第二种:from 子句中用join连接表名,使用on来指定关联条件
select A.*,B.*,C.* from A join B join C on A.字段=B.字段 and A.字段=C.字段
(2)join的连接分类
内连接和外连接,而外连接有细分为三种类型
第一类: 内连接 [inner] join
-- 查询出来的结果是:必须满足关联条件的记录进行组合
-- 第二类 : 外连接 outer join
-- 左外连接 left outer join
-- 以左表为驱动表,驱动表里的数据全部显示,另一张表只显示满足条件的数据。
-- 右外连接 right outer join
-- 以右表为驱动表,驱动表里的数据全部显示,另一张表只显示满足条件的数据。
(3)集合查询
union(去重)/union all(不去重)
两个查询语句使用上述的关键字连接即可。
注意:两个查询语句的字段名,字段个数,必须对应上。
5.高级关联查询(子查询)
当一个查询语句A所需要的数据,不是直观在表中体现,而是由另外一个查询语句B查询出来的结果,那么查询语句A就是主查询语句,查询语句B就是子查询语句。这种查询我们称之为高级关联查询,也叫做子查询。
子查询语句的位置可以在以下几个子句中:
--位于where语句中:子查询的结果可用作条件筛选时使用的值
- 在from子句中: 子查询的结果可充当一张表或视图,需要使用表别名。
- 在having子句中: 子查询的结果可用作分组查询再次条件过滤时使用的值
- 在select子句中: 子查询的结果可充当一个字段。仅限子查询返回单行单列的情况。
案例:
-- 需求2:查询员工的信息及其部门总人数,以及部门有几个职位
select a.* ,
(select count(*) from emp where deptno = a.deptno) count,
(select count(distinct job) from emp where deptno = a.deptno ) countjob
from emp a;
sql的完整执行顺序
select distinct..from t1 [inner|left|right] join t2 on 条件 where...group by...having...order by...limit
1. from t1
2. on 条件
3. [inner|left|right] join t2
4. where...
5. group by...
6. having...
7. select...
8. distinct...
9. order by...
10. limit....
6.常用函数
(1)日期函数
1)获取系统当前日期和时间的函数
select now(),curdate(),curtime(),sysdate(),current_timestamp(),CURRENT_DATE();
执行结果依次是:2024-09-01 18:45:10 2024-09-01 18:45:10 2024-09-01 18:45:10 2024-09-01 18:45:10 2024-09-01
2)获取星期几
select dayofweek(now()),weekday(sysdate()),dayname(now());
1 6 Sunday
dayofweek:星期日是1
-- weekday:星期日是6
-- dayname :获取星期的英文
3)获取第几天
select dayofmonth('2002-09-20'),dayofyear(now()),monthname(now());
20 245 September
4)获取时间日期分量
select hour(now()),minute(now()),second(now()),month(now()),day(now()),date(now());
18 51 12 9 1 2024-09-01
5)将日期时间格式化为我们想要的字符串格式 H%:24小时制 h%:12小时制
select date_format(now(),'%Y/%m/%d %h:%i:%s %p %W');
2024/09/01 06:52:10 PM Sunday
6) 日期运算函数
date_add(date,interval express unit)/date_sub(date,interval express unit)/
adddate(date,interval express unit)/subdate(date,interval express unit)
-- 获取明日的此时此刻的时间
select adddate(now(),interval 1 day);
-- 获取12小时之前的时间
select adddate(now(),interval -12 day);
(2)字符串函数
1).进制转换函数 conv(n,from_base ,to_base),对指定进制from_base的数n转成另外一种进制to_base的表现形式
select conv(12,10,8); -- 14
select conv(0xfabc,16,10); -- 64188
2) concat(v1,v2,v3):将多个参数拼接成一个字符串,只要有一个为null,就返回hull。
拼接字段时将拼接后的结果作为一个新的字段
3)lpad(str,len,padstr) rpad(str,len,padstr):使用指定的字符串从左/右填充原来的字符串
-- 从左填充,就是向右靠齐,及整体向右移动
select lpad("www.baidu.com",15,'*');
-- 从右填充,就是向左靠齐,及整体向做移动
select rpad("www.baidu.com",15,'*');
4) 截取子串 left(str,len) right(str,len)substring(str,pos[,len])
select left("www.baidu.com",9) ,right("www.baidu.com",3),substring("www.baidu.com",5,5);
www.baidu com baidu(索引从1开始)
5).length(str)/octet_length(str):返回参数对应的默认字符集的所有字节数
select length("www.baidu.com"),length("张三丰");
13 9(汉字占三个字节)
6).char_length(str) character_length(str):返回的是字符个数
select char_length("www.baidu.com"),character_length("张三丰");
13 3
7).ltrim(str) rtrim(str) trim(str):去掉字符串左/右/两端的空字符
select char_length(" abc "),
ltrim(" abc "), rtrim(" abc "),
trim(" abc "), char_length(ltrim(" abc ")),
char_length(rtrim(" abc ")),
char_length(trim(" abc "));5 abc “abc ” “ abc” 4 4 3 _:在这里表示空格
8).lcase(str) lower(str) (返回小写)ucase(str) upper(str) (返回大写):返回字母的大小写
select lcase("A"); --a
select lower("A"); --a
select ucase("a"); --A
select upper("a"); --A
9).replace(str,oldstr,newstr) :使用newstr子串替换掉str里的oldstr子串
select replace("www.baidu.com","com","cn");
www.baidu.cn
10.insert(str,pos,len,newstr) :使用newstr子串替换掉str里从pos处开始替换,替换掉len个字符
select insert("www.baidu.com",2,4,"####"); --索引从1开始
w####aidu.com
(3)数值函数
1)pow(x,y)/power(x,y)返回x的y次幂
select pow(8,3),power(8,3);
512 512
2) sqrt(n)
select sqrt(64);--8
select sqrt(2); --1.4142135623730951
3)pi()
select pi(); --3.14159
4)rand() rand(n) :小于1的随机浮点数
select rand(); --0.349491766048122
select rand(1);-- 随机数种子 0.40540353712197724
5) truncate(n,d) :直接取小数点的后d位数
select truncate(3.1465926,2); //3.14
6)round (n,d) :四舍五入保留d位小数
select round(3.145698,2); //3.14
7)mod(n,m) :n/m
select mod(10,3); --1
8)ceiling(n) floor(n)
select ceiling(3.14), floor(3.14); 4 3
(4)高阶函数之排名函数的应用
1.row_number() over(....) 给排序过的表记录分配行号,从1开始连续的自然数
2.rank() over(..) :给排序过的表记录分配名词。相同的值名词一样,后续排名出现跳跃情况( 跳跃式排名) 出现相同的值时,分配的号相同,但是下一个记录会跳一个数分配号,即
1 1 3 3 5 5 7
3.dense_rank() over(...) :给排序过的表记录分配名词。相同的值名词一样,后续排名出不现跳跃情(不跳跃式排名) 1 1 2 2 3 3 3 4 4 5
-- 注意:over是一个开窗函数,用于给字段进行排序和分组的
-- 每一个部门进行排名 partition by 用于指定分组字段
select a.* ,row_number() over(partition by deptno order by sal desc) from emp a;
select a.* ,rank() over(partition by deptno order by sal desc) from emp a;
select a.* ,dense_rank() over(partition by deptno order by sal desc) from emp a;