第5步---MySQL的DQL查询语句

第5步---MySQL的DQL查询语句

 DQL 数据库查询语言

 1.基本的查询语句

1.完整得查询得语句

简化版的查询语句

 

select * from 表名 where 条件;

2.创建用于测试的表

1.创建测试数据


-- =================================DQL=================================
-- 创建测试表
DROP TABLE IF EXISTS product;
CREATE TABLE IF NOT EXISTS product(
pid int PRIMARY KEY  auto_increment COMMENT '商品编号',
pname  VARCHAR(20)  not null COMMENT '商品名称',
price  DOUBLE COMMENT '价格',
category_id  VARCHAR(20) COMMENT '商品类别'
)-- 添加测试数据
INSERT INTO product VALUES 
(NULL,'苹果',5000,'c001'),
(NULL,'香蕉',50,'c001'),
(NULL,'西红柿',6000,'c001'),
(NULL,'西瓜',3000,'c001'),
(NULL,'杨桃',5500,'c001'),
(NULL,'手机',7000,'c001');INSERT INTO product VALUES 
(NULL,'苹果',5000,'c002'),
(NULL,'香蕉',50,'c002'),
(NULL,'西红柿',6000,'c002'),
(NULL,'西瓜',3000,'c002'),
(NULL,'杨桃',5500,'c002'),
(NULL,'手机',7000,'c002');INSERT INTO product VALUES 
(NULL,'苹果',5000,'c003'),
(NULL,'香蕉',50,'c003'),
(NULL,'西红柿',6000,'c003'),
(NULL,'西瓜',3000,'c003'),
(NULL,'杨桃',5500,'c003'),
(NULL,'手机',7000,'c003');INSERT INTO product VALUES 
(NULL,'苹果',5000,'c004'),
(NULL,'香蕉',50,'c004'),
(NULL,'西红柿',6000,'c004'),
(NULL,'西瓜',3000,'c004'),
(NULL,'杨桃',5500,'c004'),
(NULL,'手机',7000,'c004');

2.基本的查询


-- 查询所有的数据
SELECT * FROM product;-- 查询指定的列的数据
SELECT  pid,pname ,price,category_id FROM product;
SELECT  pid,pname FROM product;-- 起表别名
-- 多表查询中是可以给的
SELECT * FROM product p;
SELECT * FROM product as p;-- 列别名
SELECT pid AS ppid FROM product;
SELECT pid AS 编码 FROM product;-- 去重
SELECT DISTINCT price FROM product;-- 去除所有列都一样的数据
SELECT DISTINCT * FROM product;-- 表达式查询
SELECT  price ,price+10  new_price  FROM product;

3.运算符

1.算数运算符:加减乘除 /或者div %或者mod

2.比较:条件查询。null和所有的值都是不相等的。

 3.逻辑:

 4.位:

 3.1算数运算符

-- =============================算数运算符号=======================
-- 基本操作
SELECT 6+4;
SELECT 6-4;
SELECT 6*4;
SELECT 6/4;
SELECT 6%4;
SELECT 6 div 4;
SELECT 6 mod 4;-- 所有的商品+10元
SELECT  price ,price+10  new_price  FROM product;--  所有的商品增加10%元
SELECT  price ,price*(1.1)  new_price  FROM product;-- 所有的商品+10元
SELECT  price ,price+10  new_price  FROM product;--  所有的商品增加10%元
SELECT  price ,price*(1.1)  new_price  FROM product;-- 找苹果商品的所有的信息
SELECT *FROM product WHERE pname ='苹果';-- 找出价格为5000的商品
SELECT *FROM product WHERE price =5000;-- 查询价格不是5000的商品
SELECT *FROM product WHERE price !=5000;
SELECT *FROM product WHERE price <>5000;
SELECT *FROM product WHERE  not price =5000;
SELECT *FROM product WHERE   price not in (5000);-- 查询价格> 5000的商品
SELECT *FROM product WHERE price > 5000;-- 查询价格5000到7000之间的的商品
SELECT *FROM product WHERE price BETWEEN  5000 AND 7000;
SELECT *FROM product WHERE price  >=5000 AND price <= 7000;-- 查询价格5000或7000的商品
SELECT *FROM product WHERE price =5000 or price = 7000;
SELECT *FROM product WHERE price in (5000 , 7000);-- 查询含有果的词
-- %任意字符
-- 前面任意
SELECT *FROM product WHERE pname LIKE '%果';
-- 后面任意
SELECT *FROM product WHERE pname LIKE '果%';
-- 前后任意
SELECT *FROM product WHERE pname LIKE '%果%';-- 下划线匹配单个字符
-- 查询第二个字含有果的词
SELECT *FROM product WHERE pname LIKE '_果%';注意:坚决不能使用等号!!!
-- 查询类别不为null的所有的数据
SELECT *FROM product WHERE category_id IS NOT NULL;-- 查询类别为null的所有的数据
SELECT *FROM product WHERE category_id IS  NULL;-- 求几个值的最小值
SELECT LEAST(10,20,5) as small_number;-- 求几个值的最大值
SELECT GREATEST(10,20,5) as small_number;求最大值或者是最小值的时候要是存在null的话结果直接就是null不是我们需要的值。

求最大值或者是最小值的时候要是存在null的话结果直接就是null不是我们需要的值。
 

 3.2位运算符

主要是对二进制的相关的操作

-- =============================位相关操作===============================
-- 位与
SELECT 3 &5;
-- 0011
-- 0101
-- 结果:0001 全是1的时候才全是1-- 位或
-- 不是0就是1
SELECT 3 | 5;-- 右移位
SELECT 2>>1;-- 左移位
SELECT 2<<1;-- 位取反 
-- 1变0,0变1,变的很大的数的原因是2是32位的数字
SELECT ~2;

4.基本查询-排序

排序  

-- ===================================排序和分页====================================
-- 按照降价降序
-- 默认升序
SELECT * FROM product ORDER BY price;
SELECT * FROM product ORDER BY price ASC;
-- 降序
SELECT * FROM product ORDER BY price DESC;-- 价格降序 分配升序
SELECT * FROM product ORDER BY price DESC,category_id ASC;-- 查询所有的价格 去重
SELECT DISTINCT price FROM product ORDER BY price ASC;

5.基本查询-聚合操作

下面的操作是针对不同的列的相关的操作

 

count 行数
sum 数值和-- ==========================================聚合操作===================================-- 商品条数
-- * 不为空的行
SELECT COUNT(*) FROM product ;SELECT COUNT(pid) FROM product ;-- 价格大于5000的商品的总条数SELECT COUNT(pid) FROM product  WHERE price > 5000;-- 查询c001商品的总价格SELECT SUM(price) FROM product  WHERE category_id ='c001';-- 查询商品的最大价格SELECT Max(price) FROM product  ;-- 查询商品的最小价格SELECT Min(price) FROM product  ;-- 平均价格SELECT Avg(price) FROM product  ;-- 求某个类的平均价格SELECT Avg(price) FROM product  WHERE category_id ='c001';-- 求最大和最小价格SELECT Min(price),Max(price)  FROM product  ;

对null的操作

 

-- ==========================================聚合操作-对null的操作===================================
-- 创建测试表
DROP TABLE IF EXISTS test_null;
CREATE TABLE IF NOT EXISTS test_null(
c1 VARCHAR(20),
c2 int 
);
-- 创建测试数据
INSERT INTO test_null VALUES
('aaa',3),
('bbb',4),
('ccc',NULL),
(NULL,5);-- 测试
-- 要是选中的列是null的视而不见的,不进行统计
SELECT COUNT(*) ,COUNT(1) ,COUNT(c1),COUNT(c2)FROM test_null;-- 要是null的话,求平均值的时候就当作不存在的
SELECT max(c2) ,min(c2) ,avg(c2)FROM test_null;

6.聚合操作-分组查询

多了一个分组。可以一个或者是多个分组,可以采用having进行相关的分组的操作

必须商品中的类别就是一个分组的条件。

-- ==========================================聚合操作-分组查询===================================-- 统计 不同分类的商品
-- 相当于把相同类别的设置成了一张表,分别对其进行求和的操作
SELECT category_id,COUNT(*) FROM product GROUP BY category_id;SELECT category_id ,COUNT(1) FROM product GROUP BY category_id;

 下面是对分组过程的介绍。分组一般是和聚合是在一起进行使用的。

 

7.聚合操作-分组筛选

-- ==========================================聚合操作-分组筛选===================================
-- 统计每个类别的商品的数量并且将输出每个类别中商品数量大于5的类别的id和商品数量
SELECT category_id ,COUNT(1) FROM product GROUP BY category_id HAVING COUNT(1)>5 ;

下面是执行的顺序

 

可以加上对应的排序的字段
-- 加上排序
SELECT category_id ,COUNT(1) FROM product GROUP BY category_id HAVING COUNT(1)>5 ORDER BY category_id DESC ;

8.基本查询-分页查询

limit n:显示前n条

limit m,n:从m+1条开始显示n条


-- ==========================================基本查询-分页操作===================================
-- 显示前5条数据
SELECT * FROM product LIMIT 5;-- 从第4条开始显示5条
SELECT * FROM product LIMIT 3,5;-- 模拟分页
-- (当前页-1)*页大小
SELECT * FROM product LIMIT 0,5;SELECT * FROM product LIMIT 5,5;

9.将查询结果插入到新的表

将后面的结果插入到前面的表

  • 字段一致

  • 类型一致

  • 要插入的表必须先存在

-- ==========================================基本查询-插入新的表中===================================-- 创建测试的表
CREATE TABLE IF NOT EXISTS product2(
id int PRIMARY key ,
pname VARCHAR(20) ,
price DOUBLE
);-- 插入到上面的表
INSERT INTO product2(id,pname,price) SELECT pid,pname,price FROM product;

10.基本查询-总结

  • 简单查询:不加任何的条件。全表。字段和*。别名查询。列和表的别名。

  • 去重查询:distinct。去重重复的列或者重复的行。

  • 运算符:算数,比较,逻辑和位。

默认的是升序asc。

特点:如果order by后面跟一个字段,只会按照该字段的值进行排序。其他的字符是没有排序的。

聚合查询操作:

count(1)等价于count(*)

注意有null的值就不进行相关的操作,

分组操作:

  • 将一个表拆分成多个表

  • 分组的时候可以根据多个字段进行分组。字段相同的分到一个组,多个字段相同也是可以分到一个组中。

  • 分完组之后后面只能跟分组字段和聚合操作

  • 一般情况下聚合函数和分组函数聚合在一起使用

  • 后续的操作必须采用having进行相关的聚合的操作

分页字段:limit

书写顺序:

select 字段 from 表
where 条件
group by 分组
having 筛选(必须根据分组的条件)
order by 排序字段
limit 分页

执行顺序

from 从哪个表中进行查询
where 筛选查询的结果group by 分组统计
count 执行聚合操作
having 筛选聚合的东西
select 进行查询
order by 排序limit 进行筛选

11.中级查询-sql中级操作

-- =================================中级查询=====================
-- 创建测试数据
DROP TABLE IF  EXISTS student;
CREATE TABLE  IF NOT EXISTS student(
id INT,
name VARCHAR(20),
gender VARCHAR(20),
chinese INT,
english INT,
math INT
);INSERT INTO student(id,name,gender,chinese,english,math) VALUES(1,'张三','男',89,79,70);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(2,'李四','女',89,99,80);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(3,'王五','男',79,69,90);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(4,'赵六','女',89,79,40);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(5,'陈二','男',99,89,50);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(6,'王瓜','女',49,99,60);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(7,'轧盖','男',59,89,70);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(8,'赵恒','女',69,49,80);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(8,'赵恒','女',69,49,80);-- 查询所有的数据SELECT * FROM student;-- 查询表中所有的学生的姓名和对应的英语成绩SELECT name,english FROM student ;-- 去重SELECT DISTINCT * FROM student ;-- 统计学生的总分SELECT  DISTINCT FROM student  ;-- 先进行去重了然后对不同学生的进行求总分-- 分组的时候必须进行起别名SELECT name, sum(chinese + english + math)  AS total FROM 
(SELECT * FROM student ) tmp GROUP BY name-- 对上面的总分加上10SELECT name, sum(chinese + english + math + 10)  AS total FROM 
(SELECT * FROM student ) tmp GROUP BY name-- 找出英语大于90分的SELECT  * FROM student WHERE english>90;-- 查出总分大于200的-- 聚合操作的求和SELECT name,sum(chinese + english + math ) total  FROM  (SELECT DISTINCT  * FROM student ) tmp GROUP BY name HAVING total > 200;-- 非聚合操作的求和-- 此时不能用前面的别名但是having是可以。原因是执行顺序的原因SELECT  DISTINCT name,(chinese + english + math) total   FROM student WHERE (chinese + english + math)>200;-- 找出英语在80-90之间的SELECT  * FROM student WHERE english >=80 and english <=90;SELECT  * FROM student WHERE english BETWEEN 80 AND 90;-- 找出英语不在80-90之间的SELECT  * FROM student WHERE english NOT  BETWEEN 80 AND 90;SELECT  * FROM student WHERE NOT (english   BETWEEN 80 AND 90);SELECT  * FROM student WHERE NOT (english >=80 and english <=90);SELECT  * FROM student WHERE  english <80 OR english >90;-- 查询数学是70和50的同学SELECT  * FROM student WHERE math  =  70 OR math  =50;SELECT  * FROM student WHERE math  =  IN (70,50);-- 查询数学是不是70或50的同学SELECT  * FROM student WHERE math  != 70 AND math  !=50;SELECT  * FROM student WHERE math   NOT IN (70,50);-- 查询所有姓王的英语成绩SELECT  name,english  FROM student WHERE  name LIKE '%王';-- 查询总分是238并且姓张的同学的信息SELECT * FROM student WHERE name like '张%' AND (chinese + english + math)=238;-- 按照分数从高到低的顺序查询并显示出来SELECT id,name,SUM(english+chinese+math) AS count ,gender FROM (SELECT DISTINCT * FROM student)  s GROUP BY id  ORDER BY count;-- 按照性别进行查询并统计男和女的顺序,根据性别进行降序输出SELECT gender,COUNT(gender) AS count FROM student GROUP BY gender HAVING count >=5 ORDER BY count;

12.正则表达式

定义了一些相关的字符串的匹配的规则,本身是一个字符串,回匹配一些列符合某个句法的规则的字符串。常常用于检索,替换那些符合规则恶的文本,

可以采用regexp关键字支持正则表达式

^ 匹配输入字符串开始位置
$ 匹配输入字符串结束位置
. 匹配除了\n之外的任何单个字符
[...] 字符集合,包含的任意一个字符。[abc]可以匹配 plain中的a
[^...]负值字符集合。匹配未包含的任意字符
p1|p2|p3 匹配p1 p2或者 p3
* 0次或者多次
+ 匹配前面子表达式一次或者多次
{n} 
{n,m}

下面是演示在项目中的基本的使用

 -- ====================正则表达式-- 判断字符串是不是以a开头SELECT 'abc' REGEXP '^a';-- $判断以某个字符结尾的SELECT 'abc' REGEXP 'a$';SELECT 'abc' REGEXP 'c$';

下面是常见的正则匹配

 -- ======================下面是真正的项目中的使用-- 找以苹开始的所有的信息SELECT * FROM product WHERE pname REGEXP '^苹';-- 找以国结尾的数据SELECT * FROM product WHERE pname REGEXP '国$';-- .可以匹配任意单个字符SELECT 'abc' REGEXP '.a';-- 0SELECT 'abc' REGEXP '.b';-- 1SELECT 'abc' REGEXP '.c'; -- 1-- [...]匹配括号内的任意单个字符SELECT 'abc' REGEXP '[ade]'-- 1SELECT 'abc' REGEXP '[xyz]'-- 0-- [^..]匹配括号内的任意单个字符SELECT 'a' REGEXP '[^ade]'; -- 0SELECT 'abc' REGEXP '[^ade]'; -- 1SELECT 'abc' REGEXP '[^xyz]'; -- 1-- * 匹配0到多个字符SELECT 'stab' REGEXP '.ta*b'; -- 1SELECT 'stb' REGEXP 'ta*b'; -- -- a+ 字符a出现一次或者多次SELECT 'stab' REGEXP '.ta+b'; -- 1SELECT 'stb' REGEXP 'ta+b'; -- 0-- a? 匹配0个或者1个字符SELECT 'abc' REGEXP 'a?'SELECT 'bc' REGEXP 'a?'-- a1 |a2匹配a1或者a2SELECT 'a' REGEXP 'a|b';SELECT 'c' REGEXP 'a|b';

下面是剩下的常见的正则匹配的规则

-- 以a或者b开头的SELECT 'abc' REGEXP '^(a|b)';SELECT 'cd' REGEXP '^(a|b)';-- a{m} 匹配m个aSELECT 'aaab' REGEXP 'a{4}'; -- 0-- a{m,} 至少出现m次SELECT 'aaaa' REGEXP 'a{3}';-- 1SELECT 'aaaa' REGEXP 'a{5}';-- 0-- a{m,n} 至多n,至少出现m次SELECT 'aaaa' REGEXP 'a{4,5}';-- 1--  (ab)必须以ab整体匹配SELECT 'abc' REGEXP '(ab)';-- 1SELECT 'abc' REGEXP '(ab){2,}';-- 0

13.多表操作

表关系就是表与之间的关系

1v1的关系

  • 一个学生对应一个身份证一个身份证对应一个学生

  • 在一个表中就行不用分成两个表

1v多

  • 部门和员工:一个部门有多个员工,一个员工只能对应一个部门

  • 外键在多端的一方

 

多对多

  • 学生和课程之间就是多对多的关系

  • 演员和角色之间的关系

  • 中间表的形式进行表示

外键约束

  • 表的特殊的字段和主键一起配合进行使用

  • 外键关联的表是从表。也就是说有外键的表是从表,没有外键的表是主表。

  • 员工和部门之间的关系就是员工表是从表,部门表是主表。

  • 我们可以把表的类型分为主表和从表。

 

主表必须存在。必须是主键。不能包含空的值。可以采用复合的外键。外键中的列数必须和主键中的列数是一致的

14.外键约束

14.1外键约束的基本操作

创建表的时候可以指定外键约束。

在创建表的时候可以采用foreign key 去指定外键。

 -- 创建部门表DROP TABLE IF EXISTS dept;CREATE TABLE IF not EXISTS dept(deptno VARCHAR(20) PRIMARY key,name VARCHAR(20));DROP TABLE IF EXISTS emp;CREATE TABLE IF NOT EXISTS emp(eid VARCHAR(20) PRIMARY KEY,ename VARCHAR(20) ,age int,dept_id VARCHAR(20) ,CONSTRAINT fk FOREIGN KEY (dept_id) REFERENCES dept(deptno));

 创建完表再去添加表的约束

 -- 创建部门表DROP TABLE IF EXISTS dept2;CREATE TABLE IF not EXISTS dept2(deptno VARCHAR(20) PRIMARY key,name VARCHAR(20));DROP TABLE IF EXISTS emp2;CREATE TABLE IF NOT EXISTS emp2(eid VARCHAR(20) PRIMARY KEY,ename VARCHAR(20) ,age int,dept_id VARCHAR(20) 
--  CONSTRAINT fk FOREIGN KEY (dept_id) REFERENCES dept(deptno)
--  );ALTER TABLE emp2 ADD CONSTRAINT fk2 FOREIGN KEY (dept_id) REFERENCES dept2(deptno);

14.2外键约束的数据

必须先给部门表进行数据插入

 -- 给主表添加数据insert into dept VALUES
('1001','研发部'),
('1002','销售部'),
('1003','财务部'),
('1004','人事部');

然后给从表添加数据

 -- 给从表添加数据insert into emp VALUES
('1','张三',20,'1001'),
('2','张三',20,'1002'),
('3','张三',20,'1003'),
('4','张三',20,'1004');

测试外键约束

  • 失败:存在重复

  • 成功:可以插入外键可以指定为null

 -- 测试外键约束insert into emp VALUES ('1','张三',20,'1005');
-- null是可以的insert into emp VALUES ('1','张三',20,NULL);

删除测试

--dept数据 删除DELETE FROM dept WHERE deptno='1002';删除是拒绝的
从表的数据是可以随便删除的,删除的时候需要注意

14.3删除外键约束

采用修改表的方式进行删除

 ALTER TABLE 表名 DROP FOREIGN key  外键约束名称;ALTER TABLE emp2 DROP FOREIGN key  fk2;

14.4多对多外键约束

相互之间的约束

采用中间表的形式。除了中间表都是主表。

DROP TABLE IF EXISTS stu;CREATE TABLE IF not EXISTS stu(stu_id VARCHAR(20) PRIMARY key,stu_name VARCHAR(20));DROP TABLE IF EXISTS score;CREATE TABLE IF not EXISTS score(score_id VARCHAR(20) PRIMARY key,score_name VARCHAR(20));DROP TABLE IF EXISTS stu_score;CREATE TABLE IF not EXISTS stu_score(stu_id VARCHAR(20),score_id VARCHAR(20),score DOUBLE, -- 课程成绩PRIMARY key (stu_id,score_id));ALTER TABLE stu_score ADD CONSTRAINT FOREIGN KEY (stu_id) REFERENCES stu(stu_id);ALTER TABLE stu_score ADD CONSTRAINT FOREIGN KEY (score_id) REFERENCES score(score_id);

查看表模型

 

删除表的时候必须先删除从表。添加数据的时候先给主表添加数据

删除数据的时候先删除从表中的数据再去删除主表中的数据。

此时数据就像是添加了对应的字典的限制似的,不能直接进行删除的操作。

 

 

15.多表联合查询

15.1常见的联合查询的类型

下面是常见的连接查询的操作.

 

  • 直接查询就是笛卡尔积

  • 内连接

  • 左外

  • 右外

  • 满外连接

创建基本的表和测试的数据

-- ============================多表查询-数据准备=============
-- 创建部门表
create table if not exists dept3(deptno varchar(20) primary key ,  -- 部门号name varchar(20) -- 部门名字
);-- 创建员工表
create table if not exists emp3(eid varchar(20) primary key , -- 员工编号ename varchar(20), -- 员工名字age int,  -- 员工年龄dept_id varchar(20)  -- 员工所属部门
);-- 给dept3表添加数据
insert into dept3 values('1001','研发部');
insert into dept3 values('1002','销售部');
insert into dept3 values('1003','财务部');
insert into dept3 values('1004','人事部');-- 给emp3表添加数据
insert into emp3 values('1','乔峰',20, '1001');
insert into emp3 values('2','段誉',21, '1001');
insert into emp3 values('3','虚竹',23, '1001');
insert into emp3 values('4','阿紫',18, '1001');
insert into emp3 values('5','扫地僧',85, '1002');
insert into emp3 values('6','李秋水',33, '1002');
insert into emp3 values('7','鸠摩智',50, '1002'); 
insert into emp3 values('8','天山童姥',60, '1003');
insert into emp3 values('9','慕容博',58, '1003');
insert into emp3 values('10','丁春秋',71, '1005');

15.2不加连接条件的查询

直接形成一个笛卡尔积,两个表中的数据进行相乘

a表的每一行和b表的每一行进行匹配。

冗余的数据非常多

 

行数=部门行数*员工行数

列数=部门列数+员工行数

-- ======交叉查询
SELECT * FROM dept3,emp3;

15.3内连接查询

交集查询

-- 采用999标准写
-- ====内连接查询
SELECT * from  dept3   INNER JOIN emp3 on dept3.deptno=emp3.dept_id;-- 等价于下面的效果 
-- inner可以默认不写效果是一样的
SELECT * from  dept3    JOIN emp3 on dept3.deptno=emp3.dept_id;

上面查询的哪个部门有哪些员工,就是采用的内连接的形式。

-- 查询研发部门的员工
SELECT * from  dept3 d JOIN emp3 e on d.deptno=e.dept_id where d.name ='研发部';-- 查询研发部和销售部的所属员工
select * from dept3 a join emp3 b on a.deptno = b.dept_id and (name = '研发部' or name = '销售部') ; 
select * from dept3 a join emp3 b on a.deptno = b.dept_id and name in('研发部' ,'销售部') ; -- 查询每个部门的员工数,并升序排序
select a.*,COUNT(*) as total from dept3 a join emp3 b on a.deptno = b.dept_id  GROUP BY a.deptno ; -- 查询人数大于等于3的部门,并按照人数降序排序
select a.*,COUNT(*) as total from dept3 a join emp3 b on a.deptno = b.dept_id  GROUP BY a.deptno HAVING total>3 ORDER BY total DESC; 

15.4外连接查询

左外和右外和全连接

oracle中是有full join的但是在MySQL中是没有的需要采用union进行连接的。

-- =================外连接查询
-- 查询哪些部门有员工,哪些部门没有员工
-- 本质就是查询所有部门的员工
SELECT * FROM dept3 d LEFT JOIN emp3 e on  d.deptno=e.dept_id;-- 查询哪些员工有部门,哪些员工没有部门
SELECT * FROM dept3 d RIGHT JOIN emp3 e on  d.deptno=e.dept_id;-- 合并查询的结果
SELECT * FROM dept3 d LEFT JOIN emp3 e on  d.deptno=e.dept_id
UNION
SELECT * FROM dept3 d RIGHT JOIN emp3 e on  d.deptno=e.dept_id;

15.5多表联合查询

多表联合查询

select from where c> all查询语句等价于下面的语句
select from where c> result1 and  c> result2 and c> result3 也就是c大于所有的子查询得结果

特点:

  • 与子查询中所有得结果比较才是true,否则是false

  • all可以和=,>等进行结合使用。表示大于所有得,表示等于所有得值,表示大于等于所有得值。

-- ================多表联合查询================
-- 子查询关键字-- 查询年龄大于1003部门中所有年龄员工得信息
SELECT * FROM  emp3  WHERE age > all(SELECT age FROM emp3 WHERE  dept_id='1003');
-- 查询不属于任何一个部门得员工信息
SELECT * FROM  emp3  WHERE dept_id != all(SELECT deptno FROM dept3 );

下面是any和some

  • any:只要比其中一个值大于,小于等就行。不需要比较所有得值。只需要比较部分得值。

  • some:和any得作用是一致得。可以理解为any得别名。

-- 查询年龄大于1003部门中任意一个员工员工得信息
SELECT * FROM  emp3  WHERE age > ANY(SELECT age FROM emp3 WHERE  dept_id='1003' ) and dept_id !='1003';SELECT * FROM  emp3  WHERE age > SOME(SELECT age FROM emp3 WHERE  dept_id='1003' ) and dept_id !='1003';

 15.6自关联查询

自己关联自己,就是隐式自连接得操作。可以采用内连接得操作。一张表当作多张表进行使用。

CREATE TABLE `t_sanguo` (`eid` int(11) NOT NULL AUTO_INCREMENT,`ename` varchar(30) DEFAULT NULL,`manager_id` int(11) DEFAULT NULL,PRIMARY KEY (`eid`),KEY `manager_id` (`manager_id`),CONSTRAINT `t_sanguo_ibfk_1` FOREIGN KEY (`manager_id`) REFERENCES `t_sanguo` (`eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (1, '刘协', NULL);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (2, '刘备', 1);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (3, '关羽', 2);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (4, '张飞', 2);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (5, '曹操', 1);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (6, '许诸', 5);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (7, '孙权', 1);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (8, '周瑜', 7);
-- ===================================自关联查询===================
SELECT * FROM t_sanguo;-- 查询每一个人物得信息并且包含领导得信息
-- 就是左表得manager_id等于右表的eid
SELECT t1.*,t2.eid '领导编号' , t2.ename '领导名称' FROM t_sanguo t1 LEFT JOIN  t_sanguo t2 ON t1.manager_id=t2.eid;-- 擦汗寻所有人物和上级和上上级
SELECT t.eid,t.ename ,temp.eid '上级领导编号' ,temp.ename '上级领导名',temp.`领导编号`,temp.`领导名称`   FROM t_sanguo t LEFT JOIN (
SELECT t1.*,t2.eid '领导编号' , t2.ename '领导名称' FROM t_sanguo t1 LEFT JOIN  t_sanguo t2 ON t1.manager_id=t2.eid
) temp  ON t.manager_id=temp.eid-- 下面是采用自关联三张表的操作进行的查询的操作将自己作为三张独立的表进行的关联的查询的操作
SELECT 
t1.eid  ,t1.ename ,
t2.eid '上级领导编号' ,t2.ename '上级领导姓名',
t3.eid  '上上级领导编号',t3.ename  '上上级领导姓名'
FROM t_sanguo t1
LEFT JOIN t_sanguo t2  on t1.manager_id =t2.eid
LEFT JOIN t_sanguo t3 on t2.manager_id =t3.eid

15.7多表查询总结

外键约束

  • 主表

  • 从表

外键约束的创建的方式

  • 直接在后面加上外键

  • 采用修改表的方式进行创建外键约束

特点:

  • 主表的数据可以随便加,不能随便删除

  • 从表的数据可随便删除,不能随便添加

连接查询

  • 内:join就是。两张表的交集。

  • 外:左外和右外。

  • 全:union可以合并左外和右外的连接的查询的结果

  • 交叉:不用,笛卡尔积

自查询:

  • select的嵌套查询

  • 子查询的结果作为一个值 = 的操作,多个值 in的操作。当作一个表,可以进行表的连接的查询的操作

关键字

  • all:全部满足

  • any和some只是有一个满足就是可以的

  • exists:如果查询的有结果就是可以的,否则就是false

自关联:

  • 表必须起别名

16.子查询

嵌套多个具有子查询的小查询。返回的中间结果存在多种。

单行单列

单行多列

多行多列

多行多列


-- =================子查询
-- 查询年龄最大的员工的信息。包含员工全部信息
-- 单行单列可以直接采用=
SELECT MAX(age) FROM emp3;
SELECT * FROM emp3 WHERE age=(SELECT MAX(age) FROM emp3);
SELECT * FROM emp3 WHERE age in (SELECT MAX(age) FROM emp3);-- 查询研发部和销售部的员工的信息
SELECT * FROM emp3 WHERE dept_id in (SELECT deptno   FROM dept WHERE name in ('研发部','销售部') );SELECT * FROM emp3  e INNER JOIN dept d on e.dept_id=d.deptno;

 下面展示的是多表查询,设置了连个子查询然后进行了表连接。

 

17.IN关键字

只要是任意一个符合就是可以得。等价于得语句就是or

select from where c=result1 or c=result2 or c=result3-- 查询研发部和销售部员工的信息
SELECT * FROM emp3 WHERE dept_id IN (SELECT deptno FROM dept3 WHERE name='研发部' or name ='销售部');

18.exists关键字

和IN关键字是差不多的

其实就是给出一个让where查询条件成立的一个表达式语句

 

select  from where exists 查询语句

  • 返回至少存在一行数据得话就是可以 得返回得是true要是不成立得话就是不成立得。

  • exists后面得子查询中不反悔任何得数据。只能返回真和假,就是给where进行成立得。

-- 下面会进行全表得输出
SELECT * FROM emp3 WHERE EXISTS (SELECT * FROM emp3) -- 查询公司大于60岁得员工
SELECT * FROM emp3 WHERE age >60;
-- 下面就是采用exists进行得操作
SELECT * FROM emp3  e WHERE EXISTS ( SELECT * FROM emp3 WHERE e.age>60);-- 查询有所属部门得员工的信息
SELECT * FROM emp3  e WHERE EXISTS (SELECT *  FROM dept3 d  WHERE e.dept_id =d.deptno);-- 查询没有所属部门得员工的信息
SELECT * FROM emp3  e WHERE not EXISTS (SELECT *  FROM dept3 d  WHERE e.dept_id =d.deptno);

exists的查询的效率是比较高得。

19.MySQL常见的函数

别人写好的模板代码。

聚合函数

数学函数

日期函数

控制流函数

窗口函数

19.1聚合函数

前面学的就是count,sum。ave和max,min

现在有一个group_

--  创建一个新的表
CREATE TABLE `emp4` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`salary` decimal(10,2) DEFAULT NULL,`dept_id` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 准备下面的测试数据
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (1, '张三', 1200.00, '人事部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (2, '李四', 1500.00, '财务部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (3, '王五', 1600.00, '财务部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (4, '赵六', 1700.00, '人事部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (5, '陈二', 1500.00, '销售部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (6, '张伞', 1600.00, '销售部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (7, '招录', 1700.00, '销售部');

将所有的员工的名字合成一行

-- 聚合操作
-- 将所有的员工的名字合成一行-- 默认的是逗号分隔符
SELECT GROUP_CONCAT(name) FROM emp4;-- 指定分隔符
SELECT GROUP_CONCAT(name SEPARATOR '-') FROM emp4;-- 指定分组的方式
SELECT dept_id, GROUP_CONCAT(name SEPARATOR '-') FROM emp4 group by dept_id;-- 指定排序的规则
SELECT dept_id, GROUP_CONCAT(name ORDER BY salary SEPARATOR '-') FROM emp4 group by dept_id;

先按照部门的名称进行分组然后再进行拼接的操作

 

下面是指定排序表的规则的操作

 

19.2数学函数

-- ==============================数学函数=========================
-- 绝对值
SELECT ABS(-10);-- 往上取整 结果是2
SELECT CEIL(1.1);-- 往下取整 结果是1
SELECT floor(1.1);-- 返回列表的最大值
SELECT GREATEST(1,2,3);-- 返回列表的最小值
SELECT least(1,2,3);-- mod 取余数
SELECT MOD(5,2)-- INDEX
SELECT POWER(5,2)-- 随机数
-- 0-1之间
SELECT RAND();-- 返回0-100之间的
SELECT RAND()*100;-- 四舍五入
SELECT ROUND(3.56);
SELECT ROUND(3.46);-- 保留小数位数
SELECT ROUND(3.46,1);-- 直接取几位不四舍五入
SELECT TRUNCATE (3.1415926,3);

19.3字符串函数

-- ===========================字符串函数=======================
-- 返回字符串字符个数
SELECT char_length('hello') ;-- 注意一个汉字是一个字符
SELECT char_length('你好啊') ;-- length根据的是字节进行的计算
SELECT length('hello') ;-- 一个汉字3个字节。采用的是utf8编码导致的
SELECT length('你好啊') ;-- 字符串合并 没有分隔符
SELECT CONCAT('你好','啊')--  字符串合并 有分隔符,第一个就是就是分隔符
SELECT CONCAT_WS('-','你好','啊')-- 返回字符串在列表中的位置 第一次出现的位置
-- 你好在后面字符中出现的位置 1
SELECT  FIELD('你好','你好','啊','张伞')
-- 位置2
SELECT  FIELD('啊','你好','啊','张伞')-- 去除左边的空格
SELECT '   你好';
SELECT LTRIM('   你好');-- 去除右边的空格
SELECT RTRIM('你好     ')-- 去除两侧的空格
SELECT trim('   你好     ')-- 从字符串s中截取
-- 从第2个字符开始,截取的长度为3。从1开始的。
-- 结果:ell
SELECT MID('helloworld',2,3)-- 判断一个字符串在另外一个字符串中出现的位置
-- 从1开始的
SELECT POSITION('wo' in 'helloworld')-- 字符串替换
-- 替换的是所有符合规则的
SELECT REPLACE('helloworld','hello' ,'你好');-- 字符串反转
SELECT REVERSE('helloworld');-- ===========================字符串函数=======================
-- 返回字符串后几个字符 llo
SELECT RIGHT('hello',3);-- 比较两个字符串的大小
-- -1表示小于,挨个字符进行比较的,按照的是字典的顺序
SELECT STRCMP('hello','hi');-- 字符串截取
-- ell从第2个字符开始截取3个字符 ell
SELECT SUBSTR('hello' ,2 ,3);
SELECT SUBSTring('hello' ,2 ,3);-- 小写变大写
SELECT ucase('hello' );
SELECT upper('hello' );-- 大写变小写SELECT lcase('HELLO' );
SELECT LOWER('HELLO' );

19.4日期相关函数

-- ====================下面是日期相关的函数=================
-- 返回毫秒值 获取时间戳 从1970年开始的
SELECT UNIX_TIMESTAMP();-- 将日期字符串转换成毫秒值
SELECT UNIX_TIMESTAMP('2023-08-18 08:47:05');-- 将毫秒值转换成指定格式的日期
-- 必须按照指定的格式
SELECT FROM_UNIXTIME(1692319625,'%Y-%m-%d %H:%i:%s')

格式化日期的时候必须按照下面的格式进行编写

 

- 获取当前的日期
-- 2023-08-18
SELECT CURDATE();
SELECT CURRENT_DATE();-- 获取当前时分秒
-- 08:51:39
SELECT CURRENT_TIME();
SELECT CURTIME();-- 获取完整的日期
-- 2023-08-18 08:52:04
SELECT CURRENT_TIMESTAMP();-- 从日期字符串中获取年月日
-- 需要符合日期的规范 2023-08-18
SELECT DATE('2023-08-18 08:52:04')-- 日期之间的差值 31
SELECT DATEDIFF('2023-08-18','2023-07-18')

下面是可以加减的日期的参数

 

-- 时间之间的插值。查了多少秒 00:01:00
SELECT TIMEDIFF('08:52:04','08:51:04');-- 日期按照指定的格式化 2023-08-18 08:52:04
-- 能够保证转换出来的日期的长度是一样的
SELECT DATE_FORMAT('2023-8-18 8:52:4','%Y-%m-%d %H:%i:%s')-- 字符串换日期 2023-08-18 08:52:04
SELECT STR_TO_DATE('2023-8-18 8:52:4','%Y-%m-%d %H:%i:%s')-- STR_TO_DATE可以把英文的时间也转换出来-- 日期进行减法 日期减去2天
SELECT DATE_SUB('2023-08-18 08:52:04',INTERVAL 2 DAY)-- 日期加法 2023-08-20 08:52:04
SELECT DATE_ADD('2023-08-18 08:52:04',INTERVAL 2 DAY)
SELECT ADDDate('2023-08-18 08:52:04',INTERVAL 2 DAY)-- 从日期中获取时间
SELECT EXTRACT(HOUR FROM '2023-08-18 08:52:04')SELECT EXTRACT(YEAR FROM '2023-08-18 08:52:04')SELECT EXTRACT(MONTH FROM '2023-08-18 08:52:04')-- 获取最后一天 2023-08-31
SELECT LAST_DAY('2023-08-18 08:52:04')-- 获取指定年的哪一天是几号
SELECT MAKEDATE('2023',8);-- 获取年
SELECT YEAR('2023-08-18 08:52:04');-- 获取月
SELECT MONTH('2023-08-18 08:52:04');-- 天
SELECT SECOND('2023-08-18 08:52:04');-- 小时
SELECT HOUR('2023-08-18 08:52:04');-- 分钟
SELECT MINUTE('2023-08-18 08:52:04');-- 秒
SELECT SECOND('2023-08-18 08:52:04');-- 获取季度 1-4
SELECT QUARTER('2023-08-18 08:52:04');-- 月的名字 August
SELECT MONTHNAME('2023-08-18 08:52:04');-- 天的名字
SELECT DAYNAME('2023-08-18 08:52:04');-- 这个月中第几天 18
SELECT DAYOFMONTH('2023-08-18 08:52:04');-- 周中第几天 6
SELECT DAYOFWeek('2023-08-18 08:52:04');-- 年中多少天 230
SELECT DAYOFYear('2023-08-18 08:52:04');-- 本年的第几个周 33
SELECT WEEK('2023-08-18 08:52:04');
-- 1
SELECT WEEK('2023-01-01 00:00:00');-- 今天是周几 4+1
SELECT WEEKDAY('2023-08-18 08:52:04');-- 本年第几个星期
SELECT WEEKOFYEAR('2023-08-18 08:52:04');-- 年份及第几周 202333
SELECT YEARWEEK('2023-08-18 08:52:04');-- 当前的时间
SELECT NOW();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/104719.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序|步骤条

步骤条是现代用户界面设计中常见的元素之一,它能够引导用户按照预定顺序完成一系列任务或步骤。在小程序中,实现步骤条可以为用户提供更好的导航和引导,使用户体验更加流畅和直观。本文将介绍如何在小程序中实现步骤条,并逐步展示实现的过程和关键技巧 目录 步骤条的作用及…

CS144 计算机网络 Lab3:TCP Sender

前言 在 Lab2 中我们实现了 TCP Receiver&#xff0c;负责在收到报文段之后将数据写入重组器中&#xff0c;并回复给发送方确认应答号。在 Lab3 中&#xff0c;我们将实现 TCP 连接的另一个端点——发送方&#xff0c;负责读取 ByteStream&#xff08;由发送方上层应用程序创建…

设计模式之详解

概念 在软件工程中&#xff0c;设计模式是指软件设计问题的推荐方案。 设计模式一般是描述如何组织代码和使用最佳实践来解决常见的设计问题。 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 好处 设计模式可以提高代码的可重用性和可读…

1.RabbitMQ介绍

一、MQ是什么&#xff1f;为什么使用它 MQ&#xff08;Message Queue&#xff0c;简称MQ&#xff09;被称为消息队列。 是一种用于在应用程序之间传递消息的通信方式。它是一种异步通信模式&#xff0c;允许不同的应用程序、服务或组件之间通过将消息放入队列中来进行通信。这…

Linux Day11---mbash项目(二)

观看本文之前请先阅读Linux Day10的相关内容 1.touch 1.1 open系统调用 int open(const char*path,int oflags,mode_t mode); oflags参数&#xff1a; O_APPEND:把写入数据追加在文件的末尾 O_TRUNC:把文件长度设置为0&#xff0c;丢弃已有的内容 O_CREAT:如果需要&#…

vue+file-saver+xlsx+htmlToPdf+jspdf实现本地导出PDF和Excel

页面效果如下&#xff08;echarts图表按需添加&#xff0c;以下代码中没有&#xff09; 1、安装插件 npm install xlsx --save npm install file-saver --save npm install html2canvas --save npm install jspdf --save2、main.js引入html2canvas import htmlToPdf from …

【java】LinkedList 和 ArrayList的简介与对比

Java LinkedList和 ArrayList 在使用上&#xff0c;几乎是一样的。由于LinkedList是基于双向链表的&#xff0c;会多出list.getFirst();获取头部元素等方法 链表&#xff08;Linked list&#xff09;是一种常见的基础数据结构&#xff0c;是一种线性表&#xff0c;但是并不会按…

JavaWeb学习-Day10

SpringBootWeb案例 准备工作 开发流程&#xff1a; 开发接口步骤&#xff1a; 删除部门&#xff1a; 新增部门&#xff1a; 简化代码&#xff1a; limit:分页展示&#xff0c;公式&#xff1a;&#xff08;页数-1&#xff09;*页面总数&#xff0c;页面总数 目前出现的问题&am…

VR全景:助力乡村振兴,实现可持续发展

引言&#xff1a; 随着科技的飞速发展&#xff0c;虚拟现实&#xff08;VR&#xff09;全景技术正在以惊人的速度改变着我们的生活方式和产业格局。全景技术不仅在娱乐、教育等领域取得了巨大成功&#xff0c;也为乡村振兴提供了全新的机遇。通过以乡村为背景的VR全景体验&…

AR室内导航技术之技术说明与效果展示

随着科技的飞速发展&#xff0c;我们周围的环境正在经历着一场数字化的革命。其中&#xff0c;AR室内导航技术以其独特的魅力&#xff0c;为我们打开了一扇通往全新数字化世界的大门。本文将为您详细介绍这一技术的实现原理、工具应用以及成品展示&#xff0c;带您领略AR室内导…

opencv-全景图像拼接

运行环境 python3.6 opencv 3.4.1.15 stitcher.py import numpy as np import cv2class Stitcher:#拼接函数def stitch(self, images, ratio0.75, reprojThresh4.0,showMatchesFalse):#获取输入图片(imageB, imageA) images#检测A、B图片的SIFT关键特征点&#xff0c;并计算…

RunnerGo中WebSocket、Dubbo、TCP/IP三种协议接口测试详解

大家好&#xff0c;RunnerGo作为一款一站式测试平台不断为用户提供更好的使用体验&#xff0c;最近得知RunnerGo新增对&#xff0c;WebSocket、Dubbo、TCP/IP&#xff0c;三种协议API的测试支持&#xff0c;本篇文章跟大家分享一下使用方法。 WebSocket协议 WebSocket 是一种…

【Linux】权限问题

Linux权限 一、Linux 权限的概念二、Linux 权限管理1. 文件访问者的分类2. 文件类型和访问权限&#xff08;事物属性&#xff09;3. 文件访问权限的相关设置方法 三、默认权限1. 对文件和目录进行操作需要的权限2. 文件和目录的默认权限3. 粘滞位 一、Linux 权限的概念 Linux …

达梦数据库物化视图介绍

概述 本文将介绍达梦数据库物化视图&#xff0c;给出其概念及相关创建、使用示例。 1.物化视图概念 物化视图 (MATERIALIZED VIEW) 是目标表在特定时间点上的一个副本&#xff0c;占用存储空间&#xff0c;即将查询出来的数据存储在数据库中。当所依赖的一个或多个基表的数据…

bh002- Blazor hybrid / Maui 使用ORM和数据库快速教程

接上篇 bh002- Blazor hybrid / Maui 保存设置快速教程 源码 10. 添加引用 Index.razor.cs 添加引用 using FreeSql.DataAnnotations; #if WINDOWS using Windows.Storage; #endif 11. 简单使用freesql ORM 初始化数据,添加数据 public partial class Index {[DisplayNam…

[oneAPI] 基于BERT预训练模型的命名体识别任务

[oneAPI] 基于BERT预训练模型的命名体识别任务 Intel DevCloud for oneAPI 和 Intel Optimization for PyTorch基于BERT预训练模型的命名体识别任务语料介绍数据集构建使用示例 命名体识别模型前向传播模型训练 结果 参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3…

Unity - 制作package 插件包

1.将制作的插件包代码放置一个根目录下 2.在跟目录下创建package.json文件 //package.json {"name": "com.unity.customlibrary", //插件包名:com.组织名.包名"displayName": "CustomLibrary", //显示的插件名"v…

OpenCV项目开发实战--基于Python/C++实现鼠标注释图像和轨迹栏来控制图像大小

鼠标指针是图形用户界面 (GUI) 中的关键组件。没有它,您就无法真正考虑与 GUI 进行交互。那么,让我们深入了解 OpenCV 中鼠标和轨迹栏的内置函数。我们将演示如何使用鼠标来注释图像,以及如何使用轨迹栏来控制图像的大小 我们将使用下图来演示 OpenCV 中鼠标指针和轨迹栏功能…

保护函数返回的利器——Linux Shadow Call Stack

写在前面 提到内核栈溢出的漏洞缓解&#xff0c;许多朋友首先想到的是栈内金丝雀&#xff08;Stack Canary&#xff09;。今天向大家介绍一项在近年&#xff0c;于Android设备中新增&#xff0c;且默默生效的安全机制——影子调用栈&#xff1a;SCS&#xff08;Shadow Call St…

Kafka单节点部署

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…