mysql 怎么改变表格中的数据

哎哟,咱们今天得好好聊聊MySQL的DBUG工具,这玩意儿啊,就像是给MySQL做了一次全身检查,能让你看到它处理SQL语句时的一举一动。
咱们先来个小实验,看看这DBUG怎么玩。

首先,咱们得改一下启动文件,把原来的CUSTOM_MYSQLD改成mysqld-debug,然后重启一下实例,记得加上debug参数。
这样一来,MySQL就能开始记录它的“日记”了。

接下来,咱们来做一两个实验,看看DBUG包能干啥。
我先设置个简单的调试规则,俩调试选项:一个是d,开启各个调试点的输出;另一个是O,把输出结果记到文件里,我这里指定的是/tmp/mysqld.trace。

然后咱们创建一张表,看看调试输出的结果。
嘿,这输出里头,MySQL处理表的细节全出来了,比如它怎么分配内存的,alloc_root这事儿,都写得明明白白。

不过,光看这些细节还不够直观,咱们得加点料。
我再增加一些信息,比如函数调用树,这样一来,输出就变成了调用树的形式,咱们就能清楚地看到alloc_root分配的内存是干嘛用的,比如是为了解析SQL的mysql_parse。

再增加点有用的信息,比如文件名和行号,这下输出里头就有啦。
咱们现在可以在输出里头找找统计表相关的信息,嘿,MySQL这里头挺聪明的,直接执行了一个内置的存储过程来更新统计表。

顺着que_eval_sql这线索,咱们还能找到其他类似的统计表,比如下面这些。
这DBUG工具啊,真是帮咱们省了不少力气。

这次实验,咱们就是借助了MySQL的DBUG包,让MySQL把处理过程都暴露出来。
其实,MySQL里头类似的技术还挺多,比如performance_schema,OPTIMIZER_TRACE,这些都能把MySQL的不同信息暴露出来,方便咱们理解其中的机制。

说实话,我当时也没想明白这DBUG具体怎么用,后来慢慢摸索,才发现这玩意儿真是挺有用的。
咱们做数据库的,有时候就得这样,得自己动手实践,才能慢慢摸清门道。

MySQL的一行转换为多行技巧mysql一行变成多行

哎哟,说起来这MySQL一行变多行的技巧,咱们得好好聊聊。
我以前在做项目的时候,这事儿碰得可多了。

先说第一个,就是用UNIONALL。
这玩意儿啊,就像是把几个SELECT语句的成果拼在一起。
咱们举个例子,比如有个用户表,里面有个列叫interests,存的是用户的兴趣爱好。
你想把这些兴趣点拆成单独的行,怎么搞呢?
得先来个子查询,弄个数字表,从0到9 ,这样就能代表所有可能的分隔符位置。
然后,再用SUBSTRING_INDEX函数,把interests按逗号分割,每次取一个值。
这回,我们得用UNIONALL,把每个可能的值都提出来,变成多行。
像这样:
sql SELECT id, interest FROM ( SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(interests, ',', n.digit+1 ), ',', -1 ) AS interest FROM users JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) n ON LENGTH(REPLACE(interests, ',', '')) = n.digit + 1 ) t;
第二个方法,就是用GROUPBY。
这个嘛,更简单一些。
比如,有个订单表,里面有个items列,存的是订单里的商品。
你想把这些商品也拆成单独的行,怎么搞?
先弄个子查询,从订单表里选出来需要的数据。
再用SUBSTRING_INDEX函数,把每个商品分割开。
最后,用GROUPBY,把相同的商品组合起来。
像这样:
sql INSERT INTO new_orders(order_id, item) SELECT order_id, SUBSTRING_INDEX(SUBSTRING_INDEX(items, ',', n.digit+1 ), ',', -1 ) AS item FROM ( SELECT order_id, items FROM orders ) t JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) n ON LENGTH(REPLACE(items, ',', '')) = n.digit + 1 WHERE item != '';
说实话,当时我刚开始学这玩意儿的时候,也没想明白怎么用。
不过,实践多了,慢慢就上手了。
这两种方法,都是挺实用的,特别是在数据转换和插入的时候。