-
前言 partition by与group by都是对表中的某维度进行分组。不同的是partition by返回的是分组后的每一条记录,不改变表中数据行数,后续可以做排序、topN等操作;而 group by返回的是分组的聚合值,例如max、sum、avg等值。一、窗口函数 1.基本语法: <窗口函数> over ( partition by<用于分组的列名> order by <用于排序的列名> desc) as "rank_col" 执行顺序为: 1、根据 <用于分组的列名> 进行分组操作(partition by),得到分组结果(中间表); 2、对结果的每个分组进行组内(desc降序)排序:order by <用于排序的列名>(中间表); 3、将窗口函数用于上述结果的每个分组(over):增加组内排序序号列"rank_col"。窗口函数包括rank(),dense_rank(),row_number()等。 以上过程生成了一个分组、组内排序、增加组内排序序号列的结果。 rank()函数:如果有并列名次的行,会占用下一个名次的位置。比如正常排名是1,2,3,4,但是现在前3名是并列的名次,所以结果是:1,1,1,4. dense_rank()函数:如果有并列的名次,它不会占用下一个名次的位置,比如比如正常排名是1,2,3,4,但是现在前3名是并列的名次,所以结果是:1,1,1,2. row_number()函数:不考虑并列的情况,比如前3名是并列的名次,排名是正常的1,2,3,4. 2.示例 [LC185]. 部门工资前三高的所有员工 公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。编写解决方案,找出每个部门中 收入高的员工 。 输出格式要求如下: 分析: 题目要求是找出 每个部门中 排名前三的员工(partition by 部门),且相同收入水平并列、不占用后续排序位置(dense_rank())。 写sql前,最好把过程先想清楚,把每个中间子表想清楚,把重要的中间子表可以查出来看看,最后再完善代码,且不要上来就搞代码。思路如下: 1、先把最核心的计算写出来 分组以及组内排序: select *, dense_rank() over(partition by departmentId order by salary desc) as rank_col from Employee 按分组排序输出了,且增加了排序列rank_col,但是没有限制前三。 2、从上面的结果中,取每组的前三 把上面的结果当作子表查询 select * from( select *, dense_rank() over(partition by departmentId order by salary desc) as rank_col from Employee ) a where a.rank_col <=3 到这里,核心的计算算是完成了,实现了 每个部门中排名前三,且相同收入水平并列、不占用后续排序位置的要求。下一步,要按照规定格式输出。 3、按要求格式输出 继续把上面的结果当作子表查询 select d.name Department, b.name Employee,b.salary Salary from (select * from( select *, dense_rank() over(partition by departmentId order by salary desc) as rank_col from Employee ) a where a.rank_col <=3) b left join Department d on b.departmentId = d.id 输出正确,测试通过。 4、sql优化 分组以及组内排序后,直接join,节省一个中间子表 select d.name Department, a.name Employee,a.salary Salary from (select *, dense_rank() over(partition by departmentId order by salary desc) as "rank" from Employee ) a left join Department d on a.departmentId = d.id where a.rank <4 输出正确,测试通过。 ———————————————— 原文链接:https://blog.csdn.net/weixin_43962853/article/details/136317759
-
MySQL 是一个开放源码的小型关联式数据库管理系统,开发者为瑞典 MySQL AB 公司。目前 MySQL 被广泛地应用在 Internet 上的中小型网站中。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了 MySQL 作为网站数据库。MySQL 的特性有使用 C 和 C++ 编写,并使用了多种编译器进行测试,保证源代码的可移植性。支持 AIX、BSDi、FreeBSD、HP-UX、Linux、Mac OS、Novell Netware、NetBSD、OpenBSD、OS/2 Wrap、Solaris、SunOS、Windows 等多种操作系统。为多种编程语言提供了 API。这些编程语言包括 C、C++、C#、Delphi、Eiffel、Java、Perl、PHP、Python、Ruby 和 Tcl 等。支持多线程,充分利用 CPU 资源,支持多用户。优化的 SQL 查询算法,有效地提高查询速度。既能够作为一个单独的应用程序应用在客户端服务器网络环境中,也能够作为一个库而嵌入到其他的软件中。提供多语言支持,常见的编码如中文的 GB 2312、BIG5,日文的 Shift_JIS 等都可以用作数据表名和数据列名。提供 TCP/IP、ODBC 和 JDBC 等多种数据库连接途径。提供用于管理、检查、优化数据库操作的管理工具。可以处理拥有上千万条记录的大型数据库。GROUP BY 子句通常用于聚合函数(例如 SUM,COUNT,AVG 等)的计算,以便将多行数据组合成单个行,并根据聚合结果对数据进行分组。它可以将结果分为不同的组,其中每个组包含具有相同值的一组行,并且可以根据一项或多项列来指定分组。例如: SELECT country, city, COUNT(*) as count FROM customers GROUP BY country, city 以上 SQL 查询将在 customers 表中将客户按照所在国家和城市进行分组,并计算每个组中客户的数量。 PARTITION BY 子句用于对结果数据集进行分区(分组),然后使用聚合函数(例如 SUM,COUNT,AVG 等)来计算每个分区内的值。与 GROUP BY 不同的是,PARTITION BY 不是仅用于聚合结果的分组策略,而是仅分区未聚合的结果集。这个关键字通常与窗口函数一起使用,对每个分区执行排名、排序和聚合等操作。例如: SELECT *, SUM(quantity) OVER (PARTITION BY order_date) as total_quantity FROM orders 以上 SQL 查询将在 orders 表中,将订单按照订单日期进行分区,并计算结果中每个分区的 quantity 列的总和,并将结果添加到每一行。 因此,PARTITION BY 和 GROUP BY 都将数据集分成多个分组,然而,它们的主要区别是 GROUP BY 定义了聚合条件,而 PARTITION BY 是仅用于分组结果集并对每个分区执行排名、排序和聚合等分析函数。 ———————————————— 原文链接:https://blog.csdn.net/gly1653810310/article/details/134185783
-
聚合函数sum在窗口函数中,对自身记录以及位于自身以上的数据进行求和,如课程号0002对应的学号0002后面的sum结果就是课程号0002中学号为0001和0002对应的成绩之和,课程号0002对应的学号0003后面的sum结果就是课程号0002中学号0001、0002和0003对应的成绩之和。以上窗口函数,用了rows和preceding这两个关键字,是“之前~行“的意思,在上面也就是之本篇文章主要是以下内容:1.窗口函数:partition by窗口函数 和 group by分组的区别:partition by关键字是分析性函数的一部分,它和聚合函数(如group by)不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录。partition by用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组。partition by与group by不同之处在于前者返回的是分组里的每一条数据,并且可以对分组数据进行排序操作。后者只能返回聚合之后的组的数据统计值的记录。partition by相比较于group by,能够在保留全部数据的基础上,只对其中某些字段做分组排序(类似excel中的操作),而group by则只保留参与分组的字段和聚合函数的结果分区函数Partition By的用法_partitionby_惊寂123的博客-CSDN博客1)窗口函数的基本语法如下:<窗口函数> over ( partition by<用于分组的列名> order by <用于排序的列名>)2)以上语法中<窗口函数>的位置,可以放置以下函数:窗口函数是对where或者group by子句处理后的结果进行处理,所以窗口函数原则上只能写上select子句中。2.如何使用窗口函数?1)专用窗口函数rank。若要在每个班级内按成绩排名,则sql语句则为:select *, rank() over (partition by 班级 order by 成绩 desc) as ranking from 班级表;以上sql语句中的select子句,rank是排序的函数,要求是“每个班级内按成绩排名”。这句话分为两部分理解:a)每个班级内:按班级分组partition by用来对表分组,在这个例子中,需要按“班级”进行分组(partition by 班级)b)按成绩排名:order by子句的功能是对分组后的结果进行排序,默认按升序排列,但是在本例中用了desc,表示按降序排序。2)窗口函数已经具备了前几节中group by和order by子句的分组和排序的功能,但仍要用窗口函数是因为,group by分组汇总后改变了表的行数,一行只有一个类别,而partition by和rank函数不会减少原表中的行数。-- group by分组汇总改变行数 select 班级,count(学号) from 班级表 group by 班级 order by 班级;-- partition by分组汇总行数不变 select 学号, count(学号) over (partition by 班级 order by 班级) as current_count from 班级表;“窗口函数”之所以叫“窗口”函数,是因为partition by分组后的结果就称为“窗口”,这里的窗口是表示“范围”的意思。3)窗口函数主要有以下功能:a.同时具备分组和排序的功能b.不减少原表的行数c.语法如下:<窗口函数> over ( partition by<用于分组的列名> order by <用于排序的列名>)3.其他专用窗口函数1)专用窗口函数rank,dense_rank,row_number有什么区别?-- 专用窗口函数rank,dense_rank(),row_number的区别 select *, rank() over (order by 成绩 desc) as ranking, dense_rank() over (order by 成绩 desc) as dese_rank, row_number() over (order by 成绩 desc) as row_num from 班级表;从以上结果来看:rank()函数:这个例子中是5位,5位,5位,8位,也就是如果有并列名次的行,会占用下一个名次的位置。比如正常排名是1,2,3,4,但是现在前3名是并列的名次,所以结果是:1,1,1,4.dense_rank()函数:这个例子中是5位,5位,5位,6位,也就是如果有并列的名次,它不会占用下一个名次的位置,比如比如正常排名是1,2,3,4,但是现在前3名是并列的名次,所以结果是:1,1,1,2.row_number()函数:这个例子中是5位,6位,7位,8位,也就是不考虑并列的情况,比如前3名是并列的名次,排名是正常的1,2,3,4.最后需要注意的是,以上三个专用窗口函数,函数后面的括号不需要任何参数,保持括号()为空即可。案例1:面试经典排名问题当涉及到排名问题时,可以使用窗口函数,但使用窗口函数前,要注意区份rank()函数、dense_rank()函数以及row_number()函数的区别。例子:编写一个sql查询来实现分数排名,若两个分数相同,则分数排名相同。请注意:平分后下一个名字应该是下一个连续的整数值,换句话说就是,名次之间不该有“间隔”。因此考虑用dense_rank()函数。sql查询语句应为:select *, dense_rank() over (order by 成绩 desc) as dens_rank from 班级表;案例2:面试经典topN问题工作中常会遇到这样的业务问题:找出每个国家中进口最多的产品是哪个?找出每个国家进口贸易前5的商品是什么?诸如此类问题,都是常见的:分组取每组最大值,最小值,每组最大的N条(top N)记录。面对这类问题,我们将通过以下例子给出答案?成绩表里包含了学生的学号,课程号(学生选修课程的课程号),成绩(学生选修该课程取得的成绩).1)分组取每组最大值:按课程号分组取成绩最大值所在行的数据。(由于分组group by和汇总函数得到的是每组的一个值(最大值,最小值或平均值),而无法得到对应那一行的所有数据,所以group by不可用)。因此我们可以使用关联子查询来实现:select * from score as a where 成绩=(select max(成绩) from score as b where a.课程号=b.课程号);以上查询结果中课程号0001有2行数据是因为最大成绩80有2个。2)分组取每组最小值:按课程号分组取成绩最小值所在行的数据。select * from score as a where 成绩=(select min(成绩) from score as b where a.课程号=b.课程号);3)每组最大的N条记录:案例:现有“进口贸易表”,记录了每个国家各商品的进口额,表内容如下。问题:查找每个国家进口额最大的2个商品。解题思路:1.看到问题中要查找“每个”国家进口额最高的商品。当题目中出现“每个”时,首先要想到分组。这里指每个国家,所以要按国家来分组。2.当表按国家分组后,按进口额降序排列,排在最前面2个就是我们想要查找的进口额最大的2个商品。3.分组排序后,不能减少原表的行数,所以要用窗口函数。4.对比各窗口函数,为不受并列进口额的影响,于是决定用row_number。解题步骤:步骤一:按国家分组(partition by 国家)、并按进口额降序排列(order by 进口额 desc),套入窗口函数后,sql语句为:select *, row_number() over (partition by 国家 order by 进口额 desc) as ranking from 进口贸易表;步骤二:上表中红色框框内的数据,就是每个国家进口额最大的两个商品,也就是题目的解。要想得到只有这些解的答案,只需要提取出“ranking“值小于等于2的数据即可。这时候只需要在之前的sql语句中加入条件子句where就可以了。但是这样就会报错,原因是sql的书写顺序和运行顺序不一致,在运行过程中,select语句是最后运行的。因此不能将sql语句写成如下:select *, row_number() over (partition by 国家 order by 进口额 desc) as ranking from 进口贸易表 where rangking<=2;以上出错原因就是因为我们以为运行顺序是按书写顺序来运行的,这样是不对的,所以运行sql子句的时候,就会出错。运行where ranking的时候,select子句还没有运行,ranking列还未出现。步骤三:这时候只能采用子查询,将第一步得到的查询结果作为一个新表,最后再运行where子句。select * from (select *, row_number() over (partition by 国家 order by 进口额 desc) as ranking from 进口贸易表) as a where rangking<=2;举一反三:经典topN问题:每组最大的N条记录。这类问题既涉及分组,又涉及排序,这时候要用窗口函数来实现,这时候只需要将where子句中的2改成N即可。select * from (select *, row_number() over (partition by 要分组的列名 order by 要排序的列名 desc) as ranking from 表名) as a where rangking<=N;4.聚合函数作为窗口函数聚合函数作为窗口函数和专用窗口函数用法相同,只需要把聚合函数写在窗口函数的位置即可,但聚合函数括号里不能为空,必须写好聚合的列名。select *, sum(成绩) over ( partition by 课程号 order by 学号) as current_sum, avg(成绩) over (partition by 课程号 order by 学号) as current_avg, max(成绩) over (partition by 课程号 order by 学号) as current_max, min(成绩) over (partition by 课程号 order by 学号) as current_min, count(成绩) over (partition by 课程号 order by 学号) as current_count from score;聚合函数sum在窗口函数中,对自身记录以及位于自身以上的数据进行求和,如课程号0002对应的学号0002后面的sum结果就是课程号0002中学号为0001和0002对应的成绩之和,课程号0002对应的学号0003后面的sum结果就是课程号0002中学号0001、0002和0003对应的成绩之和。除此之外,avg()、max()、min()等聚合函数作为窗口函数时,结果都与sum()函数类似。这样使用窗口函数的用处是:聚合函数作为窗口函数,可以在每一行的数据里直观看到,截止到本行数据,统计数据有多少,最大值、最小值是多少等,从而可以看出每一行数据,对整体数据的影响。举例:累计求和问题下表为确诊人数表,包含日期和该日期对应的新增确诊人数,按照日期进行升序排列,查找日期,确诊人数以及对应的累计确诊人数。select 日期,确诊人数, sum(确诊人数) over(order by 日期) as 累计确诊人数 from 确诊人数表;案例:如何在每个组里比较题目:现有进口贸易表,记录了每个国家各商品的进口额,表内容如下:问题:查找单个商品进口额高于该商品平均进口额的国家名单。解题思路:1.查找单个商品高于该商品平均进口额,也就是要在每个商品里比较,这就涉及到分组,而sql中有分组功能的就:group by和窗口函数partition by。2.使用聚合函数avg()求出每个商品的平均进口额后,找出进口额大于平均进口额的数据。并且要求分组后不减少原表的行数。3.由于group by分组汇总后会改变表的行数,一行只有一个类别,而partition by不会减少原表行数,因此用partition by。解题步骤:1.将avg()作为窗口函数,将每个商品的平均进口额求出。select *, avg(进口额) over (partition by 商品编码 ) as 平均进口额 from 进口贸易表;2.在第1步的基础上,筛选出大于平均进口额的数据即可。这时,就需要在上一步的sql语句中加入条件子句where即可。在写sql子句前,要注意sql的书写顺序与运行顺序。select * from (select *, avg(进口额) over (partition by 商品编码 ) as 平均进口额 from 进口贸易表) as b where 进口额>平均进口额;举一反三:查找每个组里大于平均值的数据,可以有两种方法:1)使用以上的窗口函数2)使用关联子查询。5、窗口函数的移动平均select *, avg(成绩) over (order by 学号 rows 2 preceding) as current_avg from score;以上窗口函数,用了rows和preceding这两个关键字,是“之前~行“的意思,在上面也就是之前2行的意思,也就是得到的结果是自身记录及前2行的平均。例如学号0002、课程号0002成绩60的结果为:学号0001课程号0002和学号0001课程号0003以及学号0002、课程号0002对应的三个成绩的平均值。也就是学号0002课程号0002这位以及其前两行同学的平均成绩。想要计算当前行与前n行(共n+1行)的平均时,只有调整rows 与preceding中间的数字即可。这样使用窗口函数注意是可以通过preceding关键字调整作用范围,在以下的场景中非常适用:在公司业绩名单排名中,可以通过移动平均,直观地查看与相邻名次业绩的平均、求和等统计数据。6.窗口函数总结1)注意事项:partition 子句可以省略,省略时就是不指定分组,且窗口函数原则上只能写在select子句中2)窗口函数语法:select * <窗口函数> over (partition by <分组的列名> order by <排序的列名>) as <自己定义的列名> from 从哪张表中查找;其中窗口函数的位置可以放:a.专用窗口函数:rank()、dense_rank()、row_number等。b.聚合函数:sum()、avg()、max()、min()等。3)窗口函数的功能:a.同时具备分组partition by和排序order by的功能。b.不减少原表的行数,所以经常用来在每组内排名。4)窗口函数使用场景:7、触发器触发器概念:触发器是一种特殊的存储过程,它在试图更改触发器所保护的数据时自动执行。触发器与存储过程的异同相同点:1. 触发器是一种特殊的存储过程,触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段。不同点:2. 存储器调用时需要调用SQL片段,而触发器不需要调用,当对数据库表中的数据执行DML操作时自动触发这个SQL片段的执行,无需手动调用。MySQL的触发器_mysql触发器_莱维贝贝、的博客-CSDN博客8.存储过程。MySQL中的存储过程(详细篇)_mysql存储过程学习_普通网友的博客-CSDN博客(学习该博客)1)在工作中经常遇到重复性的工作,这时候就可以把常用的sql写好存储起来,这个过程就是存储过程。这样下次遇到同样的问题,就可以直接使用存储过程了,这样就可以极大地提高工作效率。2)如何使用存储过程?使用存储过程需要先定义存储过程,然后是使用已经定义好的存储过程。a.无参数的存储过程。定义存储过程的语法形式:create procedure 存储过程名称() begin <sql语句> ;end;语法中的begin……end用于表示sql语句的开始和结束。语法中的sql语句就是重复的sql语句。举个例子:查找进口贸易表中的国家名称。sql语句就是:select 国家from 进口贸易表;把这个sql语句放入存储过程的语法里,并给这个存储过程起名叫a_trade1:create procedure a_trade1 () begin select 国家from 进口贸易表;end;在navicat-查询中运行后,建立的存储过程就会出现在以上位置,这样下次就可以用以下的sql语句直接使用了,就不用另外再写一次sql语句了。call 存储过程名();如:call a_trade1 ();b.有参数的存储过程:a.中的存储过程名称后是(),括号里没有参数,当括号有参数时,就是以下的语法:create procedure 存储过程名称(参数1,参数2,…) begin <sql语句>;end;例如:要在进口贸易表中查找指定商品编码的国家有哪些?如果指定商品编码为88,那么sql语句是:select 国家 from 进口贸易表 where 商品编码=88;在实际工作中,有时候并不能一次就能指定国家是哪个,有时候业务需要指定国家为中国,有时候需要指定成美国,这个时候就需要参数,来灵活应对这种情况。这时候把sql放入存储过程就是:create procedure getNum2(num varchar(100)) begin select 国家 from 进口贸易表 where 商品编码=num;end;其中getNum2是存储过程的名称,后面括号里面的num varchar(100)是参数,参数由两部分组成,参数名称是num;参数类型是varchar(100);这里表示字符串类型。存储过程里面的sql语句(where 商品编码=num)使用了这个参数num,这样在使用存储过程时,给定参数值就可以灵活地运用了。比如现在要查商品编码是89的国家名称,那么就可以在使用存储过程的参数来实现了,也就是下面括号里的89.call getNum2(89);c.默认参数的存储过程*前面的存储过程名称后是(参数1,参数2,…),括号里面只包含了参数的类型和名称,方便调用。其实存储过程还包含了一种情况,就是存在默认参数的情况。in输入参数:参数初始值在存储过程前被指定为默认值,在存储过程中修改该参数的值不能被返回。set @num=0;-- 初始化参数 -- 初始化存储过程 create procedure in1(in num int) begin select num; set num=1; select num; end; -- in参数调用 call in1(@num); select num;out输出参数:参数初始值为空,该值可在存储过程内部被改变,并可返回。set @num=0;-- 初始化参数 -- 初始化存储过程 create procedure out1(out num int) begin select num; set num=1; select num; end; -- out参数调用 call out1(@num); select num;inout输入输出参数:参数初始值在存储过程前被指定为默认值,并且可在存储过程中被改变和在调用完毕后可被返回。set @num=0;-- 初始化参数 -- 初始化存储过程 create procedure inout1(inout num int) begin select num; set num=1; select num; end; -- inout参数调用 call inout1(@num); select num;3)注意事项a.定义存储过程语法里的sql语句代码块必须是完整的sql语句,必须用分号;结尾。create procedure 存储过程名称(参数1,参数2,…) begin <sql语句>;end;复制b.定义不同的存储过程,要用不同的存储过程名称,相同的存储过程名字会引起系统报错。原文链接:https://gitcode.csdn.net/66262c24ff62be264bf046fe.html
-
MySQL是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的RDBMS (Relational Database Management System,关系数据库管理系统)应用软件之一。 MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。 MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL作为网站数据库。与其他的大型数据库例如 Oracle、DB2、SQL Server等相比,MySQL [1] 自有它的不足之处,但是这丝毫也没有减少它受欢迎的程度。对于一般的个人使用者和中小型企业来说,MySQL提供的功能已经绰绰有余,而且由于 MySQL是开放源码软件,因此可以大大降低总体拥有成本。group by是分组函数,partition by是分区函数(像sum()等是聚合函数),注意区分。 1、over函数的写法: over(partition by cno order by degree ) 先对cno 中相同的进行分区,在cno 中相同的情况下对degree 进行排序 2、分区函数Partition By与rank()的用法“对比”分区函数Partition By与row_number()的用法 例:查询每名课程的第一名的成绩 (1)使用rank() SELECT * FROM (select sno,cno,degree, rank()over(partition by cno order by degree desc) mm from score) where mm = 1; 得到结果: (2)使用row_number() SELECT * FROM (select sno,cno,degree, row_number()over(partition by cno order by degree desc) mm from score) where mm = 1; 得到结果: (3)rank()与row_number()的区别 由以上的例子得出,在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果。 2、分区函数Partition By与rank()的用法“对比”分区函数Partition By与dense_rank()的用法 例:查询课程号为‘3-245’的成绩与排名 (1) 使用rank() SELECT * FROM (select sno,cno,degree, rank()over(partition by cno order by degree desc) mm from score) where cno = '3-245' 得到结果: (2) 使用dense_rank() SELECT * FROM (select sno,cno,degree, dense_rank()over(partition by cno order by degree desc) mm from score) where cno = '3-245' 得到结果: (3)rank()与dense_rank()的区别 由以上的例子得出,rank()和dense_rank()都可以将并列第一名的都查找出来;但rank()是跳跃排序,有两个第一名时接下来是第三名;而dense_rank()是非跳跃排序,有两个第一名时接下来是第二名。 ———————————————— 原文链接:https://blog.csdn.net/weixin_44547599/article/details/88764558
-
简介很多时候,我们都使用group by 进行分组,count(*)进行统计,两者结合可以进行聚合统计。假设我们有这样一张煤矿数据库表table name: coalmine columns: id(煤矿ID, bigint), prod_status(生产状态,varchar), prod_capacity(产能,decimal)需求:统计各生产状态的煤矿数量学过SQL的人一眼就看出来,这是一个非常基础的问题。我们只需要按照prod_status进行分组进行聚合统计即可。大致可以写如下的sql:select prod_status as name, count(*) as num from coalmine group by name;可以得到如下的输出:name | num 停产 377 停建 360 关闭 31 准备 1 在建 89 正在复产 3 生产 463 生产/在建 15 生产/试运转 12 试运转 1非常完美,我们得到了我们想要的数据。但是现在有了新的需求:统计产能在30以下,30~90,90以上的煤矿数量有多少。现在我们遇到了难题,因为产能字段(prod_capacity)是一个数值,同时统计的依据是一个区间,我们不能单纯的将其作为group by的对象进行操作。select prod_capacity as name, count(*) as num from coalmine group by name;这样做的结果,只是按数值进行分组统计。那么,该怎么办呢?区间统计(解法一)有点基础的读者不难看出,我们可以使用mysql关键字 sum 以及 if 进行操作,大致可以写出如下的SQL。select sum(if(c.prod_capacity is null or c.prod_capacity < 30, 1, 0)) as less30, sum(if(c.prod_capacity >= 30 and c.prod_capacity <= 90, 1, 0)) as between39, sum(if(c.prod_capacity > 90, 1 , 0)) as gather90 from coalmine c inner join enterprise e on c.enterprise_id = e.id;c.prod_capacity is null 可以认为prod_capacity字段为空时,认为煤矿的产能低于30.sum 以及 if 的使用方法可参阅网上教程。执行完毕后,我们可以得到如下的结果:less30 | between39 | than90 1033 330 25看起来似乎很美好,只不过没有使用分组排序稍有欠缺,导致最终结果是以一行的方式呈现,这回导致我们在应用程序里面进行实体映射(例如mybatis)时,只能使用扁平结构进行对应(例如Map),这和统一的分组映射实体出现矛盾。当然对于解决问题的结果来说这是无伤大雅的,最终我们还会讲最完美的解法,在此之前,我们先看另一种解决方案。区间统计(解法二)mysql有众多函数可以帮助我们完成各种各样的任务,只要我们仔细研究,很多冗余的SQL可以简化的漂亮,关于区间统计,其实还有专门的处理函数,他们分别是 interval 以及 ele。我们来看看他们的用法:INTERVAL(N,N1,N2,N3,...) INTERVAL()函数进行比较列表(N1,N2,N3等等)中的N值。该函数如果N<N1返回0,如果N<N2返回1,如果N<N3返回2 等等。如果N为NULL,它将返回-1。列表值必须是N1<N2<N3的形式才能正常工作。 ELT(N,str1,str2,str3,...) 如果N= 1,返回str1,如果N= 2,返回str2,等等。如果N小于1或大于参数个数,返回NULL。ELT()是FIELD()反运算。基于此,我们可以写出更漂亮的SQLselect elt(interval(c.prod_capacity,0,30,90, 100000), 'less30', 'between39', 'than90') as name, count(*) from coalmine c group by name;但显然,查询的结果受限非常之大,interval是半区间方式,(即大于等于前者小于后者),这样会导致运用场景非常之有限。当然可以通过其他方式进行优化,但是已经如使用sum、if方式来得方便灵活。但前者也有问题,就是查询的结果并不是多条记录展示,这样在很多业务系统中,进行bean映射的时候,只能采取hashmap方式进行结果映射。显然其原理还是分组统计,我们希望结果是以多行的形式展示。那么,该如何办到呢?区间统计(解法三)可以看到,既然分组的逻辑是一种if else形式的,我们可不可以在mysql里找到这种逻辑的关键字呢?显然是有的,那便是 case语句。以下是其官方文档:Syntax: CASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN result ...] [ELSE result] END 或者 CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END金风玉露一相逢,这便是我们要的东西,仔细琢磨一番,可以写出如下的SQLselect case when c.prod_capacity is null or c.prod_capacity < 30 then 'less30' when c.prod_capacity >= 30 and c.prod_capacity <=90 then 'less39' when c.prod_capacity > 90 then 'than90' end as name, count(*) as num from coalmine c group by name;返回结果如下所示:name | num less30 1033 less39 330 than90 25结语可以看到,使用case关键字不仅得到了我们想要的结果形式,同时他提供了更灵活的处理逻辑,不论是区间分组亦或是其他的非正常方式,我们都可以定义自己的处理逻辑,将业务上需要归为一组的数据输出(then)为同样的值,然后进行分组。当然,也许还有更完美的解决方案,不知君是否有所考虑呢?欢迎讨论。原文链接:https://zhuanlan.zhihu.com/p/163452689
-
【问题来源】深圳容大【问题简要】一通通话,经过座席的转换/咨询/会议后,几条记录可以通过callid关联吗【问题类别】CC-DIS【AICC解决方案版本】22.100[问题描述]您好,我通过座席A拨打座席B,再由座席B咨询转换给座席C,座席C接听后挂断,A座席工号:107,B座席工号:110,C座席:20213,测试时间点:拨打电话:2024-04-15 16:09:32,转接时间点:2024-04-15 16:10:58。tcurrentbilllog表共有9条数据(见附件话单原数据),好像单凭callid字段不能判断出它们之间是属于一通通话,有没有什么方式可以把这几条数据关联起来?agentgateway-rest.log日志在附件中。
-
如果把查询看作是一个任务,那么它由一些列子任务组成,每个子任务都会消耗一定的时间。如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数。通常来说,查询的生命周期大致可以按照顺序来看:从客户端到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端。其中“执行”可以认为是整个生命周期中最重要的阶段,其中包括大量为了检索数据到存储引擎的调用以及调用后的数据处理,包括排序、分组等。上述操作会在网络、CPU计算、生成统计信息和执行计划、锁等待(互斥等待)等操作上花费时间,尤其是向底层存储引擎检索数据的调用操作。根据存储引擎的不同,可能还会产生大量的上下文切换以及系统调用。 一、是否请求了不需要的数据 查询性能低下最基本的原因是访问的数据太多。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化。对于低效查询可以通过如下两个步骤来分析总是有效: 【1】确定应用程序是否在检索大量超过需要的数据。意味着访问了太多的行或者太多的列。 【2】确定 MySQL 服务器是否在分析大量超过需要的数据行。 有些查询会请求超过实际需要的数据,然后这些多余的数据会被应用程序丢弃。这会给 MySQL 服务器带来额外的负担,并增加网络开销【应用服务器和数据库不再同一台服务器上】另外也会消耗应用服务器的 CPU和内存资源。通常企业不允许使用 SELECT * 语句进行查询。 二、是否扫描了额外的记录 在确定查询只返回需要的数据以后,接下来应该查看查询是否扫描了过多的数据。对于 MySQL,最简单的衡量查询开销的三个指标是响应时间、扫描的行数、返回的行数:这三个指标都会记录到慢日志【SHOW VARIABLES LIKE “%slow%”;】中。 【1】响应时间: 服务时间和排队时间之和,服务时间是指数据库处理这个查询真正花费的时间。排队时间是指服务器因为等待某些资源而没有真正执行查询的时间(等待I/O操作或锁,等等)。遗憾的是无法将响应时间细分到上面这些部分。 【2】扫描的行数和返回的行数: 分析查询时,查看该查询扫描的行数是非常有帮助的。但并不是所有的行的访问代价都是相同的。较短的行访问速度快,内存中的行也比磁盘中的行的访问速度要快很多。理想情况下扫描的行数和返回的行数应该是相同的。但这种情况并不多。例如在做一个关联查询时,服务器必须要扫描多行才能生成结果集中的一行。扫描的行数对返回的行数的比率通常很小,以便在1:1和10:1之间,不过有时候这个值也可能非常非常大。 【3】扫描的行数和访问类型: 在评估查询开销的时候,需要考虑一下从表中找到某一行数据的成本。MySQL 有好几种查询方式可以查找并返回一行结果。有些访问方式可能需要扫描多行才能返回一行结果,也有些访问方式可能无需扫描就能返回结果。在EXPLAN 语句中的 type 列反映了访问类型。从全表扫描、索引扫描、范围扫描、唯一索引查询、常数引用等。速度从慢到快,扫描的行数也是从多到少。如果查询没有办法找到合适的访问类型,那么解决的最好办法就是添加一个合适的索引。索引让 MySQL 以最高效、扫描行数最少的方式找到需要的记录。 【4】如果发现查询需要扫描大量的数据但只返回少数行: 通常可以使用如下技巧去优化它:①、使用索引覆盖扫描,把所有需要的列都放到索引中,这样存储引擎无需回表获取对应行就可以返回结果了。②、改变表结构。例如使用单独的汇总表。③、重写这个复杂的查询,让 MySQL 优化器能够以更优化的方式执行这个查询。 三、一个复杂查询 OR 多个简单查询 有时候,可以将查询转换一种写法让其返回一样的结果,但是性能更好。但也可以通过修改应用代码,用另一种方式完成查询,达到最后的目的。 设计查询的时候需要考虑一个重要问题,是否需要将一个复杂的查询分成多个简单的查询。在传统的实现中,总是强调需要数据库层完成尽可能多的工作,这样做逻辑在于以前总是认为网络通信、查询解析和优化是一件代价很高的事情。对于MySQL 并不适用,MySQL 从设计上让连接和断开连接都是轻量级, 在返回一个小的查询结果很高效。现在的网络速度比以前也快很多,无论是宽带还是延迟。即使一个通用的服务器上,也能够运行每秒超过10万的查询。 四、切分查询 有时候对于一个大查询我们需要 “分而治之” 将大查询切分成小查询,每个查询功能完全一样,只是完成一小部分,每次只返回一小部分查询结果。删除旧的数据就是一个很好的例子。定期地清除大量数据时,如果用一个大的语句一次性完成的话,则可能需要一次性锁住很多数据、占满整个事务日志,耗尽系统资源、阻塞很多小的但重要的查询。将一个大的DELETE 切分成多个较小的查询可以尽可能小地影响 MySQL 性能,同时还可以减少 MySQL 的复制延迟。一秒删除一万行数据一般来说是一个比较高效而且对服务器影响也比较小的做法。如果每次删除数据后,都暂停一会儿再做下一次删除,这样也可以将服务器上原本一次性的压力分散到一个很长的时间段中,就可以大大降低对服务器的影响,还可以大大降低删除时锁的持有时间。 五、分解关联查询 很多高性能的应用都会对关联查询进行分解。可以对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。如下: SELECT * FROM teacher t JOIN student s ON t.id = s.t_id JOIN class c ON t.id = c.t_id WHERE t.name='Li'; --拆分后 SELECT * FROM teacher t WHERE t.name='Li'; SELECT * FROM student s WHERE s.id = 12; SELECT * FROM class c WHERE c.id IN (13,45,65); 1 2 3 4 5 6 7 8 用分解关联查询的方式重构查询有如下的优势: 【1】让缓存的效果更高,许多应用程序可以方便地缓存单表查询对应的结果对象。例如,上面的 teacher 已经被缓存了,那么应用就跳过了第一个查询,再例如,应用程序中已经缓存了 ID 为 12、45 的内容,那么第三个查询的 IN() 中就可以少几个 ID。另外,对于MySQL 的查询缓存来说,如果关联中某个表发生了变化,那么就无法使用查询缓存了,而拆分后,如果某个表很少改变,那么基于该表的查询就可以重复利用查询缓存结果了。 【2】将查询分解后,执行单个查询就可以减少锁的竞争。 【3】在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。 【4】查询本身效率也可能有所提升。这个例子中,使用 IN() 代替关联查询,可以让 MySQL 按照ID 顺序进行查询,这可能比随机的关联要更高效。 【5】可以减少冗余记录的查询。在应用层做关联查询,意味着对于某条记录应用只需要查询一次,而在数据库中做关联查询,则可能需要重复地访问一部分数据。这样的重构还可能会减少网络和内存的消耗。 【6】这样做相当于在应用中实现了哈希关联,而不是使用 MySQL 的嵌套循环关联。某些场景哈希关联效率要高很多。 六、UNION 的限制 MySQL 无法将外层限制条件延续到内层,这使得原本可以返回部分结果的条件无法应用到内部查询的优化上。如果希望 UNION 的各个子句根据 LIMIT 只取部分结果集,或者希望能够先排好序再合并结果集的话,就需要在 UNION 的各个子句中分别使用这些子句。例如,想将两个子查询结果联合起来,然后再取前20条记录,那么MySQL 会将两个表都存放到同一个临时表中,然后再取出前20行记录: --UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL (SELECT first_name,last_name FROM people_A ORDER BY last_name) UNION ALL (SELECT first_name,last_name FROM people_B ORDER BY last_name) LIMIT 20; 1 2 3 4 5 这条查询将会把 people_A 中的所有记录和 people_B 的所有记录放在一个临时表中,然后再从临时表中取出前20条。可以通过在 UNION 的两个子查询中分别加上一个 LIMIT 20来减少临时表中的数据: (SELECT first_name,last_name FROM people_A ORDER BY last_name LIMIT 20) UNION ALL (SELECT first_name,last_name FROM people_B ORDER BY last_name LIMIT 20) LIMIT 20; 1 2 3 4 现在中间的临时表只会包含40条记录,除了性能考虑之外,在这里还需要注意一点,从临时表中取出数据的顺序并不是一定的,所以如果想获得正确的顺序,还需要加上一个全局的 ORDER BY 和 LIMIT 操作。 MySQL 总是通过创建并填充临时表的方式来执行 UNION 查询。除非确定需要服务器消除重复的行,否则就一定要使用 UNION ALL,如果没有 ALL 关键字,MySQL 会给临时表加上 DISTINCT 选项,这会导致给整个临时表做唯一性检查。代价非常高。就是有 ALL 关键字,MySQL 仍然会使用临时表存储结果。事实上,MySQL 总是把结果放入临时表,然后再读出来,再返回给客户端。 七、优化 COUNT() 查询 COUNT() 可以统计某个列值的数量,也可以统计行数。在统计列值时要求列值是非空的(不统计NULL)。如果在COUNT() 的括号中制定了列或者表达式,则统计的就是这个表达式有值的结果数。COUNT()的另一个作用是统计行数,当MySQL确认括号内的表达式值不可能为空的时候,实际上就是在统计行数。最简单的就是当我们使用 COUNT(*) 的时候,这种情况它会忽略所有的列直接统计所有的行数。 MyISAM 的 COUNT() 函数总是非常快,前提是没有任何 WHERE 条件。因为无需实际计算表的行数。MySQL 可以利用存储引擎的特性直接获取这个值。如果 MySQL 知道某个列 col 不可能为 NULL 值,那么内部会将 COUNT(col) 转换成COUNT(*)。 【简单优化】 有时候可以使用 MyISAM 在 COUNT(*) 全表非常快的这个特性,来加速一些特定条件的 COUNT() 查询。比如: SELECT COUNT(*) FROM city WHERE ID>5; 1 通过 SHOW STATUS 的结果可以看到该查询需要扫描 5000行数据。如果将条件反转,先查找ID小于等于5的城市,然后用总城市减就能获得同样的结果,却可以将扫描数减少到5行以内。 --ID 是索引,所以会去前5行数据 SELECT (SELECT COUNT(*) FROM city)-COUNT(*) FROM city WHERE ID<=5; 1 2 通常来说,COUNT() 都需要扫描大量的行才能获得精准的结果,因为是很难优化的。在MySQL 层面还能做的就只有索引覆盖扫描了。如果还不够,就需要考虑修改应用的架构,可以增加汇总表,或者增加类似 memcached 缓存系统。 八、优化 LIMIT 分页 在进行分页操作的时候,通常会使用 LIMIT 加上偏移量的办法实现,同时加上合适的 ORDER BY 子句。如果有对应的索引效率会不错,否则,MySQL 要做大量的文件排序操作。有一个问题,当偏移量非常大的时候,例如 LIMIT 10 000,20 这样的查询,这是需要查询10 020条记录然后只返回 20条,前面的10 000条记录都将被抛弃,这样代价太高。优化此类分页查询的最简单办法就是尽可能地使用覆盖索引扫描,而不是查询所有列。对于偏移量大的时候,这样做的效率会提升非常大。例如: SELECT id,description FROM tab ORDER BY title LIMIT 10000,20; --使用覆盖索引优化后的语句如下: SELECT f.id,f.description FROM tab f INNER JOIN (SELECT id FROM tab ORDER BY title LIMIT 10000,20) t USING(id); 1 2 3 4 5 这里的 “延迟关联” 将大大提升查询效率,它让 MySQL 扫描尽量少的页面,获取需要访问的记录后再根据关联列回原表查询需要的所有列。这个技术也可以用于优化关联查询中的 LIMIT 子句。 九、排序优化 排序是一个成本很高的操作,所以从性能角度考虑,应尽可能避免排序或者尽可能避免对大量数据进行排序。如果数据量小于 “排序缓冲区” 则在内存中排序,如果数据量大于 “排序缓冲区” 则使用磁盘进行排序 。MySQL 将这一过程统称为 “文件排序:filesort”(前提没有使用索引)。 MySQL 使用内存进行 “快速排序” 操作。如果内存不够排序,那么 MySQL 会先将数据分块,对每个队列的块使用 “快速排序” 进行排序,并将各个块的排序结果存放在磁盘上,然后将各个排好序的块进行合并(merger),最后返回排序结果。 【1】两次传输排序(旧版本使用): 读取行指针和需要排序的字段,对其进行排序,然后再根据排序结果读取所需要的数据行。需要进行两次传输,既需要从数据表中读取两次数据。第二次读取数据的时候,因为是读取排序列进行排序后的所有记录,这会产生大量的随机 I/O,所以两次数据传输的成本非常高。 【2】单次传输排序(新版本使用): 先读取排序所需要的列,然后再根据给定的列进行排序,最后直接返回排序结果。因为不需要从数据表中读取两次数据,对于I/O 密集型的应用,这样做的效率高了很多。另外,相比两次传输排序,这个算法只需要一次顺序 I/O 读取所有的数据,而无需任何随机 I/O。缺点是,如果需要返回的数据非常多,非常大,会额外占用大量空间,而这些列对排序本身并没有任何作用。很难说那个算法效率高,当查询需要所有列的总长度不操作参数 max_length_for_sort_data 时,MySQL 使用单次传输排序,可以通过调整该参数来影响 MySQL 排序算法的选择。 MySQL 在进行文件排序的时候需要使用的临时存储空间可能会比想象的要大得多。在关联查询需要排序时,会分为两种情况来处理这样的文件排序。如果 ORDER BY 子句中的所有列都来自关联的一个表,那么 MySQL 在关联处理第一个表的时候就进行了文件排序。使用 EXPLAN 查看时,看到 Extra 字段会有 “Using filesort” 。另一种情况是 MySQL 都会先将结果存放在一张临时表中,然后在所有关联都结束后,再进行文件排序。EXPLAN 结果是 “Using temporary;Using filesort”,如果包含 LIMIT 的话,LIMIT 也会在排序之后应用。在 MySQL5.6 之后。当使用 LIMIT 子句时,MySQL 不会对所有结果进行排序,而是根据实际情况,选择抛弃不满足条件的结果,然后进行排序。 十、查询状态 在分析查询性能的时候,对于一个 MySQL 连接来说,可以通过查看它的状态来观察它正在做什么。最简单的方式是 SHOW FULL PROCESSLIST 命令,该命令返回结果中的 Command 列表示当前的状态。在一个查询的生命周期中,状态会变化多次。MySQL 官方手册中对这些状态值的含义有最权威的解释,如下: 【1】Sleep: 线程正在等待客户端发送新的请求; 【2】Query: 线程正在执行查询或将结果发送给客户端; 【3】Locked: 在 MySQL 服务器层,该线程正在等待表锁。InnoDB的行锁并不会体现在线程状态中; 【4】Analyzing and statistics: 线程正在收集存储引擎的统计信息,并生成查询的执行计划。 【5】Copying to tmp table [on disk]: 线程正在执行查询,将结果都复制到一个临时表,这种状态一般要么再过 GROUP BY,要么是文件排序操作,或者是 UNION 操作。“on disk” 标记,表示 MySQL 正在讲一个内存临时表放到磁盘上。 【6】Sorting result: 线程正在对结果进行排序; 【7】Sending data: 表示多种情况,线程可能在多种状态之间传送数据。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/zhengzhaoyang122/article/details/136972698
-
大家好,三月的合集又来了,本次涵盖了java,mysql,spirngboot,oracle,nginx,webpack,css,python,mongoDB,devops,golang诸多内容供大家学习。 1.Python中数据解压缩的技巧分享【转】 https://bbs.huaweicloud.com/forum/thread-0274147063634001023-1-1.html 2.CSS如何设置背景模糊周边有白色光晕(解决方案)【转】 https://bbs.huaweicloud.com/forum/thread-02121147063476589021-1-1.html 3.CSS实现渐变式圆点加载动画【转】 https://bbs.huaweicloud.com/forum/thread-0274147063231589021-1-1.html 4. Nginx access.log日志详解及统计分析小结【转】 https://bbs.huaweicloud.com/forum/thread-0274147062581229019-1-1.html 5.Webpack部署本地服务器的方法【转】 https://bbs.huaweicloud.com/forum/thread-02110147062400691022-1-1.html 6.Nginx漏洞整改实现限制IP访问&隐藏nginx版本信息【转】 https://bbs.huaweicloud.com/forum/thread-0273147062364276013-1-1.html 7.Nginx加固的几种方式(控制超时时间&限制客户端下载速度&并发连接数)【转】 https://bbs.huaweicloud.com/forum/thread-02109147062305049017-1-1.html 8.Nginx配置http和https的实现步骤【转】 https://bbs.huaweicloud.com/forum/thread-0274147061484998017-1-1.html 9.MongoDB内存过高问题分析及解决【转】 https://bbs.huaweicloud.com/forum/thread-0276147061392824019-1-1.html 10.Oracle数据库中字符串截取最全方法总结【转】 https://bbs.huaweicloud.com/forum/thread-0240147061327119025-1-1.html 11.MySQL数据库如何克隆(带脚本)【转】 https://bbs.huaweicloud.com/forum/thread-0294147061178556014-1-1.html 12.mysql5.6建立索引报错1709问题及解决【转】 https://bbs.huaweicloud.com/forum/thread-0240147061135949024-1-1.html 13.修改Mysql索引长度限制解决767 byte限制问题【转】 https://bbs.huaweicloud.com/forum/thread-0240147060706517023-1-1.html 14.SQL实现模糊查询的四种方法小结【转】 https://bbs.huaweicloud.com/forum/thread-02121147060465820020-1-1.html 15.MySql查询中按多个字段排序的方法【转】 https://bbs.huaweicloud.com/forum/thread-0240147060411844022-1-1.html 16. Devops-01-devops 是什么?【转】 https://bbs.huaweicloud.com/forum/thread-02127146828359305034-1-1.html 17.使用 Java 在Excel中创建下拉列表【转】 https://bbs.huaweicloud.com/forum/thread-0297146827870477028-1-1.html 18.管理与控制平面设计 https://bbs.huaweicloud.com/forum/thread-0239146030318575010-1-1.html 19.cisco https://bbs.huaweicloud.com/forum/thread-0292146030276181005-1-1.html 20. NSX-V整体架构 https://bbs.huaweicloud.com/forum/thread-02127146028999196007-1-1.html 21.从NVP到NSX https://bbs.huaweicloud.com/forum/thread-0279146028887825006-1-1.html 22.【监控】spring actuator源码速读-转载 https://bbs.huaweicloud.com/forum/thread-0239145954118788007-1-1.html 23.SpringCloud-RabbitMQ消息模型-转载 https://bbs.huaweicloud.com/forum/thread-0282145954036229004-1-1.html 24.【Golang入门教程】Go语言变量的声明-转载 https://bbs.huaweicloud.com/forum/thread-0279145953985911003-1-1.html 25. Spring Boot 3核心技术与最佳实践-转载 https://bbs.huaweicloud.com/forum/thread-0239145953918959006-1-1.html
-
1、捐赠者和接受者1INSTALL PLUGIN clone SONAME 'mysql_clone.so';2、创建用户及授权捐赠者:创建克隆所需用户:12CREATE USER `clone_user`@`192.168.1.%` IDENTIFIED by 'clone_user'; GRANT BACKUP_ADMIN ON *.* TO `clone_user`@`192.168.1.%` # BACKUP_ADMIN是MySQL8.0 才有的备份锁的权限接受者:创建执行克隆权限的用户:12CREATE USER clone_user@'192.168.1.%' IDENTIFIED by 'clone_user'; GRANT CLONE_ADMIN ON *.* TO 'clone_user'@'192.168.1.%';CLONE_ADMIN权限 = BACKUP_ADMIN权限 + SHUTDOWN权限。SHUTDOWN权限允许用户shutdown和restart mysqld。授权不同是因为,接受者需要restart mysqld。3、接受者设置捐赠者列表清单1SET GLOBAL clone_valid_donor_list = '192.168.1.11:3306';4、接受者执行1CLONE INSTANCE FROM clone_user@'192.168.1.11':3306 IDENTIFIED BY 'clone_user';注意:ERROR 3870 (HY000): Clone Donor plugin validate_password is not active in Recipient.5、查看进度1SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress;6、在接受者查询捐赠款的日志信息1SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;7、查询进度的另一条SQLselect stage, state, cast(begin_time as DATETIME) as "START TIME", cast(end_time as DATETIME) as "FINISH TIME", lpad(sys.format_time(power(10,12) * (unix_timestamp(end_time) - unix_timestamp(begin_time))), 10, ' ') as DURATION, lpad(concat(format(round(estimate/1024/1024,0), 0), "MB"), 16, ' ') as "Estimate", case when begin_time is NULL then LPAD('%0', 7, ' ') when estimate > 0 then lpad(concat(round(data*100/estimate, 0), "%"), 7, ' ') when end_time is NULL then lpad('0%', 7, ' ') else lpad('100%', 7, ' ') end as "Done(%)" from performance_schema.clone_progress; 8、 修改主从关系1CHANGE MASTER TO MASTER_HOST='10.0.14.141', MASTER_PORT=61106 ,MASTER_USER='repl',MASTER_PASSWORD='xxxxxxxx',MASTER_AUTO_POSITION = 1;复制9、clone脚本有一步重新初始化的操作,记得修改对应的目录 #!/usr/bin/env bash CLONE_ADMIN_USER="clone_user@'192.168.x.%'" CLONE_VALID_DONOR_LIST="192.168.x.x" MYSQL_PORT=3306 ROOT_PASSWORD="123456" # 仅支持GTID模式 # GTID_MODE=1 #删除旧文件 function del_old_file() { systemctl stop mysqld && rm -rf /data/logs/* && rm -rf /data1/data* && rm -rf /data/data/binlog/* && rm -rf /data/data/relaylog/* } function start_mysqld() { systemctl start mysqld OLDPASSWORD=`grep 'temporary password' /data/logs//mysqld.log | awk '{printf $NF}'` SETPASSWDTXT="set global validate_password.policy='LOW';alter user root@localhost identified by '${ROOT_PASSWORD}';" mysql -h localhost -P${MYSQL_PORT} -uroot -p${OLDPASSWORD} -e "${SETPASSWDTXT}" --connect-expired-password } function install_plugin() { INSTALL_PLUGIN_SQL="INSTALL PLUGIN clone SONAME 'mysql_clone.so'" mysql -h localhost -P${MYSQL_PORT} -uroot -p${ROOT_PASSWORD} -e "${INSTALL_PLUGIN_SQL}" --connect-expired-password } function set_clone_user() { SET_CLONE_USER_SQL="set global validate_password.policy='LOW';CREATE USER IF NOT EXISTS ${CLONE_ADMIN_USER} IDENTIFIED by 'clone_user';GRANT BACKUP_ADMIN,CLONE_ADMIN ON *.* TO ${CLONE_ADMIN_USER};" mysql -h localhost -P${MYSQL_PORT} -uroot -p${ROOT_PASSWORD} -e "${SET_CLONE_USER_SQL}" --connect-expired-password } function begin_clone() { CLONE_SQL="SET GLOBAL clone_valid_donor_list = '${CLONE_VALID_DONOR_LIST}:${MYSQL_PORT}';CLONE INSTANCE FROM clone_user@'${CLONE_VALID_DONOR_LIST}':${MYSQL_PORT} IDENTIFIED BY 'clone_user';" mysql -h localhost -P${MYSQL_PORT} -uroot -p${ROOT_PASSWORD} -e "${CLONE_SQL}" --connect-expired-password && echo "CLONE ENDS ... " } function change_master() { CHANGE_MASTER_SQL="STOP SLAVE;CHANGE MASTER TO MASTER_HOST='${CLONE_VALID_DONOR_LIST}', MASTER_PORT=${MYSQL_PORT} ,MASTER_USER='repl',MASTER_PASSWORD='repl20150602',MASTER_AUTO_POSITION = 1;START SLAVE;" mysql -h localhost -P${MYSQL_PORT} -uroot -p${ROOT_PASSWORD} -e "${CHANGE_MASTER_SQL}" --connect-expired-password } function execute_all() { del_old_file start_mysqld install_plugin set_clone_user begin_clone change_master } function usage() { echo "mysql-clone {-h|-d|-s|-u|-c|-m|-a}" echo "del_old_file(-d) -- stop mysqld and delete old mysql-datafiles" echo "start_mysqld(-s) -- start mysqld and set newpassword" echo "install_plugin(-i) -- install clone plgin" echo "set_clone_user(-u) -- set clone user" echo "begin_clone(-c) -- set clone donor and clone" echo "change_master(-m) -- change master" echo "execute_all(-a) -- execute all" } case "$1" in '-d') del_old_file ;; '-s') start_mysqld ;; '-i') install_plugin ;; '-u') set_clone_user ;; '-c') begin_clone ;; '-m') change_master ;; '-a') execute_all ;; *) usage esac
-
在给varchar字段建立索引时,报错如下:[root@localhost:(test) 13:53:27]> CREATE INDEX b_name_IDX USING BTREE ON test.b(name);ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.查看表结构:CREATE TABLE `b` ( `name` varchar(250) DEFAULT NULL, `standardized_name` varchar(250) DEFAULT NULL, `is_reagent` int(11) NOT NULL DEFAULT '0', `is_solvent` int(11) NOT NULL DEFAULT '0', `is_catalyst` int(11) NOT NULL DEFAULT '0', `is_ligand` int(11) NOT NULL DEFAULT '0', `to_delete` int(11) DEFAULT '0', ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;索引字段的长度大于767,或者说,使用到的字段的长度和大于767则报错。MySQL 5.6 中的innodb_large_prefix默认是关闭的。在MySQL中,innodb_large_prefix 参数是一个 InnoDB 存储引擎的配置选项。这个参数控制是否允许使用超过767字节(或255个字符)的索引前缀。默认情况下,在MySQL 5.6及以前版本中,InnoDB存储引擎对索引列的最大长度限制为767字节。对于变长数据类型如VARCHAR,这个限制包括了字符集的每个字符可能占用的字节数,而不是仅仅指字符数。例如,如果你使用的是UTF-8字符集,每个字符可能占用1到4个字节,所以一个VARCHAR(255)字段的实际最大长度可能会远小于255个字符。当 innodb_large_prefix 设置为 ON 时,InnoDB 支持更大的索引前缀长度,最大可以达到3072字节。这意味着你可以创建更长的索引,特别是对于包含大量变长数据类型的列。这对于处理大数据表和需要更复杂查询的情况非常有用。要启用 innodb_large_prefix,你可以在 MySQL 配置文件(如 my.cnf 或 my.ini)中添加以下行,并重启 MySQL 服务以应用更改:[mysqld] innodb_large_prefix = ON或者,你可以在运行时通过设置全局变量来开启它:SET GLOBAL innodb_large_prefix = ON;请注意,为了使 innodb_large_prefix 生效,还需要同时满足以下条件:有关这些条件的详细信息,请参阅 MySQL 文档。set global innodb_large_prefix=on; show variables like 'innodb_large_prefix'; alter table b Row_format=dynamic; set global innodb_file_format=BARRACUDA;再次加索引:[root@localhost:(test) 13:54:18]> CREATE INDEX b_name_IDX USING BTREE ON test.b(name); Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0
-
报错Specified key was too long; max key length is 767 bytes原因msyql5.6及以前版本, 默认索引最大长度767bytes若使用utf8mb4格式编码(utf8字符占用3字节,utf8mb4字符占用4字节)则单个字段长度不能超过1915.7及之后版本, 限制放开到3072 bytes解决方案一、将数据库版本升级到5.7版本或以上二、修改相关配置,增加操作以解决解决方案如下:1、在my.ini中修改配置:123innodb_large_prefix = ON innodb_file_format = Barracuda innodb_file_per_table = ON2、在create中添加row_format=dynamic12345678910create table sql_test(id int ,name VARCHAR(200),server_id VARCHAR(30),id_num1 VARCHAR(30),id_num2 VARCHAR(30),link VARCHAR(500),PRIMARY KEY (id),KEY sql_test_name (name)) engine=innodb row_format=dynamic;这样做的缺点会造成查询性能下降
-
一、一般模糊查询1. 单条件查询12//查询所有姓名包含“张”的记录select * from student where name like '张'2. 多条件查询1234//查询所有姓名包含“张”,地址包含四川的记录select * from student where name like '张' and address like '四川'//查询所有姓名包含“张”,或者地址包含四川的记录select * from student where name like '张' or address like '四川'二、利用通配符查询通配符:_ 、% 、[ ]1. _ 表示任意的单个字符1234//查询所有名字姓张,字长两个字的记录select * from student where name like '张_'//查询所有名字姓张,字长三个字的记录select * from student where name like '张__'2. % 表示匹配任意多个任意字符1234//查询所有名字姓张,字长不限的记录select * from student where name like '张%'//查询所有名字姓张,字长两个字的记录select * from student where name like '张%'and len(name) = 23. [ ]表示筛选范围12345678910//查询所有名字姓张,第二个为数字,第三个为燕的记录select * from student where name like '张[0-9]燕'//查询所有名字姓张,第二个为字母,第三个为燕的记录select * from student where name like '张[a-z]燕'//查询所有名字姓张,中间为1个字母或1个数字,第三个为燕的名字。字母大小写可以通过约束设定,不区分大小写select * from student where name like '张[0-9a-z]燕'//查询所有名字姓张,第二个不为数字,第三个为燕的记录select * from student where name like '张[!0-9]燕'//查询名字除了张开头妹结尾中间是数字的记录select * from student where name not like '张[0-9]燕'4. 查询包含通配符的字符串123456//查询姓名包含通配符%的记录 select * from student where name like '%[%]%' //通过[]转义//查询姓名包含[的记录 select * from student where name like '%/[%' escape '/' //通过指定'/'转义//查询姓名包含通配符[]的记录 select * from student where name like '%/[/]%' escape '/' //通过指定'/'转义
-
在 SQL 查询中,经常需要按多个字段对结果进行排序。本文将介绍如何使用 SQL 查询语句按多个字段进行排序,提供几种常见的排序方式供参考。在 SQL 查询中,按多个字段进行排序可以通过在 ORDER BY 子句中指定多个字段和排序方向来实现。下面介绍几种常见的排序方式:在 SQL 查询中,首先可以按照一个字段进行排序,然后再按照另一个字段进行排序。示例代码如下:SELECT column1, column2, column3 FROM table_name ORDER BY column1 ASC, column2 DESC;在上述示例中,我们首先按照 column1 字段进行升序排序,然后按照 column2 字段进行降序排序。除了按照一个字段进行排序外,还可以按照多个字段进行排序。示例代码如下:SELECT column1, column2, column3 FROM table_name ORDER BY column1 ASC, column2 DESC, column3 ASC;在上述示例中,我们按照 column1 字段进行升序排序,然后按照 column2 字段进行降序排序,最后按照 column3 字段进行升序排序。默认情况下,排序是升序的(ASC)。如果需要降序排序,可以在字段后面添加 DESC 关键字。示例代码如下:SELECT column1, column2, column3 FROM table_name ORDER BY column1 ASC, column2 DESC, column3 ASC;在上述示例中,我们按照 column1 字段进行升序排序,按照 column2 字段进行降序排序,最后按照 column3 字段进行升序排序。通过本文的介绍,你学习了如何在 SQL 查询中按多个字段进行排序。你了解了按单个字段排序和按多个字段排序的方式,以及如何指定排序方向(升序或降序)。这些方法可以帮助你根据需求对查询结果进行灵活的排序操作。在实际应用中,根据具体需求选择合适的排序方式和字段组合,可以使查询结果更符合预期,提高数据的可读性和分析能力。
-
Linux下MySQL安装配置 MySQL配置参数详解 一、下载编译安装 #cd /usr/local/src/ #wget http://mysql.byungsoo.net/Downloads/MySQL-5.1/mysql-5.1.38.tar.gz #tar –xzvf mysql-5.1.38.tar.gz ../software/ #./configure --prefix=/usr/local/mysql //MySQL安装目录 --datadir=/mydata //数据库存放目录 --with-charset=utf8 //使用UTF8格式 --with-extra-charsets=complex //安装所有的扩展字符集 --enable-thread-safe-client //启用客户端安全线程 --with-big-tables //启用大表 --with-ssl //使用SSL加密 --with-embedded-server //编译成embedded MySQL library (libmysqld.a), --enable-local-infile //允许从本地导入数据 --enable-assembler //汇编x86的普通操作符,可以提高性能 --with-plugins=innobase //数据库插件 --with-plugins=partition //分表功能,将一个大表分割成多个小表 #make && make install //编译然后安装 二、新建用户和组 #groupadd mysql //建MySQL组 #useradd -g mysql -s /sbin/nologin mysql //建MySQL用户属于MySQL组 三、配置#chown -R mysql:mysql /usr/local/mysql/ 把MySQL目录的权限给MySQL用户和组 #cp /usr/local/src/software/ mysql-5.1.38/support-files/my-medium.cnf /etc/my.cnf //拷入配置文件my.cnf #/usr/local/mysql/bin/mysql_install_db --user=mysql //用MySQL来初始化数据库 #chown -R mysql:mysql /usr/local/mysql/var/ //把初始化的数据库目录给MySQL所有者 #/usr/local/mysql/bin/mysqld_safe --user=mysql & //启动MySQL 四、其他#cp /usr/local/src/software/ mysql-5.1.38/support-files/mysql.server /etc/init.d/mysqld #chmod 755 /etc/init.d/mysqld #chkconfig --add mysqld #chkconfig mysqld on #service mysqld restart 五、登陆测试 #cd /usr/local/mysql/bin #mysql >show databases; # MySQL安装结束 linux下mysql配置方法在linux中mysql的配置文件路径在/usr/share/mysql下 有:my-huge.cnf 、my-large.cnf、 my-medium、my-small.cnf这些文件 根据需要打开这些文件中的一个: 在文件中找到[mysqld] 在下这行下加入datadir=FILEPATH /*这个路径为数据库存放的路径*/ 然后保存文件 在shell中输入 #cp my-***.cnf /etc #cd /etc #mv my.cnf my.cnf.bak /*把系统以前的mysql配置文件备份*/ #mv my-***.cnf my.cnf #service mysqld start /*启动mysql服务*/ #ntsysv /*配置mysql自启动,在弹出的窗口中把mysqld这项服务用空格选中,最后确定保存*/ 时间: 2011-07-19 Fedora5下配置MySQL (很有参考价值的 MySQL资料 包括如何在linux文件系统移动MySQL数据库的位置) 一.下载MySQL安装文件 完全安装MySQL需要下面6个文件: MySQL-server-community-5.1.26-0.rhel4.i386.rpm MySQL-client-community-5.1.26-0.rhel4.i386.rpm MySQL-shared-community-5.1.26-0.rhel4.i386.rpm MySQL-devel-co 有台linux服务器,系统为centos系统. 网站突然连接不上数据库,于是朋友直接重启了一下服务器.进到cli模式下,执行 service myqsld start 发现还是提示"mysql deamon failed to start"错误信息. # /etc/init.d/mysqld start MySQL Daemon failed to start. Starting mysqld: [FAILED] 查看mysqld的log文件 #less /var/log/mysqld 1.可能是/usr/local/mysql/data/rekfan.pid文件没有写的权限解决方法 :给予权限,执行 "chown -R mysql:mysql /var/data" "chmod -R 755 /usr/local/mysql/data" 然后重新启动mysqld! 2.可能进程里已经存在mysql进程解决方法:用命令"ps -ef|grep mysqld"查看是否有mysqld进程,如果有使用"kill -9 进 由于是从源码包安装的Mysql,所以系统中是没有红帽常用的servcie mysqld restart这个脚本 只好手工重启 有人建议Killall mysql.这种野蛮的方法其实是不行的,强制终止的话,如果造成表损坏,损失是巨大的. 这里推荐安全的重启方法 $mysql_dir/bin/mysqladmin -u root -p shutdown $mysql_dir/bin/safe_mysqld & mysqladmin和mysqld_safe位于Mysql安装目录的bin目录下,很容易找 linux环境Mysql 5.7.13安装教程分享给大家,供大家参考,具体内容如下 1系统约定 安装文件下载目录:/data/software Mysql目录安装位置:/usr/local/mysql 数据库保存位置:/data/mysql 日志保存位置:/data/log/mysql 2下载mysql 在官网:http://dev.mysql.com/downloads/mysql/ 中,选择以下版本的mysql下载: 执行如下命名: #mkdir /data/software #cd /da 从今年3月份开始mysql官网开始发布相关的5.6系列的各个版本,对于mysql5.6系列的版本对一起的版本进行了全局性的细节性加强:个人感觉,以下是在虚拟机中配置的mysql5.6.10源码安装的过程分享记录下: [root@mysql5 ~]# groupadd mysql [root@mysql5 ~]# useradd -r -g mysql mysql [root@mysql5 ~]# ls anaconda-ks.cfg install.log install.log.syslog 1.apache 在如下页面下载apache的for Linux 的源码包 http://www.apache.org/dist/httpd/; 存至/home/xx目录,xx是自建文件夹,我建了一个wj的文件夹. 命令列表: cd /home/wj tar -zxvf httpd-2.0.54.tar.gz mv httpd-2.0.54 apache cd apache ./configure --prefix=/usr/local/apache2 --enable-mod 在开始安装前,先说明一下mysql-5.6.4与较低的版本在安装上的区别,从mysql-5.5起,mysql源码安装开始使用cmake了,因此当我们配置安装目录./configure --perfix=/.....的时候和以前的会有些区别,这点我们稍后会提到. 一:解压缩mysql-5.6.4-m7-tar.zip 1> unzip mysql-5.6.4-m7-tar.zip 会生成mysql-5.6.4-m7-tar.gz的压缩文件 2> tar -zxvf mysql-5.6.4- 因导出sql文件 在你原来的网站服务商处利用phpmyadmin导出数据库为sql文件,这个步骤大家都会,不赘述. 上传sql文件 前面说过了,我们没有在云主机上安装ftp,怎么上传呢? 打开ftp客户端软件,例如filezilla,使用服务器IP和root及密码,连接时一定要使用SFTP方式连接,这样才能连接到linux.注意,这种方法是不安全的,但我们这里没有ftp,如果要上传本地文件到服务器,没有更好更快的方法. 我们把database.sql上传到/tmp目录. 连接到linux,登录m 一.安装Mysql 1.下载MySQL的安装文件安装MySQL需要下面两个文件:MySQL-server-4.0.16-0.i386.rpm MySQL-client-4.0.16-0.i386.rpm下载地址为:http://dev.mysql.com/downloads/mysql-4.0.html,打开此网页,下拉网页找到"Linux x86 RPM downloads"项,找到"Server"和"Client programs"项,下载需 系统:Ubuntu 16.04LTS 1\官网下载mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz 2\建立工作组: $su #groupadd mysql #useradd -r -g mysql mysql 3\创建目录 #mkdir /usr/local/mysql #mkdir /usr/local/mysql/data 4\解压mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz,并拷贝至/usr/local/mysql 一.Linux下安装配置nginx 第一次安装nginx,中间出现的问题一步步解决. 用到的工具secureCRT,连接并登录服务器. 1.1 rz命令,会弹出会话框,选择要上传的nginx压缩包. #rz 1.2 解压 [root@vw010001135067 ~]# cd /usr/local/ [root@vw010001135067 local]# tar -zvxf nginx-1.10.2.tar.gz 1.3 进入nginx文件夹,执行./configure命令 [root@vw0 亲测有效 在网上查找了好多资料,很多都安装不成功,而且都是同一个资料相互抄袭泛蓝,没一个实用的.今天配置好了,将配置过程分享一下. Linux下的Memcache运行需要libevent的支持,所以在安装memcache之前必须要安装libevent.安装过程中可能会遇到很多问题,本人都将可能遇到错误时的解决办法整理出来了. 1.先安装libevent: #yum -y install libevent libevent-devel 2.安装memcached,最新版本为:memcached-1 Ubuntu安装Mysq有l三种安装方式,下面就为大家一一讲解,具体内容如下 1. 从网上安装 sudo apt-get install mysql-server.装完已经自动配置好环境变量,可以直接使用mysql的命令. 注:建议将/etc/apt/source.list中的cn改成us,美国的服务器比中国的快很多. 2. 安装离线包,以mysql-5.0.45-linux-i686-icc-glibc23.tar.gz为例. 3. 二进制包安装:安装完成已经自动配置好环境变量,可以直接使用m 今天需要把linux服务器上的mysql版本从5.1更新到5.7,那么以下内容作为记录,提供以后安装使用手册 第一步:检查linux的操作系统版本 复制代码 代码如下: cat /etc/issue 第二步:在mysql官网上下载5.7的版本 http://dev.mysql.com/downloads/file.php?id=451627 第三步:检查linux上以前安装的mysql版本 复制代码 代码如下: rpm -qa | grep mysql 第四步:如果出现mysql的一些安装版本, 首先需要安装配置JDK,这里简单回顾下.Linux下用root身份在/opt/文件夹下创建jvm文件夹,然后使用tar -zxvf jdk-8u121-linux-x64.tar.gz -C /opt/jvm/ 将文件解压至jvm中,然后以root身份修改/etc/profile文件,在最后四行加入: export JAVA_HOME=/opt/jvm/jdk1.8.0_121 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_ file:/// 直接版本库访问(本地磁盘). http:// 通过配置Subversion的Apache服务器的WebDAV协议. https:// 与http://相似,但是包括SSL加密. svn:// 通过svnserve服务自定义的协议. svn+ssh:// 与svn://相似,但通过SSH封装 svn存储版本数据也有2种方式:BDB和FSFS.因为BDB方式在服务器中断时,有可能锁住数据,所以还是FSFS方式更安全一点.1. svn服务器安装操作系统: Redhat Linux A 我的操作系统为centos6.5 1 首先选择django要使用什么数据库.django1.10默认数据库为sqlite3,本人想使用mysql数据库,但为了测试方便顺便要安装一下sqlite开发包. yum install mysql mysql-devel #为了测试方便,我们需要安装sqlite-devel包 yum install sqlite-devel 2 接下来需要安装Python了,因为Python3已经成为主流,所以接下来我们要安装Python3,到官网去下载Python3 一.解压文件到当前目录 命令:tar -zxvf mysql....tar.gz 二.移动解压完成的文件夹到目标目录并更名mysql 命令:mv mysql-版本号 /usr/local/mysql 添加系统mysql组和mysql用户 添加系统mysql组 sudo groupadd mysql 添加mysql用户 sudo useradd -r -g mysql mysql 添加完成后可用id mysql查看 然后进入/usr/local/mysql目录 设置mysql用户组对该文件夹操作 本篇内容主要给大家讲解一下如何在linux下安装MYSQL数据库,并以安装MYSQL5.6版本为例子教给大家进行登录用户名和密码的修改等操作. 原文链接:https://blog.csdn.net/pjw0221/article/details/5679536
-
一、MySQL5.1安装 打开下载的安装文件,出现如下界面:mysql安装向导启动,点击“next”继续 选择安装类型,有“Typical(默认)”、“Complete(完全)”、“Custom(用户自定义)”三个选项,我们选择“Custom”,有更多的选项,也方便熟悉安装过程。 在“MySQL Server(MySQL服务器)”上左键单击,选择“This feature, and all subfeatures, will beinstalled on local hard drive.”,即“此部分,及下属子部分内容,全部安装在本地硬盘上”。点选“Change...”,手动指定安装目录。确认一下先前的设置,如果有误,按“Back”返回重做。按“Install”开始安装。正在安装中,请稍候,直到出现下面的界面。点击“next”继续,出现如下界面。 现在软件安装完成了,出现上面的界面,这里有一个很好的功能,mysql 配置向导,不用向以前一样,自己手动乱七八糟的配置my.ini 了,将“Configure the Mysql Server now”前面的勾打上,点“Finish”结束软件的安装并启动mysql配置向导。二、配置MySQL Server 点击“Finsh”,出现如下界面,MySQL Server配置向导启动。点击“next”出现如下界面, 选择配置方式,“Detailed Configuration(手动精确配置)”、“Standard Configuration(标准配置)”,我们选择“Detailed Configuration”,方便熟悉配置过程。 选择服务器类型,“Developer Machine(开发测试类,mysql 占用很少资源)”、“Server Machine(服务器类型,mysql占用较多资源)”、“Dedicated MySQL Server Machine(专门的数据库服务器,mysql占用所有可用资源)”,大家根据自己的类型选择了,一般选“Server Machine”,不会太少,也不会占满。 选择mysql数据库的大致用途,“Multifunctional Database(通用多功能型,好)”、“Transactional Database Only(服务器类型,专注于事务处理,一般)”、“Non-Transactional Database Only(非事务处理型,较简单,主要做一些监控、记数用,对MyISAM数据类型的支持仅限于non-transactional),随自己的用途而选择了,我这里选择“Transactional Database Only”,按“Next”继续。 对InnoDB Tablespace进行配置,就是为InnoDB 数据库文件选择一个存储空间,如果修改了,要记住位置,重装的时候要选择一样的地方,否则可能会造成数据库损坏,当然,对数据库做个备份就没问题了,这里不详述。我这里没有修改,使用默认位置,直接按“Next”继续。 选择您的网站的一般mysql 访问量,同时连接的数目,“Decision Support(DSS)/OLAP(20个左右)”、“Online Transaction Processing(OLTP)(500个左右)”、“Manual Setting(手动设置,自己输一个数)”,我这里选“Online Transaction Processing(OLTP)”,自己的服务器,应该够用了,按“Next”继续。 是否启用TCP/IP连接,设定端口,如果不启用,就只能在自己的机器上访问mysql 数据库了,我这里启用,把前面的勾打上,Port Number:3306,在这个页面上,您还可以选择“启用标准模式”(Enable Strict Mode),这样MySQL就不会允许细小的语法错误。如果您还是个新手,我建议您取消标准模式以减少麻烦。但熟悉MySQL以后,尽量使用标准模式,因为它可以降低有害数据进入数据库的可能性。还有一个关于防火墙的设置“Add firewall exception ……”需要选中,将MYSQL服务的监听端口加为windows防火墙例外,避免防火墙阻断。按“Next”继续。 注意:如果要用原来数据库的数据,最好能确定原来数据库用的是什么编码,如果这里设置的编码和原来数据库数据的编码不一致,在使用的时候可能会出现乱码。这个比较重要,就是对mysql默认数据库语言编码进行设置,第一个是西文编码,第二个是多字节的通用utf8编码,都不是我们通用的编码,这里选择第三个,然后在Character Set 那里选择或填入“gbk”,当然也可以用“gb2312”,区别就是gbk的字库容量大,包括了gb2312的所有汉字,并且加上了繁体字、和其它乱七八糟的字——使用mysql 的时候,在执行数据操作命令之前运行一次“SET NAMES GBK;”(运行一次就行了,GBK可以替换为其它值,视这里的设置而定),就可以正常的使用汉字(或其它文字)了,否则不能正常显示汉字。按“Next”继续。 选择是否将mysql 安装为windows服务,还可以指定Service Name(服务标识名称),是否将mysql的bin目录加入到Windows PATH(加入后,就可以直接使用bin下的文件,而不用指出目录名,比如连接,“mysql.exe -uusername -ppassword;”就可以了,不用指出mysql.exe的完整地址,很方便),我这里全部打上了勾,Service Name不变。按“Next”继续。 这一步询问是否要修改默认root 用户(超级管理)的密码(默认为空),“New root password”如果要修改,就在此填入新密码(如果是重装,并且之前已经设置了密码,在这里更改密码可能会出错,请留空,并将“Modify Security Settings”前面的勾去掉,安装配置完成后另行修改密码),“Confirm(再输一遍)”内再填一次,防止输错。“Enable root access from remotemachines(是否允许root 用户在其它的机器上登陆,如果要安全,就不要勾上,如果要方便,就勾上它)”。最后“Create An Anonymous Account(新建一个匿名用户,匿名用户可以连接数据库,不能操作数据,包括查询)”,一般就不用勾了,设置完毕,按“Next”继续。 确认设置无误,如果有误,按“Back”返回检查。按“Execute”使设置生效。 设置完毕,按“Finish”结束mysql的安装与配置——这里有一个比较常见的错误,就是不能“Startservice”,一般出现在以前有安装mysql 的服务器上,解决的办法,先保证以前安装的mysql 服务器彻底卸载掉了;不行的话,检查是否按上面一步所说,之前的密码是否有修改,照上面的操作;如果依然不行,将mysql 安装目录下的data文件夹备份,然后删除,在安装完成后,将安装生成的data文件夹删除,备份的data文件夹移回来,再重启mysql 服务就可以了,这种情况下,可能需要将数据库检查一下,然后修复一次,防止数据出错。三、说明 本文所涉及内容均可以在MySQL参考手册第二章“安装MySQL”中找到。MySQL参考手册地址cid:link_0。mysql的下载地址:cid:link_1。 填上安装目录,例如“F:MySQL”,也建议不要放在与操作系统同一分区,这样可以防止系统备份还原的时候,数据被清空。按“OK”继续。原文链接:https://blog.csdn.net/_net2004/article/details/5772831
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签