ดอกมะนาว

Posted in Photography | No Comments »

ปลูกมาสองปี จะได้ลูกแล้ว



นกธรรมดา

Posted in Photography | No Comments »



ยุบ รวม เลิก

Posted in Photography | No Comments »

พบว่าการแตกเป็น 3 บลอคมันอาจจะเยอะเกินไป สรุปว่า ยุบ Confession of a late night programmer กับ between the line มารวมกับบลอคนี้เลยนะครับ :3

โมบายของแมงมุม

Posted in Photography | No Comments »



Top 20+ MySQL Best Practices

Posted in CS, Web | No Comments »

ถอดความจาก http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/ เอาคร่าว ๆ นะ รูปประกอบ ไปดูได้จากเว็บต้นทาง ขี้เกียจทำรูปใหม่ และไม่อยาก repost/hot link รูปเขา

 

1. เขียน query ที่ทำให้ query cache ทำงานได้ดี

query cache คือระบบหนึ่งของ MySQL ที่จะช่วยลดโหลดของการ query โดยถ้าเรา query ข้อมูลหนึ่งครั้ง MySQL จะเก็บผลการ query ไว้ ดังนั้นถ้าเรา query ซ้ำเดิม (เช่นจากผู้ใช้คนอื่น แต่ใช้ query เดียวกัน) MySQL ก็สามารถเอาผลการ query ส่งไปให้ได้เลย โดยไม่ต้องไปค้นข้อมูลใหม่ ซึ่งทำให้การ query ทำงานได้ไว และลดโหลดของ server ได้เยอะ

ทีนี้ การเขียน query ก็มีผลต่อการ cache เหมือนกัน ลองดูตัวอย่าง

// query cache does NOT work

$r = mysql_query(“SELECT username FROM user WHERE signup_date >= CURDATE()”);

// query cache works!

$today = date(“Y-m-d”); $r = mysql_query(“SELECT username FROM user WHERE signup_date >= ‘$today'”);

อันบน cache ไม่ทำงาน เพราะเราใช้ CURDATE() ซึ่งเป็น function ที่ทำงานในระบบฐานข้อมูล ซึ่งทำให้ MySQL ต้อง execute query นี้เสมอ ซึ่ง function ในลักษณะนี้ก็เช่น NOW(), RAND() เป็นต้น ดังนั้น ถ้าเป็นไปได้ ควรหลีกเลี่ยงการทำงานในลักษณะนี้ เช่นในบรรทัดล่าง เราสร้าง string ของวันที่ปัจจุบันขึ้นมาก่อน แล้วค่อยส่งไป query เป็นต้น ทำให้ฐานข้อมูลเอา query นี้ไปเทียบได้เลย ต้องไม่ต้องไปทำงานภายในก่อน

2. ใช้คำสั่ง EXPLAIN เพื่อวิเคราะห์ SELECT query

พอเขียน query เสร็จ ควรใช้คำสั่ง EXPLAIN เพื่อวิเคราะห์ดูว่า query นั้นทำงานดีไหม และมีปัญหาที่เกิดจากโครงสร้งาของตารางหรือไม่ โดยเฉพาะถ้าเป็น query ที่มีการ join เยอะ ๆ ลองดูตัวอย่างในรูปของเว็บต้นทาง จะเห็นว่า การใช้คำสั่ง EXPLAIN จะแสดงให้เห็นถึงการ query ที่ไม่บน table ที่ไม่ได้สร้าง index key ที่เหมาะสม จึงทำให้จำนวน rows ที่เกี่ยวข้องมีสูง (7883  rows) ซึ่งพอใส่ index เข้าไป จำนวน rows ที่เกี่ยวข้องก็ลดลงอย่างมาก ซึ่งแน่นอนว่า การ query ก็จะไวขึ้น

3. ใช้ LIMIT 1 เมื่อต้องการ query แค่ record เดียว

อันนี้คงไม่ต้องการอะไรมาก คือถ้าเราต้องการข้อมูลแค่ record เดียว เช่นจะดูว่า มี account นี้ในระบบไหม หรือว่า มีรหัสนักศึกษานี้ในระบบไหม ให้ใส่ LIMIT 1 เสมอ เพราะในการ query ที่มี LIMIT 1 ถ้า MySQL พบข้อมูลตัวแรกแล้ว(ซึ่งก็คงมีแค่ตัวเดียว) มันก็จะหยุดการ query แล้วให้ผลคืนทันที ซึ่งต่างจากการไม่ใส่ LIMIT 1 ที่ MySQL จะต้องเช็คไปจนสุดตาราง ถึงจะหยุดการทำงานได้

4. ใส่ index สำหรับทุก field ที่ต้องการค้นหา

หลักการง่าย ๆ คือ ถ้ามี field ไหนไปโผล่ใน WHERE clause ของ SELECT จงใส่ index ให้มันเสีย เพื่อให้มัน search ได้ไวขึ้น

แน่นอน วิธีการนี้ใช้ได้กับกรณี exact match เช่น WHERE lastname like ‘pruet’ หรือว่า partial match เช่น WHERE lastname like ‘pr%’ เท่านั้น ถ้าต้องการทำ full text match เช่น WHERE lastname like ‘%pr%’ การทำ index จะไม่ช่วยอะไร ต้องไปใช้ MySQL fulltext search แทน ดังนั้น พยายามหลีกเลี่ยงการทำ full text match ด้วย

5. ใช้ข้อมูลประเภทเดียวกันใน column ที่เอามา join กัน และให้ทำ index ทั้งสองฝั่งด้วย

การ join เป็นการทำงานที่มี cost สูงมาก เพราะจะต้องมีการเอาข้อมูลจากสอง table มาเทียบกัน ในฐานข้อมูลที่ออกแบบไม่ดี การ join สอง table หมายถึงการจำนวน query ที่เท่ากับ จำนวน record ของทั้งสอง table มาคูณกัน ซึ่งเป็นการทำงานที่ช้ามากแน่นอน

สิ่งที่ต้องทำเพื่อหลีกเลี่ยงกรณีนั้นคือ ใน column ที่จะเอามา join กัน ให้ทำ index เสมอ และทั้งสอง column จะต้องเป็น data type เดียวกันเท่านั้น เพราะถ้าเป็นคนละ data type (เช่น DECIMAL กับ INT) แล้ว MySQL จะใช้ index ในการ join ไม่ได้

6. อย่าใช้ ORDER BY RAND()

ถ้าเขียนโค้ดแบบนี้

$r = mysql_query(“SELECT username FROM user ORDER BY RAND() LIMIT 1”);

MySQL จะต้องเรียกคำสั่ง RAND() ในทุก record ก่อน แล้วจึงเอา record มาเรียงกัน แล้วจึงดึงออกมาแค่หนึ่ง record ซึ่งแน่นอนว่าทำงานช้ามาก

ควรทำแบบนี้ดีกว่า

$r = mysql_query(“SELECT count(*) FROM user”);

$d = mysql_fetch_row($r);

$rand = mt_rand(0,$d[0] – 1);

$r = mysql_query(“SELECT username FROM user LIMIT $rand, 1”);

โค้ดยาวขึ้น แต่ทำงานเร็วกว่าเยอะ เพราะทำงาน rand แค่ครั้งเดียว (แถมทำนอก MySQL ด้วย) แล้วจึงไป query ออกมาแค่ record เดียว

7. หลีกเลี่ยง SELECT *

ถ้าต้องการข้อมูลเพียงไม่กี่ field ให้ระบุไปเลยว่าต้องการอะไร อย่าใช้ SELECT * เพราะยิ่งข้อมูลที่เราสั่งให้ดึงมาน้อย ก็จะลดโหลดทั้งในส่วนของการเรียกข้อมูลจาก harddisk และการส่งข้อมูลผ่าน network โดยเฉพาะถ้าต้องการข้อมูลเยอะ ๆ

8. ทุก table ต้องมี field id

ทุก table ควรจะมี field ที่เป็น PRIMARY KEY, AUTO_INCREEMENT, UNSIGNED ที่กำหนดให้เป็น id ซึ่งควรจะใช้ในการเชื่อม table เข้าด้วยกัน เพราะว่า การ query table ด้วย field id ในลักษณะดังกล่าว จะทำได้เร็วกว่าการ query โดยใช้ field ที่เป็น VARCHAR มาก (ต่อให้ทำ primary key/index แล้วก็ตาม)

9. ถ้าเป็นไปได้ พยายามใช้ ENUM แทนที่ VARCHAR

column แบบ ENUM ทำงานได้ไว และใช้พื้นที่น้อย ดังนั้นถ้ามีข้อมูลที่รู้อยู่แล้วว่ามีอะไรบ้าง และจำกัด เช่น พวก status ต่าง ๆ ก็ควรจะใช้เป็น ENUM แล้วระบุไปเลยว่ามีอะไรบ้าง

ข้อดีอีกอย่างคือ ลดการพิมพ์ผิดในกรณีของ VARCHAR ได้ เพราะถ้าพิมพ์ผมาผิด ENUM จะโวยวายทันทีว่าไม่มีข้อมูลแบบนี้

10. ใช้คำสั่ง PROCEDURE ANALYSE() เพื่อวิเคราะห์โครงสร้างตาราง

คำสั่ง PROCEDURE ANALYSE() มีประโยชน์มากในการวิเคราะห์โครงสร้างตาราง “และข้อมูลที่อยู่ด้านใน” ว่าเหมาะสมไหม เช่น ถ้าเราระบุให้ primary key เป็น INT แต่จริง ๆ แล้ว มีข้อมูลไม่กี่ตัว มันก็จะแนะนำให้ใช้ MEDIUMINT แทน ตัวอย่างเช่น ตารางที่เก็บรายชื่อของคณะต่าง ๆ ในมหาวิทยาลัยเป็นต้น

ถ้าใช้ phpmyadmin อยู่ จะมีคำสั่ง Propose table restructure อยู่ ซึ่งมันก็เรียก PROCEDURE ANALYSE() นี่แหละมาทำงาน

11. ใช้ NOT NULL เสมอ

ถ้าในตารางไม่ได้ใช้ค่า NULL ทำอะไร ซึ่งส่วนใหญ่ก็จะเป็นอย่างนั้น ก็ให้ระบุในค่า column ว่าเป็น NOT NULL แล้วใช้ค่า default จริง ๆ ไปเลย เช่น 0 สำหรับ INT และ string ว่าง สำหรับพวกข้อความต่าง ๆ  อย่างแรกคือ NULL column กินพื้นที่เยอะกว่าข้อมูลอื่น ๆ และเวลาเขียนโค้ดก็ต้องมานั่งเช็คอีกว่า มันจะ NULL ไหม

12. พยายามใช้ prepare ในการสร้าง query

โดยทั่วไป เราเขียน query ได้สองวิธี คือผ่าน prepare หรือว่า query เข้าไปตรง ๆ การใช้ prepare ข้อดีอย่างแรกคือ ช่วยป้องการ SQL injection ได้ เพราะมันจะทำการ filter ข้อมูลให้ก่อนหนึ่งชั้น ส่วนในแง่ของ performance นั้น ถ้าเกิดว่า query นั้นมีการใช้ซ้ำ ๆ หลาย ๆ ครั้ง เช่น การดึงข้อมูลมาสร้างเป็นตาราง การใช้ prepare จะช่วยลดโหลดของ MySQL ลงได้ เพราะ MySQL จะทำการวิเคราะห์ query นั้นแค่ครั้งเดียว

ข้อจำกัดของ prepare มีแค่อย่างเดียว คือ ใน MySQL version 5.0 ลงมา query ที่ใช้ผ่าน prepare จะไม่ถูก cache

13. ใช้ unbeffered query ในการ query ข้อมูลใหญ่ ๆ

ปกติ เวลาเรา query ข้อมูลจากฐานข้อมูล MySQL จะสร้าง buffer อันหนึ่งไว้เก็บ query result ทั้งหมด และเมื่อได้ result ทั้งหมดแล้ว ก็จะส่งข้อมูลใน buffer กลับมาให้ ซึ่งถ้าเรา query ข้อมูลขนาดใหญ่ จะส่งผลสองประการคือ 1. กินพื้นที่ memory ของ server 2. กว่าจะได้ข้อมูลกลับมา ก็ต้องรอให้ได้ข้อมูลครบก่อน ซึ่ง php ก็มีคำสั่ง mysql_unbuffered_query ให้ใช้ โดยจะไม่มีการรอให้ MySQL ค้นข้อมูลให้หมดก่อน แต่จะทยอยส่งมาให้เลย ด้วยวิธีการนี้ จะช่วยลดขนาด memory ที่ใช้ และเพิ่มความเร็วในการได้ข้อมูลแรก ๆ ด้วย

ข้อจำกัดคือ เราจะต้องอ่านข้อมูลทั้งหมด หรือสั่ง mysql_free_result ก่อนที่จะส่ง query ถัดไป และกลุ่มคำสั่งที่จัดการข้อมูลแบบทั้งก้อน เช่น mysql_num_rows และ mysql_data_seek จะใช้งานไม่ได้

14. เก็บ IP address เป็น UNSIGNED INT

ปกติ เรามักจะเก็บ IP address เป็น VARCHAR(15) ด้วยว่ามันมีจุดหลายจุด แต่จริง ๆ แล้ว เราสามารถเก็บมันเป็นตัวเลขแบบ UNSIGNED INT ด้วย ซึ่งกินพื้นที่น้อยกว่า index ได้ไวกว่า และเปรียบเทียบกันได้ไวกว่าด้วย วิธ๊การก็คือ สร้าง column ให้เป็น UNSIGNED INT แล้วใช้ function INET_ATON() และ INET_NTOA() ของ MySQL แปลงไป/แปลงกลับระหว่าง IP ADDRESS และ ตัวเลข เช่น ตัวอย่าง

$r = “UPDATE users SET ip = INET_ATON(‘{$_SERVER[‘REMOTE_ADDR’]}’) WHERE user_id = $user_id”;

ถ้าไม่อยากไปทำที่ระดับ MySQL ใน PHP ก็มีคำสั่ง ip2long() กับ long2ip() ให้ใช้

15. table แบบ Fixed-length  ทำงานเร็วกว่า

table ที่ทุก column มีขนาดจำกัด (fixed-length) จะเรียกว่า static หรือ fixed-length table ซึ่งชนิด column ที่”ไม่ใช่” fixed-length คือ VARCHAR, TEXT และ BLOB. ดังนั้น ถ้าสามารถหลีกเลี่ยง column ทั้งสามชนิดนี้ได้ จะทำให้ MySQL ทำงานกับ table นั้นได้ไวกว่ามาก เพราะว่าเวลา MySQL จะไปอ่านข้อมูลใน record หนึ่ง ๆ มันจะสามารถคำนวณตำแหน่งได้ง่าย (เช่น ตำแหน่งที่ต้องการ x ความยาว record) ซึ่งถ้า table มันไม่ fixed MySQL ก็ต้องวิ่ง seek หาตำแหน่งเอา หรือว่าไปดูจาก primary key

ถ้าจำเป็นต้องมี column ที่ไม่ใช่ fixed-length อาจจะใช้เทคนิค Vertical Partitioning ในการแยก column ที่ fixed กับ ไม่ fixed ออกจากกัน ลองดูข้อถัดไป

16. Vertical Partitioning

เป็นเทคนิคการแบ่ง table ออกเป็นหลายส่วน โดยการกระจาย column ออกไปเพื่อผลทางประสิทธิภาพ สมมติว่าเรามี table หนึ่งที่มี column ดังต่อไปนี้ table1(id, login, fname, lname, address, last_login)

ตัวอย่างที่ 1: เช่นถ้าเรารู้ว่า บาง column ไม่ได้ถูกใช้บ่อย ๆ (เช่น ที่อยู่) ก็สามารถแย่งออกไปเป็นอีก table หนึ่ง เช่นแยกเป็น  table1(id, login, fname, lname, last_login) และ table2(id, address) ซึ่งจะทำให้ table1 มีขนาดเล็กลงมาก และทำงานได้ไวขึ้น

ตัวอย่างที่ 2: ถ้าเรารู้ว่า บาง column มีการ update ถี่ ๆ ในขณะที่ column อื่นไม่มีการเปลี่ยนแปลง ก็อาจจะแยก column นั้นออกมา เพื่อให้ข้อมูลใน column อื่น ๆ คงอยู่ใน cache ได้ เช่นในตัวอย่าง last_login จะมีการ update ทุกครั้งที่ผู้ใช้ติดต่อ server ซึ่งการ update แต่ละครั้ง ก็จะทำให้ทั้ง record ถูก flush ออกไป เราจึงควรแบ่ง table ออกเป็น table1(id, login, fname, lname, address) และ t2(id, last_login) เพื่อให้การ update เกิดใน t2 เท่านั้น

ข้อควรระวังคือ พอแบ่งเป็น 2 table แล้ว ก็ไม่ควรให้มัน join กันบ่อย ๆ เพราะมันมีค่าใช้จ่ายสูง ถ้า column ที่ถูกแยกออกมา ต้องถูกใช้ร่วมกันบ่อย ๆ ก็ไม่ควรแยกตั้งแต่แรก

17. กระจาย DELETE กับ INSERT query ใหญ่ ๆ ออกมา

ถ้าเราจำเป็นต้องทำการ DELETE หรือ INSERT ข้อมูลจำนวนมาก ๆ บนเว็บที่กำลังทำงานอยู่ ก็ไม่ควรทำทีเดียวทั้งหมด เพราะมันจะไป lock table ของเรา แล้วทำให้ MySQL ไม่สามารถทำงานอื่น ๆ ได้ วิธีการคือ ค่อย ๆ กระจายทำทีละน้อย ๆ เช่น ลบทีละ 10,000 record แล้วหยุดไปสักพัก เพื่อให้ MySQL สามารถไปทำอย่างอื่น เช่น จัดการ SELECT query ที่คั่งค้าง ก่อนจะกลับมาลบต่อ ลองดูตัวอย่าง

while (1) {
mysql_query(“DELETE FROM logs WHERE log_date <= ‘2009-10-01’ LIMIT 10000”);
if (mysql_affected_rows() == 0) {
// done deleting
break;
}
// you can even pause a bit
usleep(50000);
}

จากตัวอย่าง เราลบไป 10,000 record แล้วก็หยุดพักไปครู่ใหญ่ โดยใช้คำสั่ง usleep ก่อนที่จะสั่งลบต่อ

18. column เล็ก ๆ ทำงานไวกว่า

สิ่งที่ทำให้ database ทำงานช้าสุดคือ harddisk ดังนั้น ถ้าเราสามารถลดปริมาณข้อมูลที่ต้องอ่านเขียนจาก harddisk ได้ ระบบเราก็จะทำงานเร็วขึ้น และประหยัดพื้นที่ harddisk มากขึ้น วิธีการหนึ่งก็คือ การใช้ชนิด column ให้เหมาะสม เช่น ถ้าเราคิดว่าจะมี record แค่ไม่กี่อัน ก็อย่าใช้ INT เป็น primary key แต่เปลี่ยนเป็น MEDIUMINT, SMALLINT หรือแม้แต่ TINYINT แทน เป็นต้น หรือว่าถ้าต้องการเก็บแค่วันที่ ก็ใช้ DATE แทนที่จะเป็น DATETIME เป็นต้น

19. ใช้ storage engine ให้ถูก

ใน MySQL มี storage engine หลักอยู่สองตัวคือ MyISAM กับ InnoDB ถ้าเอาง่าย ๆ ก็คือ MyISAM เหมาะกับโปรแกรมที่เน้นการ read เพราะว่ามันเป็น table-level locking เวลามีคนพยายาม insert/update/delete มันจะล๊อคทั้ง table ซึ่งทำให้ทำงานช้า ส่วน InnoDB สนับสนุน row-based locking ซึ่งทำให้การ insert/update/delete จะทำได้ไวกว่า MyISAM แต่ด้วยความซับซ้อนของมัน โดยทั่วไปสำหรับโปรแกรมเล็ก ๆ ที่เน้น SELECT (โดยเฉพาะ SELECT COUNT(*))  มันเลยจะทำงานกว่า MyISAM

20. พยายามใช้ ORM

ORM หรือ Object Relational Mapper นอกจากจะทำให้เขียนโปรแกรมง่าย เพราะว่าไม่ต้องไปยุ่งกับ SQL มากแล้ว ยังสามารถเพิ่มประสิทธิภาพของโปรแกรมได้ด้วย เพราะว่า ORM library โดยทั่วไป จะถูกเขียนให้มีประสิทธิภาพสูงอยู่แล้ว และมันยังทำ lazy loading ได้ด้วย นั่นคือ ถ้าเราสั่งเรียกข้อมูลมา แต่ไม่ได้ใช้ทันที ORM ก็จะไม่เรียกมากให้ทันทีเช่นกัน โดยจะเรียกมาเพื่อจะใช้

21. ระวังการใช้ Persistent Connection

โดยทั่วไป Persistent Connection จะช่วยลด overhead ในการเชื่อมต่อได้ เพราะว่าเราไม่ต้องทำการสร้างการเชื่อมต่อทุกครั้งที่ต้อง query ข้อมูล แต่เนื่องจาก connection มันไม่ถูกปิด ดังนั้นมีโอกาสที่ connection ของ MySQL จะเต็มเพราะว่า Apache มัน reuse connection ของ child process จนทำให้ connection ปิดไม่ได้นั่นเอง ตัวอย่างเช่น ถ้า MySQL ใช้ table-locking แล้ว php script ก่อนหน้านี้ ไม่ได้ปลดล๊อคก่อนที่จะปิดตัว script ตัวถัดมา จะถูก lock ทันที เพราะว่า ตราบใดที่ connection ยังไม่ถูกปิด MySQL ก็ต้องคง lock อันนั้นไว้อยู่

คำแนะนำคือ อย่าใช้

 

 

 

 

ใช้ GMail ให้สนุก ต้องเข้าใจ Label

Posted in Life, Web | No Comments »

เนื่องมาจากมีน้องสาวท่านหนึ่งทวีตว่า

Screenshot (30)

ทำให้รู้ว่าหลาย ๆ คนยังไม่เข้าใจหลักการของ label ใน GMail ถึงแม้ว่าจะเปิดบริการมาแล้วเกือบสิบปี

ถ้าให้อธิบายสั้น ๆ สำหรับคำถามของน้องเขาก็คือ ทุกอย่างใน GMail เป็น label และทั้ง inbox/folder ทั้งหลาย ก็เป็น label ทั้งนั้น

หรืออีกในหนึ่ง ใน GMail ไม่มี inbox/folder นั่นเอง

 

 

ก็ขอย้อนอดีตนิดหนึ่ง อีเมลแต่ดั้งเดิมนั้น ได้แนวคิดมาจากการส่งจดหมายจริง ๆ (หรือที่มักจะเรียกกันว่า Snail Mail) ที่ว่าพอจดหมายมาถึง เราก็จะเอาจดหมายมาจัดแยก เช่นถามผู้รับ หรือตามหัวข้อ ซึ่งช่องหรือสิ่งที่ใช้เก็บจดหมายนั้น ภาษาอังกฤษก็จะเรียกว่า Folder ดังนั้น ในโปรแกรมอีเมลดังเดิม ก็จะมี folder ไว้ให้ เพื่อให้ผู้ใช้ระบุว่า จะเก็บอีเมลของตัวเองที่ไหน เช่น จดหมายเจ้าจะอยู่ใน Inbox ซึ่งถ้าอ่านแล้ว คิดว่าเป็นเรื่องเกี่ยวกับงาน เราก็จะย้ายจาก Inbox ไปใส่ Business เป็นต้น แล้ววันหลัง พอเราอยากจะหาจดหมายฉบับดังกล่าว ก็จะเขาไปดูใน Business แล้วอาจจะสั่งให้มันเรียงตามวันส่ง เรียงตามผู้ส่ง หรือตามหัวข้อ ซึ่งไม่ว่าจะด้วยวิธีการใด ขบวนการทั้งหมด ก็เลียนแบบมาจากการส่งจดหมายจริง ๆ

 

แต่จดหมายต่างจากอีเมลตรงที่ว่า มันอยู่ได้เพียงที่เดียว แต่อีเมลเป็นข้อมูลอีเล็คทรอนิกส์ มันไม่จำเป็นต้องอยู่ที่เดียวก็ได้ นั่นคือที่มาของระบบ label ใน GMail

 

label ใน GMail นั้น สามารถถูกำหนดให้กับอีเมลไหนก็ได้ และอีเมลหนึ่ง ๆ จะมีหลาย label ก็ได้ ซึ่งจะทำให้การจัดการอีเมลมีความยืดหยุ่นมากขึ้น ลองดูรูปด้านล่าง

Screenshot (23)

ด้านซ้ายมือที่เขียนไว้ว่า A ในโปรแกรมอีเมลดั้งเดิมจะเป็นรายการของ folder แต่ใน GMail รายการดังกล่าวคือรายการของ label ที่เราเลือกให้มาแสดง ดังนั้น ถ้าเรากดเลือกตรง Starred แล้ว GMail ก็จะแสดงอีเมลทั้งหมดที่มี label Starred กำหนดอยู่ หรือถ้าเรากดเลือก Important เขาก็จะแสดงรายการอีเมลที่มี label Important กำหนดอยู่ ดังนั้นถ้าอีเมลใด มี label มากกว่าหนึ่งอัน มันก็จะไปโผล่ในหลาย ๆ ที่ได้

Screenshot (24)

ซึ่งรายการ label ด้านซ้ายนี้ เราสามารถระบุได้ว่า จะให้แสดงอะไรบ้าง โดยระบุใน Settings ซึ่งพอเข้าไป จะเห็นได้ชัด จากรูปที่เขียนไว้ว่า B ว่า นี่ไม่ใช่ folder list แต่เป็น label list โดยเราสามรถที่จะเลือก show hide หรือ show if unread ได้ โดย show if unread หมายความว่า ถ้ามีอีเมลที่ยังไม่ได้อ่าน และมี label ดังกล่าวอยู่ ชื่อ label ดังกล่าวก็จะแสดงใน label list

Screenshot (25)

นอกจากนั้น เรายังทำ label แบบ nested ได้ด้วย เช่น ในรูป ตรงที่เขียนไว้ว่า C/D จะเห็นว่า 261102 จะอยู่ภายใต้ CPE ดังนั้น อีเมลได้ที่ถูกกำหนด label 261102 ก็จะได้รับ label CPE ไปโดยอัตโนมัติ ซึ่งเราสามารถทำ nested แบบหลายชั้นได้

Screenshot (26)

ปัญหาหนึ่งของการทำ label หรือ tag คือการที่เราขี้เกียจใส่ label/tag ซึ่ง GMail ก็ใช้วิธีการให้เราสร้าง filter ได้ โดยถ้าอีเมลใดตรงกับ filterก็จะสามารถกำหนด Action ต่าง ๆ ที่รวมถึงการใส่ label ได้ เช่นในรูปด้านบน ตรงที่เขียนไว้ว่า E ผมสร้าง filter ที่บอกว่า ถ้ามีอีเมลใดที่มาจาก mailing list ที่จัดการโดย tccc.list.cs.columbia.edu ก็จะไม่ต้องเอาใส่ใน Inbox และให้ใส่ label Conf เข้าไปเลย

หมายเหตุ: ใน GMail จะมี label ของ system อยู่สองสามตัวที่จะทำงานโดยอัตโนมัติ เช่น All Mail จะเป็น label ที่กำหนดให้กับอีเมลทุกอัน และไม่สามารถลบได้ Inbox จะเป็น label ที่ถูกกำหนดให้กับอีเมลที่เพิ่งได้รับโดยอัตโนมัติเป็นต้น

Screenshot (27)

การสร้าง filter ก็ทำไม่อยาก เพราะมันเป็น rule base แบบ match/action ธรรมดา โดยขั้นแรกเราจะกำหนดเงื่อนไขก่อนว่า อีเมลได้จะถูกกรองโดย filter นี้ ซึ่งอาจจะมาจากชื่อผู้ส่ง หัวข้อ หรือว่าเนื้อความก็ได้ (ซึ่งก็เป็นเหตุให้ Google ถูกบ่นว่าแอบอ่านอีเมลของผู้ใช้อยู่) ตามรูปด้านบน ตรงช่อง F

Screenshot (28)

เมื่อกำหนด match condition แล้ว ก็จะมากำหนด action ซึ่ง มีมากมาย ตามรูปด้านบน ช่อง G ซึ่งถ้านั่งดูดี ๆ เกือบทั้งหมด เป็นการกระทำที่เกี่ยวข้องกับ label ทั้งนั้น

ฟหกดฟหกด

หรือว่าถ้าอยากกำหนด label เอง ก็ทำได้ โดยที่ toolbar ด้านบน จะมีรูป label/tag อยู่ ก็กดเลือกตรงนั้น แล้วมันจะแสดงตามพื้นที่ H ก็กดเลือก label ที่ต้องการได้เลย ใช้ได้ทั้งในหน้าอ่านจดหมาย และหน้าแสดงรายการจดหมาย

ซึ่งถ้าเราใช้ label จนคล่องแล้ว ก็อาจจะพลิกแพลงได้ เช่น ใช้ทำ GTD เป็นต้น

GMail ได้เปลี่ยนวิธีการจัดการอีเมลให้เข้ากับโลกสมัยใหม่มากขึ้น ในเมื่อไม่มีความจำเป็นต้องใส่อีเมลเข้าไว้กับ folder ใด folder หนึ่งอีกต่อไปแล้ว ดังนั้น ก็ขอให้ลืมไปเลยว่า ต้องแยกจดหมายโดยใช้ folder แต่เปลี่ยนไปใช้การกำหนด label ให้กับจดหมายแทน แล้วแยกจดหมายตาม label เอา ซึ่งไม่ใช่เฉพาะเรื่อง label เท่านั้น ที่ GMail เปลี่ยนวิธีการจัดการอีเมล แม้แต่การจัดการรายการอีเมล GMail ก็เปลี่ยนจากการ sort เป็นการ search แทน นั่นคือแทนที่เราจะต้องเรียงจดหมายตามผู้ส่ง ตามวันที่ส่ง หรือตามหัวข้อ เพื่อหาอีเมลที่ต้องการ GMail ก็บอกเราว่า ฉันจะเรียกตามวันที่ได้รับเท่านั้น ส่วนถ้าต้องการหาอีเมลอะไร ก็ search เอาสิ ซึ่งการใช้ label ก็เพื่อให้การ search ทำได้อย่างมีพลังอีกด้วย

ทั้ง label และการจัดการรายการอีเมลโดยการ search ก็มาจากธรรมชาติของบริษัท Google ที่เป็น search engine company นั่นเอง

วัดห่างหน้าบ้าน

Posted in Life | 1 Comment »

เดือนก่อน ที่บ้านผม(ตรงที่ลูกศรสีเหลืองชี้อยู่ คลิกที่รูปเพื่อดูรูปใหญ่ได้) เห็นคนแปลกหน้ามาเต็มไปหมด มีเสียงเหมือนกำลังถางป่า แถมอีกวันมีกองไฟโผล่ขึ้นกลางป่าตรงข้ามบ้าน พร้อมกับเต้นท์สีน้ำเงินอีกหลายหลัง ด้วยความสงสัยเลยเดินเข้าไปถาม ได้ความว่า ชาวบ้านช่างคำหลวง ซึ่งเป็นหมู่บ้าน(ชาวบ้าน)ที่ติดกับหมู่บ้าน(จัดสรร)ผม กำลังถางป่าเพราะแถวนั้นมีวัดห่างอยู่ ก็ทำให้นึกขึ้นได้ว่า ในป่าตรงข้ามบ้านมีกองอิฐและศาลพระภูมิหักกองอยู่ใต้ต้นไม้ คิดไว้ว่าคงเป็นแค่จอมปลวกใหญ่ที่ชาวบ้านเอาพระเศียรหักหรือศาลพระภูมิเก่ามาทิ้ง ไม่คิดว่าจะเป็นวัดห่าง

หลายคนอาจจะสงสัยว่าวัดห่างคืออะไร วัดห่างเป็นคำเมือง ถ้าคำไทยก็คือวัดร้างนั่นเอง ในประเทศไทย จะมีวัดร้างอยู่เป็นจำนวนมาก ซึ่งส่วนใหญ่ก็จะอยู่ในรูปของกองอิฐกองดิน ที่ชาวบ้านมักจะเอาศาลไปวางไว้ แถว ๆ บ้านผม เท่าที่รู้ก็คือ 4 ที่ และมีที่ไม่รู้อีกเยอะ
1243922_10151670476909582_1929040839_o

ชาวบ้านนอกอีกว่า พ่อหลวง กับ ท่านวัดช่างคำหลวง(ลูกศรสีแดง) พาชาวบ้านมาหักล้างถางพง แล้วอาจจะสร้างศาลอะไรสักอย่าง (ลูกศรสีเขียว) ด้วย

พอคุย ๆ ไป ชาวบ้านก็เล่าให้ฟังอีกว่า สาเหตุที่อยู่ดี ๆ ชาวบ้านมาช่วยกันหักร้างถางพงก็เพราะว่าช่วงก่อน มีชาวบ้านหลายคน เห็นดวงไฟแดง ๆ ลอยจากบริเวณนี้ เข้าไปในหมู่บ้าน ก็คงเริ่มกลัวกัน แต่มีคนเฒ่าคนแก่บอกว่า ถ้าเห็นให้ยกมือไหว้แล้วบอกว่า ถ้าเป็นวิญญาณดี ก็ขอให้ลอยขึ้น แล้วดวงไฟก็ลอยขึ้นจริง ๆ ชาวบ้านก็เลยคาดเดาว่า น่าจะเป็นธาตุที่อยู่ที่วัดนี้ พ่อหลวงวัดช่างคำหลวง ก็เลยระดมชาวบ้านมาปัดกวาดทำความสะอาด และนิมนต์พระมาทำพิธี พร้อมกับตั้งศาลพระพุทธรูป ตามรูปด้านล่าง
WP_20130901_001

 

ซึ่งศาลที่ว่านี้ อยู่ตรงประตูห้องนั่งเล่นพอดี เรียกว่าถ้าเปิดประตูห้องนั่งเล่น มองข้ามถนนไป ก็จะเห็นศาล นับว่า อุ่นใจดีนัก

เรื่องสุดท้ายที่ชาวบ้านเล่าให้ฟังคือ บริเวณนี้ชาวบ้านเรียกว่า สันเพด ซึ่ง สัน ก็คือพื้นที่ ๆ ที่ดินดอน หรือที่มีกองดินอยู่ ในที่นี่ก็คือกองอิฐของวัดร้างที่มีดินถม มันก็จะเป็นสันดินขึ้นมา ส่วน เพด ก็คือ เปรต นั่นเอง คงไม่ต้องอธิบายอะไร โดยชาวบ้านบอกว่า ปกติจะไม่มีใครเข้ามาในบริเวณนี้เลย ตอนที่หมู่บ้านผมมาซื้อที่ดินแถวนี้ ชาวบ้านก็ขอให้สงวนพื้นที่ตรงนี้ไว้เป็นที่สาธารณะ ดังนั้น หมู่บ้านก็เลยตัดแปลงที่ดินให้ล้อมพื้นที่ตรงนี้เอาไว้ ก็สงสัยอยู่ว่า ใครจะกล้ามาสร้างบ้าน

มีคนถามอยู่เหมือนกันว่า ไม่กลัวเหรอ ก็ถ้าเราไม่ได้ทำอะไรเสียหาย ไม่ได้เอาขยะไปทิ้งไม่เคยเอาหมาไปขี้เรี่ยราด ทำอะไรก็ยกมือไหว้บอกไป ทั้งเจ้าที่ที่เป็นคนและไม่ใช่คน เขาก็คงเอ็นดูเราอยู่บ้างแหละ ผมอยู่นี่มาสามปีกว่าละ ก็ไม่ได้รู้สึกอะไรเลย ไม่เคยเจอเหตุการณ์ใด ๆ ทั้งสิ้น คนที่มาบ้านก็ไม่เคยเจออะไร เงียบสงบดี

โดยส่วนตัวแล้ว ผมกลัวขโมยมากกว่ากลัวผีนะ 😛 แล้วถ้ามีวัดห่างอยู่หน้าบ้านแล้วขโมยไม่กล้วขึ้นบ้านเพราะกลัวผี ผมว่าก็โอเคเลยนะ 😀

Tiny orange

Posted in Photography | No Comments »



night traveler

Posted in Photography | No Comments »



Office 365 University

Posted in Review, Work | No Comments »

หลังจากใช้ iPad เป็นเครื่องหลัก พกไปทำงานอยู่สักพักก็พบว่า มันไม่ค่อยสะดวกเท่าไหร่ ด้วยสามเหตุผลคือ 1. Microsoft Word 2. Microsoft Excel 3. Microsoft Powerpoint นั่นคือชีวิตของผมได้เปลี่ยนมาเป็น Document Engineer ในภาคกลางวันอย่างเต็มตัวแล้ว T_T และ iPad ก็ยังมีข้อจำกัดอื่น ๆ เช่น เขียนโปรแกรมไม่ได้ เป็นต้น จึงถึงเวลาต้องเปลี่ยนไปใช้ตัวอื่นแทน โดยผมมี Criteria ดังนี้

  1. แบตอึด อย่างน้อยต้องได้เกิดหนึ่งวันแบบสบาย ๆ เนื่องจากพอใช้ iPad ซึ่งแบตอึดมาก ใช้ได้เกิน 1-2 วันแน่ ๆ ซึ่งก็ต้องแลกกับประสิทธิภาพแน่นนอน เพราะพวก Core i3/5/7 อยู่ได้ไม่ถึงครึ่งวันแน่ ๆ
  2. ต่อ 3G ได้ อันนี้ก็มาจาก iPad เช่นกัน ทำให้เสียนิสัย ต้องต่อเน็ตตลอดเวลา
  3. ใช้งาน Microsoft Office ได้ ซึ่งก็หมายความว่า ต้องเป็น Windows ถึงแม้ว่าจะมี Libre/OpenOffice ให้ใช้บนแพลตฟอร์มอื่น ๆ แต่ถ้าต้องทำงานเอกสารเยอะ ๆ ร่วมกับพวก Microsoft Office แล้ว จะพบว่าปวดหัวมาก จึงยังไม่ใช่ตัวเลือกที่ดีนัก
  4. เป็น Tablet ได้ สามารถเอาไปใช้บนโซฟาได้

ด้วยเหตุผลเหล่านี้ จึงเป็นที่มาของการถอย Acer W511 มาใช้ พร้อมกับ Windows 8 ซึ่งตัวนี้ ใช้งานได้ตามข้อ 1, 2, 4 ด้านบนแบบสบาย ๆ

ส่วนข้อ 3 นั้น ก็มีอยู่สองสามทางเลือกคือ 1. ใช้ของเถื่อน 2. ซื้อ Office แบบกล่อง 3. ซื้อ Office 365 เมื่อลองเช็คดูแล้ว Office 365 นั้น ผมสามารถซื้อแบบ Office 365 University ซึ่งสนนราคาก็คือ 2,199 บาท สำหรับสี่ปี ความหมายก็คือ ผมไม่ได้ซื้อ Office ขาดแบบซื้อกล่อง แต่ซื้อแบบ Subscription ซึ่งถ้าหมดสี่ปี ผมก็ต้องจ่ายอีกรอบ

หลายคนอาจจะไม่ชอบรูปแบบนี้ เพราะว่าไม่ได้ซื้อขาด แล้วต้องเสียเงินเรื่อย ๆ แต่ในอีกแง่หนึ่ง การซื้อแบบ Subscription ก็มีข้อดีคือ ถ้า Microsoft ออก Office รุ่นใหม่ ผมก็จะได้ใช้รุ่นใหม่น้นทันทีโดยไม่ต้องจ่ายเงินซื้อใหม่ และจากประวัติ จะเห็นว่า Microsoft ได้ออกรุ่นใหม่ดังนี้ 2001 -> 2003 ->2007 -> 2010 -> 2013 ซึ่งถ้าดูแบบนี้ ผมน่าจะได้ใช้รุ่นใหม่อีกรุ่นหนึ่ง น่าจะไม่ 2015 ก็ 2016 และถ้ามาคำนวณค่าใช้จ่ายแล้ว 2,200 บาท ใช้ได้สองเครื่อง ไม่ว่าจะเป็น Windows หรือ Mac และใช้ได้ 4 ปี ก็คือถ่าโคตรคุ้มนะครับ คุ้มกว่าโปรแกรมเถื่อนอีก เพราะว่าได้ Update อัตโนมัติตลอดเวลา ได้ Skydrive เพิ่ม ได้ Skype minute อีกนิดหน่อย

พอใช้งานไป ก็พบว่ามันคือ Office 2013 ที่ทำ Integrate เพิ่มกับ Skydrive ซึ่งก็สะดวกมาก สำหรับคนที่ใช้คอมพ์หลายเครื่อง และถ้าใช้ Windows Phone ก็จะยิ่งสะดวกไปใหญ่ ตัว Office ก็ทำงานได้ดีตามที่ควรจะทำงานได้ ยิ่ง ๆ หลัง ๆ ใช้ Word, Office, Excel ทุกวัน ก็ยิ่งเห็นว่า มันดีกว่าไปนั่งทำบน Google Docs เยอะ เพราะถึงแม้เน็ตจะล่ม ก็ยังทำงานได้

สรุปว่า คุ้มครับ