2017/8/28
rails 直接執行 SQL 且避免 sql injection
markdown
以下是一個 sql update 的範例程式:
```
old_value = ActiveRecord::Base.sanitize(old_value)
new_value = ActiveRecord::Base.sanitize(new_value)
updated_at = ActiveRecord::Base.sanitize(Time.current)
results = ActiveRecord::Base.connection.execute(
"update table
set field=#{new_value},
updated_at=#{updated_at}
where field=#{old_value}"
)
```
2017/8/22
sql 的 where in 查詢效能問題
markdown
問題:當我想要where in 一個很大的陣列,或者子查詢,該怎麼寫呢?
在[Performance issue in update query](https://stackoverflow.com/questions/24647503/performance-issue-in-update-query)提到:
各種方法,從慢到快:
* 打N次query,用 where = 每次只查一個值
* 打1次query,用 where in 或是 where exists
* 使用 join values
* (當資料量足夠大時) 建立一個暫時表並且加上索引,然後使用join
在[SQL: When it comes to NOT IN and NOT EQUAL TO, which is more efficient and why?](https://stackoverflow.com/questions/17037508/sql-when-it-comes-to-not-in-and-not-equal-to-which-is-more-efficient-and-why/17038097#17038097)提到,
各種 query 從慢到快:
* where field = v1 and field = v2 and ... and field = vn
* where field in (v1,v2...vn)
* 使用 CTE 做 values join 或 values subquery 都比前面快100倍以上
* 暫存表 join 跟 暫存表 subquery 跟 CTE values join 差不多快 (也許是資料量大小的問題)
CTE:Common Table Expression 是一種臨時定義一個 table 的語法,只能在下一個 select 使用,文章中有提到:
```
WITH excluded(item) AS (
VALUES('item1'), ('item2'), ('item3'), ('item4'),('item5')
)
SELECT *
FROM thetable t
WHERE NOT EXISTS(SELECT 1 FROM excluded e WHERE t.item = e.item);
```
其中的 WITH AS 就是建立 CTE 的語法
在[Optimizing a Postgres query with a large IN](https://dba.stackexchange.com/questions/91247/optimizing-a-postgres-query-with-a-large-in)中也提到了:
* IN 最慢
* 使用 join values 是很好的
* 資料量太大就建立暫存表,並且加上index,再去join
結論:使用 with values 建立 CTE 再拿去做 join 應該是最簡單又有效的作法。
2017/8/21
在 blogger 貼漂亮 code 的方法(使用 markdown 和 prettyprint)在使用 < 符號時產生的問題
前情提要:http://etrex.blogspot.tw/2017/03/blogger-code-markdown-prettyprint.html
在使用 element.innerHTML 時,會將 < 字元轉換為 < 再輸出
然後 markdown 再度把 < 轉換為 &lt;
所以最後顯示為 <
為了解決這個問題,必須找到一個方法,去取得最原始的html
查了一下發現似乎無法簡單的達成。
https://stackoverflow.com/questions/15419209/getting-raw-text-content-of-html-element-with-html-uninterpreted
https://stackoverflow.com/questions/5998443/how-to-get-raw-html-from-string-in-jquery
結論:必須在取得innerHTML之後做一次html decode
但 html decode 的成本太高,可能只要處理< > &就好。
在前一篇文章裡 Jo 的留言中,提出的解法為:
在使用 element.innerHTML 時,會將 < 字元轉換為 < 再輸出
然後 markdown 再度把 < 轉換為 &lt;
所以最後顯示為 <
為了解決這個問題,必須找到一個方法,去取得最原始的html
查了一下發現似乎無法簡單的達成。
https://stackoverflow.com/questions/15419209/getting-raw-text-content-of-html-element-with-html-uninterpreted
https://stackoverflow.com/questions/5998443/how-to-get-raw-html-from-string-in-jquery
結論:必須在取得innerHTML之後做一次html decode
但 html decode 的成本太高,可能只要處理< > &就好。
在前一篇文章裡 Jo 的留言中,提出的解法為:
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.6.4/showdown.min.js"></script> <script> var converter = new showdown.Converter(); var posts = document.querySelectorAll(".post-body"); //定義要替換的字元 var insteadWords = { ">": ">", "<": "<", "&": "&" }; //loop每一篇文章 Array.prototype.forEach.call(posts, function(el, i){ /*有在開頭找到 markdown 字眼才處理,把整個文章取出來替換成 html * 從文章取出內容時,應該有某些字元早就被轉換過,但因為是寫 markdown,根本不需要轉 * 所以再寫一段程式把某些特定的字轉回來,暫時只定義了 3 組 */ if(el.innerHTML.indexOf("markdown") <= 1){ var origin = el.innerHTML; origin = origin.replace("markdown",""); for (var key in insteadWords){ origin = origin.replace(new RegExp(key,'g'),insteadWords[key]); }; //先把特殊字元轉回來再作 markdown 的轉換 el.innerHTML = converter.makeHtml(origin); } }); var pres = document.querySelectorAll("pre"); Array.prototype.forEach.call(pres, function(el, i){ el.classList.add("prettyprint"); }); </script> <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=sunburst"></script>
2017/8/20
2017/8/10
以誘導代替強迫
當你想要別人去做某件事,你可能會採取一些手段去做,比方說:
金錢攻勢:「給你錢,快點做」
人情攻勢:「拜託啦~求你~」
情緒勒索:「你不做,我就去死」
勒索:「你不做,我就讓你死」
...
這些手段大概可以被區分為兩類,強迫與誘導。
強迫:對方不甘願的去做了某件事,他會說:「你為什麼要逼我啊~****~」
誘導:對方心甘情願去做了某件事,他會說:「感謝有你,有你真好」
強迫的手段通常不太容易達成效果,而且會把人際關係弄差。
例1:
你看到一個正妹,你跟他說「我想跟你交往,跟我在一起好嗎?」
正妹看你一臉肥宅樣,拒絕了。於是你:
1: 死纏爛打
2: 把自己變成高富帥
選1,很簡單可以執行,但是效果不好,強求的感情也不會幸福。
選2,這是一條困難的路,但是效果會很好,就算這個正妹真的不喜歡你,下一個正妹會喜歡你的。
你必須要思考,要怎麼樣讓別人打從心裡想做那些你想要他們做的事情。
例2:
你覺得醫學系超棒der,你想要讓你的小孩成為醫生,於是你:
1: 跟小孩說:「不管怎樣你就是要給我念醫學系,以後當醫生,乖,聽爸媽的話,以後你會懂der」
2: 在家裡弄一個環境放了一堆醫學相關的東西,提供各種機會讓小孩能接觸醫學方面知識,一段時間之後他會以為他有醫學方面的天賦。
選1,結果小孩醫學系念完不當醫生,或者自殺,慘。
選2,你盡力了,就算最後小孩沒去當醫生,但他有值得更好的。
有一個寓言故事,叫做北風與太陽,我直到今天才知道這個寓言在講什麼。
金錢攻勢:「給你錢,快點做」
人情攻勢:「拜託啦~求你~」
情緒勒索:「你不做,我就去死」
勒索:「你不做,我就讓你死」
...
這些手段大概可以被區分為兩類,強迫與誘導。
強迫:對方不甘願的去做了某件事,他會說:「你為什麼要逼我啊~****~」
誘導:對方心甘情願去做了某件事,他會說:「感謝有你,有你真好」
強迫的手段通常不太容易達成效果,而且會把人際關係弄差。
例1:
你看到一個正妹,你跟他說「我想跟你交往,跟我在一起好嗎?」
正妹看你一臉肥宅樣,拒絕了。於是你:
1: 死纏爛打
2: 把自己變成高富帥
選1,很簡單可以執行,但是效果不好,強求的感情也不會幸福。
選2,這是一條困難的路,但是效果會很好,就算這個正妹真的不喜歡你,下一個正妹會喜歡你的。
你必須要思考,要怎麼樣讓別人打從心裡想做那些你想要他們做的事情。
例2:
你覺得醫學系超棒der,你想要讓你的小孩成為醫生,於是你:
1: 跟小孩說:「不管怎樣你就是要給我念醫學系,以後當醫生,乖,聽爸媽的話,以後你會懂der」
2: 在家裡弄一個環境放了一堆醫學相關的東西,提供各種機會讓小孩能接觸醫學方面知識,一段時間之後他會以為他有醫學方面的天賦。
選1,結果小孩醫學系念完不當醫生,或者自殺,慘。
選2,你盡力了,就算最後小孩沒去當醫生,但他有值得更好的。
有一個寓言故事,叫做北風與太陽,我直到今天才知道這個寓言在講什麼。
2017/8/4
訂閱:
文章 (Atom)