抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

安装

数据库的基础操作

1
2
3
4
5
6
# 查看所有数据库
show databases;
# 创建数据库
create database database_name;
# 删除数据库
drop database database_name;

⚠️使用drop database命令时,MySQL并不会给出任何提醒、确认信息。该命令执行后,所有数据表和数据也将删除,且操作不可逆。请慎重使用

数据表的基本操作

🌟想要操作数据表,需要使用use database_name指定操作在哪个数据库中执行。如果没有选择数据库,就会抛出No database selected的错误。

创建表

1
2
3
4
5
6
7
# 创建数据表
create table <table_name>(
column_1 data_type,
...
);
# 查看数据表
show tables;

🌟约束

⭐主键约束

主键,又称主码,是表中一列或多列的组合。主键约束(Primary Key Constraint)要求主键列的数据唯一,并且不允许为空。

1
2
3
4
5
# 单字段主键
字段名 数据类 primary key [默认值]
# 多字段主键
[constraint <约束名>] primary key [字段名1,字段名2...]

外键约束

外键,用来在两个表的数据之间的建立连接,可以是一列或者是多列,以确保引用数据的完整性。定义外键之后,不允许删除在另一张表中具有关联关系的行。

主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的那个表即是主表。

从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的那个表即是从表。

优点:保证数据的完整性和一致性,级联操作方便,数据的一致性交给数据库,代码量小。

1
constraint <外键约束名> foreign key(外键名) references <主表> 主键列1 [,主键列2...]

提示

子表的外键必须关联父表的主键,且关联字段的数据类型必须匹配,如果类型不一样,则创建子表时,就会出现错误“ERROR 1005(HY000): Can't create table 'database.tablename'(errno: 150)”

⚠️ 【阿里规范-强制】不得使用外键与级联,一切外键概念在应用层解决。

原因:外键约束每次做delete或者update都必须考虑外键约束,在开发测试时极为不便。

非空约束

非空约束,指字段的值不能为空。用户添加数据未指定值,数据库系统报错。

1
字段名 数据类型 not null

唯一性约束

唯一性约束,要求该列唯一,允许为空,但只能出现一个空值。

1
2
3
4
# 方式一
字段名 数据类型 unique
# 方式二
[constraint <约束名>] unique(<字段名>)

默认值约束

默认值约束,指给某列设定默认值。当插入一条记录没有这个字段值时,系统自动赋值。

1
字段名 数据类型 default 默认值

自增

在数据库应用中,经常希望在每次插入新记录时,系统自动生成字段的主键值。可以通过为表主键添加auto_increment关键字来实现。默认的,在MySQL中auto_increment的初始值是1,每新增一条记录,字段值自动加1。一个表只能有一个字段使用auto_increment约束,且该字段必须为主键的一部分。auto_increment约束的字段可以是任何整数类型(tinyintsmallintintbigint等)。

1
字段名 数据类型 auto_increment

⚠️自增持久化

在MySQL 8.0之前,自增主键auto_increment的值自增主键auto_increment的值如果大于max(primary key)+1,在MySQL重启后,会重置auto_increment=max(primary key)+1。

原理是,在MySQL 5.7系统中,对于自增主键的分配规则,是由InnoDB数据字典内部一个计数器来决定的,而该计数器只在内存中维护,并不会持久化到磁盘中。当数据库重启时,该计数器会通过下面这种方式初始化。

到了MySQL 8.0之后,将自增主键的计数器持久化到重做日志中。每次计数器发生改变,都会将其写入重做日志中。如果数据库重启,InnoDB会根据重做日志中的信息来初始化计数器的内存值。为了尽量减小对系统性能的影响,计数器写入到重做日志时并不会马上刷新数据库系统。

查看表结构

desc / describe语句可以查看表的字段信息,其中包括字段名、字段数据类型、是否为主键、是否有默认值等

1
2
3
desc (describe) 表名;
# 查看表详细结构;\G 参数会使结果更加直观。
show create table <表名\G>

其中,各个字段的含义分别解释如下:

  • NULL:表示该列是否可以存储NULL值
  • Key:表示该列是否已编制索引。PRI表示该列是表主键的一部分;UNI表示该列是UNIQUE索引的一部分;MUL表示在列中某个给定值允许出现多次。
  • Default:表示该列是否有默认值,有的话指定值是多少。
  • Extra:表示可以获取的与给定列有关的附加信息,例如AUTO_INCREMENT等。

🌟修改表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 修改表名
alter table <旧表名> rename [to] <新表名>;
# 修改字段的数据类型
alter table <表名> modify <字段名> <数据类型>;
# 修改字段排列 first添加在最前面,after表示某字段之后,没有配置位置,默认添加在最后。
alter table <表名> modify <字段名> <数据类型> <first | after 已有字段>;
# 修改字段名
alter table <表名> change <旧字段名> <新字段名> <新数据类型>;
# 添加字段
alter table <表名> add <新字段名> <新数据类型> [约束条件] [first | after <已存在字段名>];
# 删除字段
alter table <表名> drop <字段名>;
# 删除表的外键约束
alter table <表名> drop foreign key <外键约束名>;
# 更换存储引擎
alter table <表名> engine=<更换后的存储引擎名称>;

删除表

1
2
drop table [if exists]表1[,表2,...];
# 存在外键约束要先解除外键,才能删除表。

数据类型

整数类型

类型名称 存储空间(/字节) 范围(有符号) 范围(无符号)
tinyint 1 $-27$~$27-1$ 0~$2^8-1$
smallint 2 $-2{15}$~$2{15}-1$ 0~$2^{16}-1$
mediumint 3 $-2{23}$~$2{23}-1$ 0~$2^{24}-1$
int 4 $-2{31}$~$2{31}-1$ 0~$2^{32}-1$
bigint 8 $-2{63}$~$2{63}-1$ 40~$2^{64}-1$

⚠️显示宽度只用于显示,并不能限制取值范围和占用空间。例如:int(3)会占用4字节的存储空间,并且允许的最大值不会是999,而是INT整型所允许的最大值。

浮点数和定点数类型

类型名称 说明 存储空间(/字节)
float 单精度 4
double 双精度 8
decimal(M,D),dec 定点 M+2

⚠️用户指定的精度超出精度范围,则会四舍五入。

💬在MySQL中,定点数以字符串形式存储,在对精度要求比较高的时候(如货币、科学数据等)使用decimal的类型比较好,另外两个浮点数进行减法和比较运算时容易出问题,所以在使用浮点数时需要注意,并尽量避免做浮点数比较。

日期和时间类型

类型名称 日期格式 日期范围 存储空间(/字节)
year yyy 1901~2155 1
time hh:mm:ss -839:59:59 ~ 838:59:59 3
date yyy-MM-dd 1001-01-01 ~ 9999-12-31 3
datetime yyy-MM-dd hh:mm:ss 1001-01-01 00:00:00 ~ 9999-12-3 23:59:59 8
timestamp yyy-MM-dd hh:mm:ss 1970-01-01 00:00:01 utc ~ 2038-01-19 03:17:07 utc 4

⚠️

  • time类型的输入格式为d hh:mm:ss,最终可以转换到hh:mm:ss格式。注意,使用d hh格式输入时,小时一定要是双位,小于10的在前面加0

  • date允许不严格语法:任何标点符号都可以用做日期部分之间的间隔符。

  • datetime在存储日期数据时,按实际输入的格式存储,即输入什么就存储什么,与时区无关;

    timestamp值的存储是以UTC(世界标准时间)格式保存的,存储时对当前时区进行转换,检索时再转换回当前时区。查询时,不同时区显示的时间值是不同的。

文本字符串类型

类型名称 说明 存储空间(/字节)
char(M) 固定长度 $1\leq{M}\leq{255}$
varchar(M) 可变长度 L+1,$L\leq{M}$ 和 $1\leq{M}\leq{255}$
tinytext L+1,$L\leq{2^8}$
text L+2,$L\leq{2^{16}}$
mediumtext L+3,$L\leq{2^{24}}$
longtext L+4,$L\leq{2^{32}}$
enum 枚举类型,只能有一个字符串值 1或者2,取决于枚举值的数目(最大值为65535)
set 设置,字符串对象可以有零个或者多个set成员 1,2,3,4或者8,取决于集合成员的数量(最多64个成员)

二进制字符串类型

类型名称 说明 存储空间(/字节)
bti(M) 位字段 $\frac{M+7}8$
binary(M) 固定长度 M
varbinary(M) 可变长度 M+1
tinyblob(M) 最大长度:$(28-1)2$B L+1,$L\leq{2^8}$
blob(M) 最大长度:$(2{16}-1)2$B L+2,$L\leq{2^{16}}$
mediumblob(M) 最大长度:$(2{24}-1)2$B L+3,$L\leq{2^{24}}$
longblob(M) 最大长度:$(2{32}-1)2$B 或 4GB L+4,$L\leq{2^{32}}$

运算符

运算符是告诉MySQL执行特定算术或逻辑操作的符号。MySQL中的运算符逻辑与C、Java等语言的运算符逻辑相通的内容,就不过多赘述了。以下比较运算符是MySQL特有的。

比较运算符 作用
<=> 安全等于。这个操作符和=操作符执行相同的比较操作,不过<=>可以用来判断NULL值
is null 判断是否为null
is not null 判断是否不为null
least 在有两个或多个参数时,返回最小值
greatest 当有两个或多个参数时,返回最大值
between and 判断一个值是否落在两个值之间
isnull 与is null 作用一致
in 判断一个值是否存在与给定的列表中
not in 判断一个值是否不存在与给定的列表中
like 通配符匹配 【%匹配任意数目(包括0个)的字符;_只能匹配一个字符】
regexp 正则匹配

regexp:

  • ^ 开头
  • $结尾
  • .任意一个
  • *匹配任意个

函数

数学函数

表达式 作用
abs(x) 绝对值
pi() $\pi$,结果保留7位小数
sqrt(x) $\sqrt{x}$
mod(x,y) x被y除后的余数
ceil(x) / ceiling(x) 返回不小于x的最小整数值,返回值转化为一个BIGINT
floor(x) 返回不大于x的最大整数值,返回值转化为一个BIGINT
rand() rand()返回一个随机浮点值v,范围在0到1之间(0 ≤ v ≤1.0)若已指定一个整数参数xrand(x),则它被用作种子值,用来产生重复序列。
round(x)
round(x,y)
round(x) 返回最接近于参数x的整数,对x值进行四舍五入
使用round(x,y)函数对操作数进行四舍五入操作,结果保留小数点后面指定y位。y为负数时,保留的小数点左边的相应位数直接保存为0,不进行四舍五入。
truncate(x,y) 返回被舍去至小数点后y位的数字x。若y的值为0,则结果不带有小数点或不带有小数部分。若y设为负数,则截去(归零)x小数点左起第y位开始后面所有低位的值
sign(x) 返回参数的符号,x的值为负、零或正时返回结果依次为-1、0或1
pow(x,y)
power(x,y)
函数返回x的y次乘方的结果值
log(x)
log10(x)
log(x)返回x的自然对数,x相对于基数e的对数
log10(x)返回x的基数为10的对数
radians(x)
degrees(x)
radians(x)将参数x由角度转化为弧度
degrees(x)将参数x由弧度转化为角度
sin \ cos \ asin \ acos \ tan \ atan \ cot 正弦 \ 余弦 \ 反正弦 \ 反余弦 \ 正切 \ 反正切 \ 余切

字符串函数

函数 作用
char_length(str)
length(str)
返回值为字符串str所包含的字符个数
返回值为字符串的字节长度[中文2 / 英文1]
concat(s1,s2,…) 返回结果为连接参数产生的字符串,或许有一个或多个参数。有null返回null,有二进制返回二进制
concat_ws(x,s1,s2,…) 参数x是其他参数的分隔符,分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其他参数。如果分隔符为NULL,则结果为NULL。函数会忽略任何分隔符参数后的NULL值。
insert(s1,x,len,s2) 返回字符串s1,其子字符串起始于x位置和被字符串s2取代的len字符。如果x超过字符串长度,则返回值为原始字符串。假如len的长度大于其他字符串的长度,则从位置x开始替换。若任何一个参数为NULL,则返回值为NULL
lower (str)
lcase (str)
将字符串str中的字母字符全部转换成小写字母。
upper(str)
ucase(str)
将字符串str中的字母字符全部转换成大写字母。
left(s,n)
right(s,n)
返回字符串s开始的最【左 | 右】边n个字符
lpad(s1,len,s2)
rpad(s1,len,s2)
字符串s1,其【左 | 右】边由字符串s2填补到len字符长度
ltrim(s)
rtrim(s)
trim(s)
返回字符串s,字符串【左 | 右 | 两】侧空格字符被删除
trim(s1 from s) 删除字符串s中两端所有的子字符串s1
repeat(s,n) 重复生成字符串
space(n) 返回一个由n个空格组成的字符串
replace(s,s1,s2) 使用字符串s2替代字符串s中所有的字符串s1。
strcmp(s1,s2) 若所有的字符串均相同,则返回0;若根据当前分类次序,第一个参数小于第二个,则返回-1;其他情况返回1
substring(s,n,len) 带有len参数的格式,从字符串s返回一个长度与len字符相同的子字符串,起始于位置n。也可能对n使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的n字符,即倒数第n个字符,而不是字符串的开头位置
mid(s,n,len) 与上一致。len小于1,结果时空字符串。
locate(str1,str)
position(str1 in str)
instr(str, str1)
返回子字符串str1在字符串str中的开始位置。
reverse(s) 字符串反转
elt(n,字符串1,字符串2,…,字符串n) 若n =1,则返回值为字符串1;若n=2,则返回值为字符串2;以此类推;若n小于1或大于参数的数目,则返回值为null
field(s,s1,s2,…,sn) 返回字符串s在列表s1,s2,…,sn中第一次出现的位置,在找不到s的情况下,返回值为0。如果s为null,则返回值为0,原因是null不能同任何值进行同等比较。
make_set(x,s1,s2,…,sn) 函数按x的二进制数从s1,s2,…,sn中选取字符串。例如5的二进制是0101,这个二进制从右往左的第1位和第3位是1,所以选取s1和s3。s1,s2,…,sn中的null值不会被添加到结果中。

日期时间函数

函数 作用
curdate()
current_date()
将当前日期按照 YYYY-MM-DD
current_timestamp()
localtime()
now()
sysdate()
返回当前日期和时间值,格式为YYYY-MM-DD HH:MM:SS
unix_timestamp(date)
from_unixtime(date)
时间转时间戳
时间戳转时间
utc_date() 返回当前UTC(世界标准时间)日期值,其格式为YYYY-MM-DD
month(date)
monthname(date)
返回date对应的月份,范围值为1~12
返回日期date对应月份的英文全名。
dayname(d)
dayofweek(d)
weekday(d)
dayname(d):返回d对应的工作日的英文名称
dayofweek(d):返回d对应的一周中的索引(位置,1表示周日,2表示周一,…,7表示周六)
weekday(d):返回d对应的工作日索引:0表示周一,1表示周二,…,6表示周日。
week(d)
weekofyear(d)
week(d)计算日期d是一年中的第几周
weekofyear(d)计算某天位于一年中的第几周,范围是1~53
dayofyear(d)
dayofmonth(d)
dayofyear(d)函数返回d是一年中的第几天,范围是1~366
dayofmonth(d)函数返回d是一个月中的第几天,范围是1~31。
year(date)
quarter(date)
month(date)
day(date)
hour(time)
minute(time)
second(time)
年份、季度、月份、日期、小时、分钟和秒钟
extract(type from date) 例如extract(year_month from date)
其中的type是上栏中的类型,年月和day
time_to_sec(time)
sec_to_time(seconds)
时间转成秒数
秒数转成时间
date_add()
adddate()
date_sub()
subdate()
addtime()
subtime()
date_diff()
计算日期和时间的函数
date_format(date,format) 格式化日期
time_format(time,format) 格式化时间

条件判断函数

  • if(expr,v1,v2)

    如果表达式expr是true(expr <> 0 and expr <> null),则返回值为v1;否则返回值为v2。if()的返回值为数字值或字符串值,具体情况视其所在语境而定。

    如果v1或v2中只有一个明确是NULL,则if()函数的结果类型为非null表达式的结果类型。

  • ifnull(v1,v2)

    假如v1不为null,则ifnull()的返回值为v1;否则其返回值为v2。ifnull()的返回值是数字或者字符串,具体情况取决于其所在

  • case

    case expr when v1 then r1 [when v2then r2]…[else rn+1] end:如果expr值等于某个vn,则返回对应位置then后面的结果;如果与所有值都不相等,则返回else后面的rn+1

系统信息函数

作用 函数
获取版本号 version()
获取MySQL服务器当前连接的次数 cibbectuib_id()
显示有哪些线程在运行(包括当前连接数,连接状态、帮助识别) processlist
获取用户名 user()、current_user、current_user()、system_user()和session_user()
获取字符串的字符集 charset(str)
返回字符串str的字符排列方式 collation(str)
返回最后生成的AUTO_INCREMENT值 last_insert_id()

加密函数

函数 描述
md5(str) 字符串算出一个MD5 128比特校验和。该值以32位十六进制数字的二进制字符串形式返回,若参数为NULL,则会返回NULL
sha(str) 从原明文密码str计算并返回加密后的密码字符串,当参数为NULL时,返回NULL。SHA加密算法比MD5更加安全。
sha2(str, hash_length) 使用hash_length作为长度,加密str。hash_length支持的值为224、256、384、512和0。其中,0等同于256。

其他

函数 描述
format(x,n) 将数字x格式化,并以四舍五入的方式保留小数点后n位,结果以字符串的形式返回。若n为0,则返回结果函数不含小数部分。
conv(n, from_base, to_base) 函数进行不同进制数间的转换。返回值为数值n的字符串表示,由from_base进制转化为to_base进制。如有任意一个参数为null,则返回值为null。自变量n被理解为一个整数,但是可以被指定为一个整数或字符串。最小基数为2,最大基数为36。
inet_aton(expr) 给出一个作为字符串的网络地址的点地址表示,返回一个代表该地址数值的整数。地址可以是4或8bit地址。
get_lock(str,timeout)
release_lock(str)
加锁
解锁
benchmark(count,expr) 函数重复count次执行表达式expr
convert(… using …) 带有using的convert()函数被用来在不同的字符集之间转化数据。
cast(x, as type)
convert(x, type)
函数将一个类型的值转换为另一个类型的值,可转换的type有binary、char(n)、date、time、datetime、decimal、signed、unsigned。

🌟数据的操作

查询语句

  • {* | <字段列表>}包含星号通配符和字段列表,表示查询的字段。其中,字段列表至少包含一个字段名称,如果要查询多个字段,多个字段之间用逗号隔开,最后一个字段后不加逗号。

    在字段列前添加distinct去重

  • FROM <表1>,<表2>...,表1和表2表示查询数据的来源,可以是单个或者多个。

  • WHERE子句是可选项,如果选择该项,将限定查询行必须满足的查询条件。

  • GROUP BY <字段>,该子句告诉MySQL如何显示查询出来的数据,并按照指定的字段分组。

    [HAVING <条件表达式>]用来筛选分组之后的数据展示

  • [ORDER BY <字段>],该子句告诉MySQL按什么样的顺序显示查询出来的数据,可以进行的排序有升序(ASC)、降序(DESC)。

  • [LIMIT [<offset>,] <row count>],该子句告诉MySQL每次显示查询出来的数据条数。

  • AS 用于表、列的重命名

聚合函数

函数 描述
avg() 平均值
count() 计数;count(*),会统计空值行;count(字段)会忽略空值行
max() 最大值
min() 最小值
sum() 求和

连接查询

1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE `a` (
`a_id` varchar(100) DEFAULT NULL,
`b_id` varchar(100) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
INSERT INTO `a` VALUES ('1','1','Duo'),('2','1','Tony'),('3','2','Lili'),('4','4','Seri');

CREATE TABLE `b` (
`b_id` varchar(100) DEFAULT NULL,
`class_name` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
INSERT INTO `b` VALUES ('1','体育'),('2','美术'),('3','舞蹈');
表a 表b
a_id b_id
b_id class_name
name
1
2
3
4
5
6
7
8
# 1. 使用where进行连接
select a.name,b.class_name from a,b where a.b_id = b.b_id;
# 2. 使用[inner] join进行连接,等价于使用where连接
select a.name,b.class_name from a [inner] join b on a.b_id = b.b_id;
# 3. left join
select a.name,b.class_name from a left join b on a.b_id = b.b_id;
# 4. right join
select a.name,b.class_name from a right join b on a.b_id = b.b_id;
连接方式 描述
where 内连接,$a\cap{b}$
[inner] join 内连接,$a\cap{b}$
left join 外连接,数据展示以a为主
right join 外连接,数据展示以b为主

子查询

1
2
3
4
5
6
7
8
9
10
11
# 1. any(任意一个) / some(多个,包括一个) / all 所有
select a_id from a where a_id > any (select b_id from b);
select a_id from a where a_id > some (select b_id from b);
select a_id from a where a_id > all (select b_id from b);
# 2. exists / not exists [系统对子查询进行运算以判断它是否返回行,如果至少返回一行,那么exists的结果为true,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么exists返回的结果是false,此时外层语句将不进行查询。not exists 与之相反]
select * from a where [not] exists (select b_id from b where b_id > 12);
# 3. in 限制某字段范围在子查询查询结果中;in 也可以替换成比较运算符
select * from a where b_id in (select b_id from b where class_name != '体育');
# 4. union / union all 合并查询 [两个查询结果列数不等不能合并]
### union all 保留重复值
select * from a union [all] select * from b

插入数据

1
2
insert into table_name [(column_list)] values (value_list);
insert into table_name values (value_list1),(value_list2),...;

更新数据

1
update table_name set column_name1 = value1,... [where 条件];

删除数据

1
delete from table_name [where 条件]

添加计算列

1
2
3
4
5
create table tb1(
a int(9),
b int(9),
c int(9) generated always as ((a+b)) virtual
);

评论