Thursday, November 30, 2006

How to Get Referrals

Seth Godin:

Yes, we know that referrals are the very best way to grow your business.

And we know that asking for a referral is both scary but apparently the most effective technique.

And we know that excellent service is a great place to start.

Given the no-win nature of most referrals, you need to reset your expectations and consider a few ideas:
  • Make it easy for someone to bring up what you do (by changing the nature of the service or product).
  • Give your best customers something of real value to offer to their friends (a secret menu, a significant gift certificate). Once you do that, not giving that gift to a friend feels selfish.
  • Paying me to refer you rarely works, because you’re not just asking for a minute of my time, you’re asking me to put my credibility on the line.
  • Understand that low-risk referrals happen more often than high-risk ones, and either figure out how to become a low-risk referral or embrace the fact that you have to be truly amazing in order to earn one.

and

  • Be worthy. Not just in the work you do, but in your status in the marketplace. I’m far more likely to refer someone with a back story, someone who’s an underdog, or relatively unknown. That’s why saying "thank you" in deeds (not so much in words) goes such a long way.

การ Design Form สำหรับ Web Application

การ Design Form สำหรับ Web Application ที่ดี จะช่วยให้ User เข้าใจถึงโครงสร้างของกลุ่มข้อมูล การจัดหมวดหมู่ ความเชื่อมโยงกันของแต่ละ Field มีจุดที่น่าสนใจไล่สายตา ทำให้ User สามารถเรียนรู้ Step ในการกรอก Input ได้ด้วยตนเอง

ในการ Design Form นั้นควรคำนึงถึงเรื่องหลัก ๆ ดังนี้
  1. การจัดวาง Layout ของ Field ต่าง ๆ ใน Form และ Label เช่น เรียงแนวตั้ง แนวนอน ชิดซ้ายขวา
  2. การใช้ Visual Element ต่าง ๆ ประกอบ เพื่อให้ดูง่ายขึ้น เช่น สีพื้น กล่อง Panel Font เส้นขอบ เส้นแบ่ง
  3. Action ที่จะทำกับ Form ได้ เช่น ปุ่มหลัก (Submit, Save) ปุ่มรอง (Cancel, Reset) หรือ Link ต่าง ๆ
ดังรูปตัวอย่าง จากบทความด้านล่าง

  1. Web Application Form Design
  2. Web Application Form Design Expanded

ตัวอย่างในการวาง Layout แบบต่าง ๆ

  1. แบบตามใจ Programmer
  2. แบบแนวตั้ง
  3. แบบหลาย Column
  4. แนวนอน
  5. แบบกำหนดระยะ Margin
  6. แบบใช้ Fieldset

Wednesday, November 29, 2006

ทำไมเราต้องทำ Performance Tuning?




ก็เพราะมันช้า ไม่ทันใจ

คำถามคือ มันช้าเพราะอะไร ความช้าเกิดได้จากหลายสาเหตุ หลายที่ ไล่ตั้งแต่ ระดับ Low Level เช่น Disk I/O ไปจนถึง ระดับ High Level เช่น Database Design และการเขียน SQL Query



สาเหตุความช้าที่พบบ่อย ๆ มีดังนี้




  1. Design Database ไม่ดี หรือดีเกินไป
    ในการออกแบบฐานข้อมูล จะมีการ Normalize Table แตกตารางเป็นหลายตาราง ให้มีความซ้ำซ้อนน้อยที่สุด เพื่อให้สะดวกต่อการ Insert, Update, Delete แต่เมื่อเราต้องการดึงข้อมูล (Select) จากตารางต่าง ๆ ขึ้นมาใช้ ทำให้ต้อง Join, Subquery หรือแม้กระทั่ง Union จากหลายตารางมากเกินไป เพื่อให้ได้ผลลัพท์ที่ต้องการ ซึ่งทำให้ช้าเกินกว่าที่รับได้ ถ้าข้อมูลมีจำนวน Record มากขึ้นเกินระดับหนึ่ง

    ในการออกแบบ Database ควร Normalize ตารางให้มีความซ้ำซ้อนน้อยที่สุด และควรคำนึงถึง การใช้งานของ User ด้วย ว่าส่วนใหญ่แล้ว User ใช้งานข้อมูลนั้น ๆ อย่างไร เช่น ใช้ทีละ 1 Record หรือทีละหลาย Record ต้องดูเปรียบเทียบหรือไม่ ข้อมูลเป็นข้อมูลที่ขึ้นกับเวลาหรือไม่ ข้อมูลอะไรใช้บ่อยใช้ไม่บ่อย ช่วงเวลาที่ใช้งานมากที่สุด ข้อมูลมีความหลายหลายหรือซ้ำกันแค่ไหน เมื่อเราเข้าใจการใช้งานของ User แล้ว ถึงจะเป็นเรื่องเทคนิคการออกแบบ เช่น การสร้าง Index, การใช้ View, Materialized View, Cost-Based Optimizer (CBO), Data Partitioning, Data Replication, Aggregation Table for Decision Support System, การใช้ค่า Null


  2. Application Tuning
    สาเหตุอันดับหนึ่งของความช้า เนื่องมากจากการเขียน SQL ไม่ถูกต้อง ทำให้เกิดการ Full Table Scan (ไล่ดูข้อมูลทั้งตารางทีละ Record ตั้งแต่ 1 ไปถึง 100), การจัดเรียงข้อมูล (Sorting) เพื่อ Matching หรือแสดงผลทุกครั้งที่ Query, Join หลาย Table เกินไป, ดึงข้อมูลมากเกินกว่าที่จะแสดงผลให้ User ดูได้ในคราวเดียว, Caching, การใช้ Like, การใช้ OR, Union, Order by, Distinct, Group by, Implicit Cast ที่ไม่เหมาะสม, ไม่ใช้ Bind Variable


  3. Memory Tuning
    ระบบจัดการฐานข้อมูล (Database Management System : DBMS) ต้องการหน่วยความจำ (Memory) ที่เพียงพอ เพื่อใช้งานการทำงานต่าง ๆ เช่น shared_pool, buffer cache, log buffer ตัวอย่างเช่นเราสามารถดูอัตรา Buffer Hit Ratio ถ้าค่ายิ่งมากยิ่งเร็ว แสดงว่าข้อมูลที่เราต้องการถูก Load อยู่บน Memory แล้วไม่ต้องไปหาจากใน Harddisk ใหม่ แต่ถ้าค่าน้อยแสดงว่า Memory น้อยเกินไป หรือมีปัญหาเรื่องการ Design อื่น ๆ ทำให้ DBMS ไม่สามารถใช้ข้อมูลที่อยู่บน Memory ได้ต้องไปดึงจาก Harddisk มาใหม่

    การตั้งค่าให้ข้อมูลบางอย่างที่ใช้บ่อยถูก Load อยู่บน Memory ตลอดเวลาตั้งแต่เริ่ม ทำให้ป้องกันปัญหาข้างต้นได้ระดับหนึ่ง


  4. I/O Tuning
    ระบบฐานข้อมูลไม่สามารถทำงานได้เร็ว ถ้าข้อมูลอยู่บน Disk ที่ช้า หรือ Network ที่ช้า และควรมีการบริหารจัดการ Data File, Log File, Temp File และ Block Size ที่เหมาะสม


  5. Eliminate Database Contention:
    ใช้ Tools ตรวจหา Lock, Latch และ Wait ภายใน Database และกำหนด Schedule Batch Job ให้ไม่กระทบกับงานขณะ Peak Working Hours.


  6. OS Tuning
    ตรวจสอบ และ Tune OS, CPU, I/O, Memory Utilization โดยประสานงานกับผู้ดูแลระบบ และศึกษาเกี่ยวกับ OS Platform ที่ใช้อยู่ เช่น Windows, Linux, Unix, Solaris

Tuesday, November 28, 2006

Patterns การออกแบบ Tools การค้นหา

Patterns การออกแบบ Tools การค้นหาข้อมูลใน Application

1. ควรมีการ Save ค่า Criteria ที่ใส่ไปทั้งหมด เพื่อนำมา Load ค่า Default ใช้ค้นหาในคราวหลังเพื่อไม่ต้องกรอก, เลือกใหม่ ทุก ๆ ครั้ง ในงานประจำวัน สำหรับแต่ละ User, Role, Organization
2. ควรมีปุ่ม Reset ค่า Criteria เพื่อนำไปสู่สถานะเริ่มต้น Search เงื่อนไขอื่น ๆ หรือใช้ [Reset] Template
3. ความมากเกินไปของจำนวน Item ใน List ขึ้นอยู่กับคุณภาพของ Label ด้วยว่าถ้า Order ออกมาแล้ว สามารถหาได้ง่ายหรือไม่ และปกติเลือกทีละหลายอันหรือไม่ แต่ไม่ควรเกิน 20 สำหรับ Label ที่หายาก และ 100 สำหรับ Label ดี
4. ในบาง Field ที่เป็น Nullable ควรมี Option [None] ให้เลือกเพื่อค้นหา Record ที่มี Field นั้น ๆ ยังไม่มี Value ใด ๆ
5. บางทีมีเงื่อนไขที่เป็น Negative เช่น ให้ไม่แสดง Entity ที่มีสถานะใดบ้าง เช่น Closed, Rejected.
6. Form Search ควร Collapse ได้ และมี Basic Search (Field ที่ค้นหาบ่อย ๆ), Advance Search (ทุก ๆ Field)

Patterns การออกแบบการแสดงผลลัพธ์การค้นหา

การแสดงผลลัพท์การค้นหา
1. แสดงผลเป็น Grid ถ้าเป็นการค้นหาข้อมูลประเภท Master ที่ Label (NAME, CODE) เป็น นัยสำคัญ ให้แสดง Order by Name หรือ Code Accending
2. แสดงผลเป็น Grid ถ้าเป็นการค้นหาข้อมูลประเภท Transaction ที่มีการสร้างใหม่ หรือเปลี่ยนแปลงบ่อย มีเวลาเป็นนัยสำคัญ ให้แสดง Order by Last Update Descending
3. ถ้าเป็น Field Number ให้ Align right, Number Formatted (Integer, Seperator, Floating point, Percentage, Zero padding, Money)
4. ถ้าเป็น Field Text ให้ Align left
5. ถ้าเป็น Field Datetime, Date, Time ให้ Align right, Locale Formatted
6. มีการให้ User เลือก Field และ ทิศทางในการ Order by
7. มี Paging แสดงตำแหน่ง Record ที่แสดงอยู่, จำนวน Record ที่แสดงอยู่ และจำนวน Record ทั้งหมด ที่ค้นหาได้
8. มีการ Navigate ระหว่าง Page
9. มีให้เลือกระบุ จำนวน Record ทีแสดงใน 1 Page เช่น 1, 5, 10, 25, 50, 100, Etc.
10. สามารถเลือก Column ที่จะแสดงใน Grid Search Result ได้
11. สามารถ Export Search Result เป็น Excel, CSV, Printer Friendly ได้
12. มีการ Filter by QBE

Monday, November 27, 2006

Patterns การออกแบบ Form ค้นหา

ถ้าเป็น text ควร เป็น textbox ใช้งานโดย
1. ไม่ใส่ (blank) คือ [Any]
2. ใส่คือ like %aaa% หรือ
3. ให้ลูกค้าใส่ wildcard (*) เองได้ เช่น aaa*, *aaa, *aaa* แต่ไม่รับ aa**aa
4. ค่า Default คือ blank
5. Trim ค่าก่อนนำไปหา
6. หาแบบ Case-insensitive

ถ้าเป็นตัวเลข ควรเป็น Range เป็น textbox 2 ช่อง คือ a, b
1. ถ้ากรอกทั้งสองช่อง คือ between a, b
2. ถ้ากรอกช่องแรกอย่างเดียว > a
3. ถ้ากรอกช่องสองอย่างเดียว < b
4. ค่า Default คือ a, b เป็น blank

ถ้าเป็น Date, Datetime ควรเป็น pop-up calendar หรือ Drop down 3 อัน (Year, Month, Day) 2 ชุดเป็น range คือ a, b
1. ค่า Default คือ a, b เป็น blank
2. ถ้ากรอกทั้งสองช่อง ให้ใช้ between a, b
3. ถ้ากรอกช่องแรกอย่างเดียว > a
4. ถ้ากรอกช่องสองอย่างเดียว < b
5. เมื่อเลือก Default a เป็นวันที่ 1 ของเดือนนั้น ๆ
6. เมื่อเลือก Default b เป็นวันที่ ณ ปัจจุบัน
Note. การค้นหาส่วนใหญ่ไม่จำเป็นต้องใช้ Time นอกจากจำเป็นจริง ๆ หรือ Transaction เยอะจริง ๆ

ถ้าเป็น List ที่เลือกได้ 1 รายการ จากจำนวน Item ไม่มาก
1. ใช้ Dropdown List (Single Select, Order by Label)
2. Option แรกเป็น [Any] ที่ถูกเลือกโดย Default

ถ้าเป็น List ที่เลือกได้ 1 รายการ จากจำนวน Item มาก (1)
1. ให้แสดงเป็น Grid 1 Row
2. Record แรกเป็น [Any]
3. เลือกโดย Pop-up Window
4. มี Pop-up Window มี Search Form รูปแบบเหมือนดังเอกสารนี้
5. สามารถเลือกได้ 1 Record แล้วกับไปเติมใน Grid
6. ในกรณีไม่มีที่ต้องการ สามารถสร้าง Entity ใหม่จากใน Pop-up ได้

ถ้าเป็น List ที่เลือกได้ 1 รายการ จากจำนวน Item มาก (2)
1. ให้แสดงเป็น textbox ไม่ใส่คือ any
2. ใส่ค่ามานำไป เป็น criteria กับ Field CODE or NAME or Etc. โดยเงื่อนไข like %aaa% หรือ
3. ให้ลูกค้าใส่ wildcard (*) เองได้ เช่น aaa*, *aaa, *aaa* แต่ไม่รับ aa**aa
4. ค่า Default คือ blank

ถ้าเป็น List ที่เลือกได้หลายรายการ ที่มีจำนวน Item ไม่มาก
1. ใช้ List box (Multiple Select, Order by Label)
2. Option แรกเป็น [Any] ที่ถูกเลือกโดย Default

ถ้าเป็น List ที่เลือกได้หลายรายการ ที่มีจำนวน Item มาก (1)
1. ให้แสดงเป็น Grid
2. Record แรกเป็น [Any]
3. เลือกโดย Pop-up Window
4. มี Pop-up Window มี Search Form เหมือนดังเอกสารนี้
5. สามารถเลือกได้หลาย Record แล้วกลับไปเติมใน Grid
6. ในกรณีไม่มีที่ต้องการ สามารถสร้าง Entity ใหม่จากใน Pop-up ได้

ถ้าเป็น List ที่เลือกได้หลายรายการ ที่มีจำนวน Item มาก (2)
1. ให้แสดงเป็น textbox ไม่ใส่คือ any
2. ใส่ค่ามานำไป เป็น criteria กับ Field CODE or NAME or Etc. โดยเงื่อนไข like %aaa% หรือ
3. ให้ลูกค้าใส่ wildcard (*) เองได้ เช่น aaa*, *aaa, *aaa* แต่ไม่รับ aa**aa
4. ค่า Default คือ blank

ถ้าเป็นเงื่อนไขแบบ User Related
1. เหมือนกับ List
2. มี Option ให้เลือก [Myself] เป็น Option ที่ 2 ต่อจาก [Any]
Note. อาจจะเป็น My Group, My Organization, My ...

ถ้าเป็นเงื่อนไขแบบ Time Related
1. ค้นหาโดยเป็น List ระยะเวลาย้อนหลัง จนถึงปัจจุบัน เช่น 1Hr ago, 2Hrs ago, ...1Day ago, 7Days ago, 1Month ago, ... etc.
2. ค้นหาโดยเป็น List ช่วงเวลาที่สนใจ เช่น Today, Yesterday, This Week, Last Week, This Month, Last Month, This Quarter, This Year, This Fiscal Year
3.

ถ้าเป็นเงื่อนไขแบบ No. of Relationship
1. มี Field การเลือกรูปแบบของ Relationshop เช่น Child of, Related to, Duplicated of, Has duplicate, Parent of, Etc.
2. มี Field ให้กำหนด ตัวเลข จำนวน Entity ที่ Related ด้วย ในรูปแบบดังเอกสารนี้

การค้นหาแบบ Full-text Search
1. มี Textbox ให้ใส่อะไรก็ได้ จะนำไปค้นหา ทุก ๆ Field และ Sub-Entities แสดง Entity ที่ใกล้เคียงที่สุดขึ้นมาอันดับต้น ๆ

การค้นหาแบบ Quick ID
1. มี Textbox ให้ใส่ ID ของ Entity แล้วถ้า Match (Exactly) ให้แสดง Detail ของ Entity นั้น ๆ ไม่ต้องแสดง Search Result

ถ้าเป็นเงื่อนไขแบบ Structured List, Nested List, Multi-List หรือ Tree
...

ถ้าเป็นเงื่อนไขแบบ Context Related
...