[SQL]having的使用時機

一般來說having常常搭配group by一起使用

假設有一張articles的資料表,共有10筆資料如下:

現在有個情境是「取得文章分類的流覽次數超過5且依照次數由高到低排序」

若是一個初學SQL的新手又不認識having的用法,可能會寫成這樣:

SELECT
	category_id,
	SUM(view_cnt) AS view_cnt
FROM
	`articles`
WHERE
	view_cnt > 5;
GROUP BY
	category_id
ORDER BY
	view_cnt DESC

乍看之下好像是對的,但其實這個SQL變成「取得文章流覽次數超過5的文章分類流覽次數並依照次數由高到低排序」,這是因為WHERE會套用在GROUP BY之前,所以在GROUP BY前會把文章瀏覽次數小於5的排除掉才進行GROUP BY,這個結果不是我們要的!

正確的SQL是利用GROUP BY搭配HAVING

SELECT
	category_id, SUM(view_cnt)  AS total_view_cnt
FROM
	`articles`
GROUP BY category_id
HAVING total_view_cnt > 5
ORDER BY total_view_cnt DESC

如果不想使用HAVING的話也可以利用子查詢的方式,但比較不建議

SELECT * FROM (
SELECT
	category_id, SUM(view_cnt)  AS total_view_cnt
FROM
	`articles`
GROUP BY category_id
ORDER BY total_view_cnt DESC
) A
WHERE A.total_view_cnt > 5;

因為查兩次,多此一舉

Advertisements

[Linux]利用nslookup指定DNS查詢Domain

總該有個前因

今天遇到一個突發狀況,DNS(Domain Name Server)上的子網域設定突然失效導致客戶無法使用子網域下的服務

在查明是DNS的問題之前,腦海中有閃過一個指令是可以用來指定DNS查詢Domain

後來詢問Google大神才喚醒我的記憶

在解決這個突發狀況的時候nslookup幫了我很大的忙

正好趁這個機會重溫一下nslookup這個指令

我記得第一次接觸它是在大學修網路概論課的時候

一句話說明nslookup的作用

nslookup是用來查詢網路上的DNS

我們都知道網路上有非常多DNS,常見的有:

中華電信

  • 168.95.1.1
  • 168.95.192.1

Google

  • 8.8.8.8
  • 8.8.4.4

我們在本機可以設定要去哪一台DNS查詢Domain

那如果在不更動本機的DNS設定下,可以使用別台的DNS來查詢Domain嗎?

答案是Yes, 對!就是利用nslookup

如何使用nslookup

nslookup提供interactive和non-interactive兩種模式來查詢

non-interactive

nslookup google.com #使用本機設定的DNS查詢google.com這個domain
nslookup google.com 8.8.8.8 #到8.8.8.8這台DNS查詢google.com這個domain

interactive

nslookup
> server 8.8.8.8 #指定DNS
> google.com 8.8.8.8 #查詢google.com這個domain

以上兩種方式都有人在用,看個人習慣

自己比較偏好第二個

[vue.js] v-model.lazy的使用時機

vue.js的v-model directive是一個非常方便的東西

由於v-model是使用two way data binding

所以只要修改就會立即顯示

但有時候我們也會希望v-model不要這麼快就幫我們sync

尤其是使用者在填寫表單(form)的時候

我們會希望使用者填完之後才觸發

這時候就可以使用v-model.lazy

加上.lazy這個內建的modifier讓data sync在change event事件後才去處理

vuejs v2:

<input v-model.lazy="name">

參考來源:

https://vuejs.org/v2/guide/forms.html#lazy

javascript ES6 的箭頭函式(arrow function)

javascript ES6的arrow function是方便的syntax sugar,可以幫助我們寫出更簡潔的js code

在arrow function還沒出現前,針對特定element綁定事件大致會像這樣:

document
.getElementById('my-btn')
.addEventListener("click", function(e) => {
alert('before es6');
});

將以下的anonymous function替換成arrow function的寫法:

document
.getElementById('my-btn')
.addEventListener("click", (e) => {
alert('arrow function');
});

只有一個參數時,可省略括號:

document
.getElementById('my-btn')
.addEventListener("click", e => {
alert('arrow function');
});

若只有一行statement時,可以省略大括號

document
.getElementById('my-btn')
.addEventListener("click", e => alert('arrow function'));

其實從以上的範例還真看不出來arrow function強大的地方XD
頂多就只有省略function這個關鍵字和大括號而已
但其實這只是arrow function的其中一種寫法
更方便的用法還在後頭~

arrow function讓你不用.bind(this)

我們都知道javascript的this是一個很tricky的東西
和Java、C#、PHP等OOP的語言的this所代表的涵意是不太一樣的

言規正傳,如果不使用arrow function在setTimeout的callback中要取得object instance的this
就要使用.bind把object instance的this綁定給setTimeout的callback

function UserModel(id) {
    this.id = id;
    this.name = '';

    setTimeout(function() {
	this.name = 'from remote';
    }.bind(this), 1000);
}

var userModel = new UserModel(1);
console.log(userModel.name);

但如果使用arrow function就簡單的多了,不需要加上.bind(this)

function UserModel(id) {
    this.id = id;
    this.name = '';

    setTimeout(() => {
	this.name = 'from remote';
    }, 1000);
}

var userModel = new UserModel(1);
console.log(userModel.name);

結論

ES6的arrow function可以讓我們少寫一些程式碼
更容易處理this的指向,進而寫出更簡潔易懂的程式碼

[PHP] 為什麼應該使用MySQL Native Driver(mysqlnd)來取代MySQL Client Library(libmysqlclient)

還記得以前第一次自己架設LAMP開發環境的時候,就已經注意到安裝有這兩個package了

但那時候還不曉得有何差別,只記得書上叫我裝php5-mysql就照著裝XD

前陣子碰到一個需要安裝mysqlnd才能解決的問題,正好趁這個機會來瞭解一下差別

MySQL Native Driver is a replacement for the MySQL Client Library (libmysqlclient)

在PHP文件的myslqnd章節內一開頭就說明了mysqlnd是用來取代libmysqlclient

為何PHP官方會建議使用mysqlnd?

 

mysqlnd是屬於PHP Project的一部份

不像libmysqlclient是使用MySQL license,mysqlnd是使用PHP license這也避免了一些因為license所衍生的問題(看看前陣子Oracle告Google的新聞就知道為什麼了!)

mysqlnd的功能比libmysqlclient還多

從PHP 5.3.0開始mysqlnd library 已經是內建在PHP的library,mysqlnd提供的一些功能像是query caching、lazy connections、SSL這些在libmysqlclient的沒辦法用的

詳細差異請參閱Library feature comparison

mysqlnd的效能比libmysqlclient還好

由於mysqlnd是用C寫的PHP extension,所以它是使用PHP memory management system也支援PHP memory limit和memory_get_usage(),安裝mysqlnd可以使用memory_get_usage()來追蹤記憶體的使用情形,而是在libmysqlclient是不可能的,因為libmysqlclient要使用C語言的function malloc(),在官網有舉一個例子

One example of the memory efficiency is the fact that when using the MySQL Client Library, each row is stored in memory twice, whereas with the MySQL Native Driver each row is only stored once in memory.

libmysqlclient在儲存每一筆資料row到memory的時候會存兩次

而mysqlnd只會存一次

 

參考來源:

http://php.net/manual/en/mysqlnd.overview.php

http://php.net/manual/en/mysqlinfo.library.choosing.php

http://php.net/manual/en/intro.mysqlnd.php

https://dev.mysql.com/downloads/connector/php-mysqlnd/

讓Git untrack已經進repository的檔案

初學Git的人都知道,可以使用.gitignore來忽略檔案

但如果這個檔案已經進到repository了呢?

一旦檔案已經commit到repository,只把該檔案加到.gitignore的話是沒有用的

還要將那個檔案變成untracked的狀態,這時候可以使用

git rm --cached i-am-a-file-name

將檔案untrack後,並commit這次的異動

再把檔案加到.gitignore

就大功告成了

關於git config的層級

安裝完git後為了方便性,需要初始化一些設定

這個動作可以透過git config來完成

git config有分為三種不同的層級,以下是由高到低的優先權

 

1.檔案庫層(–local參數可省略)的設定會在.git資料夾中的config檔

$ git config --local user.name "Tony Ciou"

 

2.使用者層(global)的設定會在家目錄的.gitconfig檔案內

$ git config --global user.name "Tony Ciou"

 

3.系統層(system)的設定會在/etc/gitconfig檔案內

$ git config --system user.name "Tony Ciou"

 

一般來說安裝git後至少會初始化以下的設定

$ git config --global user.name "YOUR NAME"
$ git config --global user.email "YOUR EMAIL ADDRESS"
$ git config --global core.editor "YOUR CODE EDITOR"