读书 - 《MySQL 技术内幕(第4版)》之常用命令不平常

毕业多年,问题驱动型学习模式,学习不挑食,现在成功的成为前端、后端、移动端的全栈,不,是全干程序员。

问题驱动学习,导致学习碎片化,知识体系不专一,用时方学,再用其他工具时继续学,边学边忘。很难想像自己曾外包一年到家电子商务公司做报表数据整理,报表涉及到 ibm cognos、microsoft reporting service、webfocus、qlickview、ireport,客户部分第三方数据通过 excel 导入,当时使用 vb 编程做各种关联、筛选、联动汇总,感叹 excel 的强大,但此刻感觉好遥远,远得把我再放回工位会无从下手。

天天挂在口头的缩写单词,用得太多已忘记它的原意,很庆幸自己愚笨的大脑里还尚存自知,看到略感陌生的单词全拼统统放入笔记,工作多年的事实永远是自黑的依据。

SQL: structured query language 结构化查询语言
RTF: rich text format 富文本格式
RDBMS: relational database management system 关系数据库管理系统

常用命令的常用用法不值得放在笔记中,是的,此篇笔记就是按这个思路整理的,白纸黑字,为日后扇脸留下些痕迹。

操作数据库的第一步,自是开门进屋,再翻箱倒柜的找东西;登录操作目前没有发现不平常的用法,参数可指定主机、端口、编码类型、数据库、是否加载数据等功能。

$ mysql -uroot -ppassword;
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 61
Server version: 5.6.16 Homebrew

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

上面这段提示语不能再眼熟,熟到没有完整的阅读过整体文字,若是告诉你里面提示了几个不常用的命令,你能找到几个或用到过几个?

sql 语句语法是以分号 ; 结尾,也可以使用 \g ,虽然感觉分号更简洁,但必需承认在阅读此书前我是无知的。

mysql> select now()\g
+---------------------+
| now()               |
+---------------------+
| 2016-11-09 23:26:18 |
+---------------------+
1 row in set (0.00 sec)

\c 清空当前的输入,解释很简单,平时使用 ctrl + u 组合命令清空输入的信息,但试想若 sql 语句过长分行输入时,其间发现输入有误放弃已输入命令,如何做?无知的我是直接输入分号 ; 表示 sql 语句结束再回车,任由报错信息横行。其实输入 \c 才是干净、优雅的解决方案。

mysql> select
    -> now()\c
mysql>

sqlite3 支持结果集行列转换,一直以来以为是 sqlite3 的特性,还是我所待的井太深,结尾符使用 \G 表示结果集行列转换。

mysql> select now()\G
*************************** 1. row ***************************
now(): 2016-11-09 23:31:19
1 row in set (0.00 sec)

业务逻辑复杂时在多个数据库中切来切去,乱忙一通后,还记当前是那个数据库吗?之前我的做法,想继续在那个数据库操作就再执行 use the-db-i-want,这样操作过于暴力,查看一下当前所在数据库省时省力。

mysql> select database();
+------------+
| database() |
+------------+
| NULL       |
+------------+
1 row in set (0.00 sec)

查看表结构只会 desc,其实下面五行命令都可以达到预期的效果,虽然最终还坚持简短的 desc,但多了四条学习的入口。

mysql> desc sys_users;
mysql> describe sys_users;
mysql> explain sys_users;
mysql> show columns from sys_users;
mysql> show fields from sys_users;

有些属性表字段列表好几屏,总有些字段名让记混,如何过滤字段?在 information_schema 数据库中翻来倒去的各种不利索,其实查看表结构的命令本身就支持过滤功能,解锁更多用法请查看 api。

mysql> desc sys_users 'user_name';
mysql> show columns from sys_users like '%name';
mysql> show fields from sys_users like '%name';

数据库一般不会很多,数据表上百倒是稀松平常,有些功能相近的数据表名完全没有让人想去记的欲望,只记得一些关键字,如何去过滤?曾经自以为找到了救星 page 命令,但过于啰嗦,show 命令原天然支持。

mysql> show databases like '%bi';
mysql> show tables like '%bases';

平时按行 values() 插入数据,也可以按列 set 插入,用法一目了然,为日后多条解法思路。

mysql> create table test_set (first_name varchar(255), last_name varchar(255));
Query OK, 0 rows affected (0.05 sec)

mysql> insert into test_set value();
Query OK, 1 row affected (0.01 sec)

mysql> select * from test_set;
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| NULL       | NULL      |
+------------+-----------+
1 row in set (0.00 sec)

mysql> insert into test_set set first_name='hello';
Query OK, 1 row affected (0.00 sec)

mysql> select * from test_set;
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| NULL       | NULL      |
| hello      | NULL      |
+------------+-----------+
2 rows in set (0.00 sec)

虽然登录成功后提示的文字中包含了版本信息,也不耽误随时查看 mysql 版本。

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.6.16    |
+-----------+
1 row in set (0.00 sec)

虽然百分之八十的运算符都有用过,就是因为它全必须收下。

读书 - 《MySQL 技术内幕(第4版)》之常用命令不平常_第1张图片
MySQL 运算符

数据过滤比较 null 时都是使用 is,查看上述运算符可以知道宇宙飞船是相当有用的,日常可以不用,但阅读别人代码时至少不应该怔住。

where name is null;
where name <=> null;
where name is not null;
where not (name <=> null);

使用 if 命令排序,场景比如: 按加入时间升序查看用户列表,那些未赋值的行就会排前面,使用 where 过滤则会显示部分结果集,如何做到显示所有用户,并按加入时间升序,加入时间为 null 的排在后面?

mysql> select user_name, join_date
    -> from sys_users
    -> order by if(join_date <=> null, 1, 0), join_date asc;
if(condition, value_when_true, value_when_false)

加入时间为空时为 1,否则为 0,所以不为空的都排在前面,继续按加入时间升序,达到了预期效果。

limit 自身就支持 offset,下面两条命令运行效果一致。

limit 3, 3
limit 3 offset 3

随机排序,从来就没有想过该功能,可能服务器代码写多了,从来都是把结果集交给服务器语言二次处理。假若做个抽签功能,随机抽一名幸运用户,分别在数据库、服务器端处理看性能如何。

mysql> select id, user_name from sys_users order by rand() limit 1;
+------+-----------+
| id   | user_name |
+------+-----------+
| 7249 | 宋某某    |
+------+-----------+
1 row in set (0.00 sec)
#!/usr/bin/env ruby
require 'benchmark'

def massive_run(&block)
  1.upto(10) { yield }
end

Benchmark.bm(7)  do |x|
  x.report('server') do
    massive_run { User.all.sample }
  end
  x.report('sql') do
    massive_run { User.all.order('rand()').limit(1).first }
  end
end

output:
              user     system      total        real
server    2.860000   0.120000   2.980000 (  3.243038)
sql       0.010000   0.000000   0.010000 (  0.435641)

毫无疑问,在数据库端处理更高效,而且随着数据量的增大性能差距会更大,同时提醒一直追求码更少代码的自己,性能才是核心,但提高性能需要更专业、更全面的知识,只会一个解决方案,那它绝对不会是最佳实践方案。

日期操作的命令很丰富,有时间需要单独整理总结,作份简单的时间报告。

mysql> select
    ->   month(now()) as '月份'
    -> , monthname(now()) as '英文'
    -> , dayofmonth(now()) as '几号'
    -> , week(now()) as '几周'
    -> , dayofweek(now()) - 1 as '周几'
    -> , dayofyear(now()) as '已过'
    -> , timestampdiff(day, curdate(), '2017-01-01') as '还剩'\G
*************************** 1. row ***************************
月份: 11
英文: November
几号: 10
几周: 45
周几: 4
已过: 315
还剩: 52
1 row in set (0.00 sec)

模糊匹配使用 % 太多,很少想起单字符匹配符 _,匹配一位三个字的用户名,不要贸然使用 length 除非你确定用户名全英文或中文,一个中文占几个字符。

_ 匹配一个字符
% 匹配任何一个字符序列(包括空序列在内)

mysql> select user_name from sys_users where user_name like '___' limit 1;
+-----------+
| user_name |
+-----------+
| 张某某    |
+-----------+
1 row in set (0.01 sec)

mysql> select user_name, length(user_name) from sys_users limit 2;
+-----------+-------------------+
| user_name | length(user_name) |
+-----------+-------------------+
| 张某      |                 6 |
| 张某某    |                 9 |
+-----------+-------------------+
2 rows in set (0.00 sec)

难得整理这么全的组合命令,光标操作的命令不止适用于 mysql, linux/darwin terminal 都支持的,珍爱手指,爱护键盘,从使用快捷键做起。

读书 - 《MySQL 技术内幕(第4版)》之常用命令不平常_第2张图片
MySQL/Linux/Darwin 光标操作组合命令.png

你可能感兴趣的:(读书 - 《MySQL 技术内幕(第4版)》之常用命令不平常)