MySQL学习正式篇
2024/11/5
一、表的创建和字段约束
CREATE TABLE s_student(
id BIGINT,
username VARCHAR(20),
age INT,
emal VARCHAR(20)
)
可以看到表中有很多约束,如何使用SQL语句添加这些约束呢?
1、添加主键约束
使用PRIMARY KEY
1.1添加主键约束
--创建表的时候添加
CREATE TABLE s_student(
id BIGINT PRIMARY KEY,
username VARCHAR(20),
age INT,
emal VARCHAR(20)
)
--创建表后添加
CREATE TABLE s_student(
id BIGINT ,
username VARCHAR(20),
age INT,
emal VARCHAR(20)
)
ALTER TABLE s_student ADD PRIMARY KEY (id);
1.2、联合主键
除了单个主键外,SQL还有联合主键:将两个字段同时作为主键使用,语法为:
CREATE TABLE emp2(
xingming VARCHAR(100),
deptId INT,
sal DOUBLE,
PRIMARY KEY (xingming,deptId)
)
注意:
当主键由多个字段组成时候,不能直接在字段后面声明主键.
一张表有一个主键,联合主键也是一个主键
2、添加自增约束,非空约束,默认约束
2.1、自增约束
-- AUTO_INCREMENT 自增
CREATE TABLE emp4(
eid INT PRIMARY KEY AUTO_INCREMENT,
xingming VARCHAR(100),
sal DOUBLE
)
2.2、非空约束
CREATE TABLE emp4(
eid INT,
xingming VARCHAR(100) NOT NULL,
sal DOUBLE
)
2.3、默认约束
CREATE TABLE emp4(
eid INT,
xingming VARCHAR(100),
sal DOUBLE DEFAULET 5000
)
2.4、唯一约束
CREATE TABLE emp4(
eid INT ,
xingming VARCHAR(100) UNIQUE,
sal DOUBLE
)
测试案例:
CREATE TABLE s_student(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL UNIQUE,
age INT DEFAULT 18,
emal VARCHAR(20)
)
3、外键关联
当两个表带有关系时,需要设置外键进行关联,例如学生表和班级表,班级由学生组成
- 主外键关联的时候 删除先删除子表 再删除主表
-- 创建一个学生表和一个班级表
CREATE TABLE students (
id INT PRIMARY KEY,
student_name VARCHAR(42) NOT NULL,
age INT DEFAULT 19,
class VARCHAR(42)
);
CREATE TABLE classes (
class_id INT PRIMARY KEY,
class_name VARCHAR(42) NOT NULL UNIQUE,
teacher VARCHAR(22) NOT NULL
);
-- 添加外键关联
ALTER TABLE students
ADD CONSTRAINT fk_class_name -- 外键名字为:fk_class_name
FOREIGN KEY(class)
REFERENCES classes(class_name);
4、删除约束
-- 删除主键约束(无需键名)
ALTER TABLE students
DROP PRIMARY KEY;
-- 删除外键约束
ALTER TABLE students
DROP FOREIGN KEY fk_class_name;
二、表中数据的插入
2.1、插入班级表数据
-- 插入班级数据
INSERT INTO classes (class_id, class_name, teacher) VALUES
(1, 'Class A', 'Mr. Smith'),
(2, 'Class B', 'Ms. Johnson'),
(3, 'Class C', 'Mrs. Brown'),
(4, 'Class D', 'Mrs. Tom');
2.2、插入学生表数据
-- 插入学生数据
INSERT INTO students (id, student_name, age, class) VALUES
(1, 'Student 1', 25, 'Class A'),
(2, 'Student 2', 19, 'Class A'),
(3, 'Student 3', 19, 'Class A'),
(4, 'Student 4', 20, 'Class A'),
(5, 'Student 5', 19, 'Class A'),
(6, 'Student 6', 22, 'Class A'),
(7, 'Student 7', 19, 'Class A'),
(8, 'Student 8', 23, 'Class A'),
(9, 'Student 9', 24, 'Class B'),
(10, 'Student 10', 19, 'Class B'),
(11, 'Student 11', 18, 'Class B'),
(12, 'Student 12', 23, 'Class B'),
(13, 'Student 13', 20, 'Class B'),
(14, 'Student 14', 19, 'Class B'),
(15, 'Student 15', 24, 'Class B'),
(16, 'Student 16', 19, 'Class B'),
(17, 'Student 17', 11, 'Class C'),
(18, 'Student 18', 19, 'Class C'),
(19, 'Student 19', 12, 'Class C'),
(20, 'Student 20', 21, 'Class C'),
(21, 'Student 21', 15, 'Class C'),
(22, 'Student 22', 19, 'Class C'),
(23, 'Student 23', 18, 'Class C'),
(24, 'Student 24', 19, 'Class C'),
(25, 'Student 25', 22, NULL);
二、DQL表的数据查询语法
1、语法
select
[all | distinct]
<目标列的表达式1> [别名],
<目标列的表达式2> [别名]
...
from <表名或者视图名> [别名],<表名或者视图名> [别名] ...
[where <条件表达式>]
[group by <列名>]
[having <条件表达式>]
[order by 列名 [asc | desc]]
[limit <数字或者列表>];
2、单表查询
2.1、查询所有
-- 查找班级为ClassA的学生
SELECT *
FROM students
WHERE class = 'Class A';
2.2、查询所有,给表起名
SELECT *
FROM students students1; -- students1是查询出来后的表的别名
2.3、给列起别名
SELECT student_name AS name_std
FROM students
WHERE class = 'Class A';
2.4、去重查询
SELECT DISTINCT class
FROM students;
3、运算符
Mysql支持4中运算符
3.1、算数运算符
运算符 | 含义 |
+ | 加 |
- | 减 |
* | 乘 |
/ 或者 div | 除 |
% 或者 mod | 取余 |
3.2、比较运算符
运算符 | 含义 |
< | 小于 |
<= | 小于等于 |
= | 乘 |
> | 大于 |
>= | 大于等于 |
<> 或者 != | 不等于 |
<=> | 绝对相等 |
is null is not null | 空 非空 |
in not in | 包含 不包含 in(1,2,3)查询列值为123的数据 |
like | 模糊查询,用于%水%,查询带水的数据 |
createst least | 最大最小值 |
regex | 正则表达式 |
3.3、逻辑运算符
运算符 | 含义 |
not ! | 逻辑非 |
and && | 逻辑与 |
or || | 逻辑或 |
XOR | 异或 |
3.4、位运算符【了解】
运算符 | 含义 |
| | 按位或 |
& | 按位与 |
^ | 按位异或 |
~ | 按位非 |
<< 和 >> | 左移和右移 |
4、排序
排序的语法:
select 字段名1,字段名2 ...
from 表名
order by 字段名1 [asc|desc] ,字段名2[asc|desc] .....
asc 表示升序 desc 表示降序 如果不写默认升序
order by 支持单个字段 多个字段 表达式 函数 别名
order by 子句放在查询语句的后面 limit除外
5、聚合查询 [聚合函数 聚集函数]
count() | 统计的是指定列不为null的行数 |
sum() | 指定列的数值之和 如果查询查询的指定列不是数值类型,那么计算结果为0 |
max() | 最大值 |
min() | 最小值 |
avg() | 平均值 |
6、分组查询
分组查询的语法:
select 字段名1,字段名2 ...
from 表名
group by 分组字段 having 分组条件
SELECT category_id,COUNT(*)
FROM product
GROUP BY category_id;
如果要进行分组,select子句之后,只能出现分组字段和统计函数,其他的字段不能出现!!
7、分页查询
分页查询语法:
select 字段名1,字段名2 ...
from 表名 limit m,n
SET @page_size = 10; -- 每页显示的记录数
SET @page_number = 2; -- 当前页码SELECT *
FROM students
LIMIT @page_size OFFSET (@page_number - 1) * @page_size;
m: 整数 表示从第几条开始 (当前页-1)*pageSize
n: 整数 表示查询几条记录
8、查询数据的存储
insert into 目标表 select 查询表 (表中字段与查询出的临时表的字段必须完全一致)
将一张的表数据导入到另外一张表 需要把表创建了!
SELECT value1,value2 INTO table2 FROM table1;(MySQL不指出,SQL Server支持)
要求table2是不存在的,因为插入的时候会临时创建
9、正则表达式
- ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
- $ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
- . 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。
- [...] 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
- [^...] 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。
- p1|p2|p3 匹配 p1 或 p2 或 p3。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。
- * 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。
- + 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
- {n} n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
- {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。
10、关联查询
关联查询是指在 SQL 查询中使用一个或多个表之间的关系。通常通过主键和外键的关系来实现。
假设有两个表 students
和 classes
,我们可以通过关联查询来获取每个学生的班级信息。
I、内连接(INNER JOIN)
内连接只返回在两个表中都有匹配记录的行。
SELECT students.student_name, classes.class_name
FROM students
INNER JOIN classes ON students.class = classes.class_name;
II、左连接(LEFT JOIN)
左连接返回左表中的所有行,以及右表中匹配的行。如果右表没有匹配,则结果为 NULL
。
SELECT students.student_name, classes.class_name
FROM students
LEFT JOIN classes ON students.class = classes.class_name;
III、右连接(RIGHT JOIN)
右连接返回右表中的所有行,以及左表中匹配的行。如果左表没有匹配,则结果为 NULL
。
SELECT students.student_name, classes.class_name
FROM students
RIGHT JOIN classes ON students.class = classes.class_name;
IV、全连接(FULL JOIN)
MySQL 不直接支持全连接,但可以通过联合左连接和右连接来模拟。
SELECT students.student_name, classes.class_name
FROM students
LEFT JOIN classes ON students.class = classes.class_name
UNION
SELECT students.student_name, classes.class_name
FROM students
RIGHT JOIN classes ON students.class = classes.class_name;