畢業(yè)多年抑党,問題驅(qū)動型學習模式包警,學習不挑食,現(xiàn)在成功的成為前端底靠、后端害晦、移動端的全棧,不苛骨,是全干程序員篱瞎。
問題驅(qū)動學習,導致學習碎片化痒芝,知識體系不專一俐筋,用時方學,再用其他工具時繼續(xù)學严衬,邊學邊忘澄者。很難想像自己曾外包一年到家電子商務公司做報表數(shù)據(jù)整理,報表涉及到 ibm cognos、microsoft reporting service粱挡、webfocus赠幕、qlickview、ireport询筏,客戶部分第三方數(shù)據(jù)通過 excel 導入榕堰,當時使用 vb 編程做各種關(guān)聯(lián)、篩選嫌套、聯(lián)動匯總逆屡,感嘆 excel 的強大,但此刻感覺好遙遠踱讨,遠得把我再放回工位會無從下手魏蔗。
天天掛在口頭的縮寫單詞,用得太多已忘記它的原意痹筛,很慶幸自己愚笨的大腦里還尚存自知莺治,看到略感陌生的單詞全拼統(tǒng)統(tǒng)放入筆記,工作多年的事實永遠是自黑的依據(jù)帚稠。
SQL: structured query language 結(jié)構(gòu)化查詢語言
RTF: rich text format 富文本格式
RDBMS: relational database management system 關(guān)系數(shù)據(jù)庫管理系統(tǒng)
常用命令的常用用法不值得放在筆記中谣旁,是的,此篇筆記就是按這個思路整理的翁锡,白紙黑字蔓挖,為日后扇臉留下些痕跡。
操作數(shù)據(jù)庫的第一步馆衔,自是開門進屋,再翻箱倒柜的找東西怨绣;登錄操作目前沒有發(fā)現(xiàn)不平常的用法角溃,參數(shù)可指定主機、端口篮撑、編碼類型减细、數(shù)據(jù)庫、是否加載數(shù)據(jù)等功能赢笨。
$ 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.
上面這段提示語不能再眼熟未蝌,熟到?jīng)]有完整的閱讀過整體文字,若是告訴你里面提示了幾個不常用的命令茧妒,你能找到幾個或用到過幾個萧吠?
sql 語句語法是以分號 ;
結(jié)尾,也可以使用 \g
桐筏,雖然感覺分號更簡潔纸型,但必需承認在閱讀此書前我是無知的。
mysql> select now()\g
+---------------------+
| now() |
+---------------------+
| 2016-11-09 23:26:18 |
+---------------------+
1 row in set (0.00 sec)
\c
清空當前的輸入,解釋很簡單狰腌,平時使用 ctrl + u
組合命令清空輸入的信息除破,但試想若 sql 語句過長分行輸入時,其間發(fā)現(xiàn)輸入有誤放棄已輸入命令琼腔,如何做瑰枫?無知的我是直接輸入分號 ;
表示 sql 語句結(jié)束再回車,任由報錯信息橫行丹莲。其實輸入 \c
才是干凈光坝、優(yōu)雅的解決方案。
mysql> select
-> now()\c
mysql>
sqlite3 支持結(jié)果集行列轉(zhuǎn)換圾笨,一直以來以為是 sqlite3 的特性教馆,還是我所待的井太深,結(jié)尾符使用 \G
表示結(jié)果集行列轉(zhuǎn)換擂达。
mysql> select now()\G
*************************** 1. row ***************************
now(): 2016-11-09 23:31:19
1 row in set (0.00 sec)
業(yè)務邏輯復雜時在多個數(shù)據(jù)庫中切來切去土铺,亂忙一通后,還記當前是那個數(shù)據(jù)庫嗎板鬓?之前我的做法悲敷,想繼續(xù)在那個數(shù)據(jù)庫操作就再執(zhí)行 use the-db-i-want
,這樣操作過于暴力俭令,查看一下當前所在數(shù)據(jù)庫省時省力后德。
mysql> select database();
+------------+
| database() |
+------------+
| NULL |
+------------+
1 row in set (0.00 sec)
查看表結(jié)構(gòu)只會 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
數(shù)據(jù)庫中翻來倒去的各種不利索悟耘,其實查看表結(jié)構(gòu)的命令本身就支持過濾功能落蝙,解鎖更多用法請查看 api。
mysql> desc sys_users 'user_name';
mysql> show columns from sys_users like '%name';
mysql> show fields from sys_users like '%name';
數(shù)據(jù)庫一般不會很多暂幼,數(shù)據(jù)表上百倒是稀松平常筏勒,有些功能相近的數(shù)據(jù)表名完全沒有讓人想去記的欲望,只記得一些關(guān)鍵字旺嬉,如何去過濾管行?曾經(jīng)自以為找到了救星 page
命令,但過于啰嗦鹰服,show
命令原天然支持病瞳。
mysql> show databases like '%bi';
mysql> show tables like '%bases';
平時按行 values()
插入數(shù)據(jù)揽咕,也可以按列 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)
雖然百分之八十的運算符都有用過蛹头,就是因為它全必須收下。
數(shù)據(jù)過濾比較 null
時都是使用 is
戏溺,查看上述運算符可以知道宇宙飛船是相當有用的渣蜗,日常可以不用旷祸,但閱讀別人代碼時至少不應該怔住耕拷。
where name is null;
where name <=> null;
where name is not null;
where not (name <=> null);
使用 if
命令排序,場景比如: 按加入時間升序查看用戶列表托享,那些未賦值的行就會排前面骚烧,使用 where 過濾則會顯示部分結(jié)果集,如何做到顯示所有用戶闰围,并按加入時間升序赃绊,加入時間為 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碧查,所以不為空的都排在前面,繼續(xù)按加入時間升序校仑,達到了預期效果忠售。
limit
自身就支持 offset
,下面兩條命令運行效果一致迄沫。
limit 3, 3
limit 3 offset 3
隨機排序档痪,從來就沒有想過該功能,可能服務器代碼寫多了邢滑,從來都是把結(jié)果集交給服務器語言二次處理。假若做個抽簽功能愿汰,隨機抽一名幸運用戶困后,分別在數(shù)據(jù)庫、服務器端處理看性能如何衬廷。
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)
毫無疑問摇予,在數(shù)據(jù)庫端處理更高效,而且隨著數(shù)據(jù)量的增大性能差距會更大吗跋,同時提醒一直追求碼更少代碼的自己侧戴,性能才是核心宁昭,但提高性能需要更專業(yè)、更全面的知識酗宋,只會一個解決方案积仗,那它絕對不會是最佳實踐方案。
日期操作的命令很豐富蜕猫,有時間需要單獨整理總結(jié)寂曹,作份簡單的時間報告。
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)
模糊匹配使用 %
太多回右,很少想起單字符匹配符 _
隆圆,匹配一位三個字的用戶名,不要貿(mào)然使用 length
除非你確定用戶名全英文或中文翔烁,一個中文占幾個字符渺氧。
_ 匹配一個字符
% 匹配任何一個字符序列(包括空序列在內(nèi))
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 都支持的蹬屹,珍愛手指侣背,愛護鍵盤,從使用快捷鍵做起哩治。