go to http://oracle.in.th

Wednesday, June 30, 2010

Oracle Application Express 4.0 พร้อมดาวน์โหลดแล้ว!!!


สำหรับคนที่เล่นตัว Oracle Application Express หรือ APEX อยู่นั้น เห็นข่าวนี้คงจะดีใจนะครับ เพราะว่าทาง Oracle ได้ออกตัว Oracle Application Express Release 4.0 มาให้ดาวน์โหลดกันไปใช้แล้ว หลังจากที่เคยออกมาให้ทดลองเล่นกันในแบบ Oracle Application Express 4.0 Early Access ให้ติดใจกันก่อน แล้วค่อยปล่อยของจริงในวันนี้นี่เอง

สนใจดาวน์โหลดตัว Oracle Application Express 4.0 คลิก ที่นี่ เลยครับ
ถ้าได้ทดสอบกันแล้ว เป็นอย่างไร อย่าลืมมาแชร์ประสบการณ์กันนะครับ :)

อ้างอิง
ข้อเขียนนี้ช่วยฉัน:  

Monday, June 28, 2010

Oracle APEX #1

Oracle Application Express (Oracle APEX) คืออะไร

Oracle APEX เป็นเครื่องมือพัฒนา web application ที่รวดเร็วสำหรับฐานข้อมูล Oracle. เพียงใช้ผ่าน web browser กับประสบการณ์การเขียนโปรแกรมที่จำกัด แต่เราสามารถพัฒนาและปรับการใช้งาน Application อย่างรวดเร็วและปลอดภัยได้

Oracle APEX มีการพัฒนาอย่างต่อเนื่อง เป็นตัวเลือกในฐานข้อมูล Oracle และไม่มีค่าใช้จ่าย ชื่อเดิมของ Oracle APEX นั้นคือ HTML DB และรองรับ Oracle Database 10.2.0.3 ขึ้นไป รวมถึง Oracle Database 10g Express Edition (Oracle XE)

การติดตั้ง Oracle APEX จะเป็นส่วนหนึ่งของการติดตั้ง Oracle Database 11g แต่ถ้าต้องการเวอร์ชั่นใหม่ล่าสุด สามารถดาวน์โหลดได้ฟรีจาก Oracle Technology Network (OTN)

Browser Based เพียงเราใช้ Web browser กับประสบการณ์การเขียนโปรแกรมที่จำกัด แต่เราสามารถพัฒนา Application ได้เพียงไม่กี่นาที ช่วยให้เราสามารถพัฒนาโปรแกรมบนคอมพิวเตอร์ได้เพียงใช้ web browser

Rapid Application Development (RAD) ด้วยตัวช่วยที่ง่ายและการเขียนโปรแกรมแบบ declarative(ไม่มี code ถูกสร้าง หรือ compile) ช่วยให้เราสามารถสร้างรายงานและโปรแกรมรับค่าได้อย่างมีประสิทธิภาพ เราสามารถสร้างรายงานจาก spread sheet (upload) หรือจาก table และ view ในฐานข้อมูล. Oracle
APEX ยังประกอบไปด้วย SQL Workshop ในการสร้าง และจัดการกับ Object ฐานข้อมูล เพื่อสนับสนุนโปรแกรม

การพัฒนาโปรแกรมแบบ Declarative

บน APEX การใช้งานจะเป็นแบบ declarative นั้นหมายถึงว่าเราไม่ต้องสร้าง หรือคอมไพล์

ตัวอย่างของโปรแกรม declarative ใน Oracle APEX:
Forms
จากตัวช่วยเราสามารถสร้าง Form จาก table หรือ stored procedure. เมื่อสร้าง Form จาก table ตัวช่วยจะสร้างตัวจัดการกับการ insert, update และ delete ให้อัตโนมัติ. เมื่อเราสร้าง Form เราสามารถจัดเรียงรูปแบบข้อมูลอย่างรวดเร็ว ในแบบที่เราต้องการ

Interactive Reports
ผู้พัฒนาสามารถเลือก table หรือ กำหนด SQL statement. ดังนั้นเราสามารถจำกัดความสามารถของผู้ใช้ (เช่น ปิดการ download หรือไม่อนุญาติบางคอลัมน์ ด้วยการซ่อนไว้ ) ถ้าต้องการ

Session State
Oracle APEX จัดการกับสถานะการเข้าใช้งานในฐานข้อมูล ผู้พัฒนา application สามารถเข้าถึง session state ด้วยการใช้ substitution และ SQL bind variable syntax.

องค์ประกอบ APEX
Application Builder
- Database Applications - ผู้พัฒนา Application ใช้ตัวช่วยเพื่อประกอบงานเป็น page ขึ้นมา โดยแต่ละ page อาจจะเป็น report, chart, map, calendar, form เป็นต้น
- Websheets - ช่วยให้ผู้ใช้สามารถจัดการข้อมูลที่มีโครงสร้างและไม่มีโครงสร้าง โดยไม่ต้องการความช่วยเหลือจากผู้พัฒนา

SQL Workshop - ใช้ในการจัดการและดูแล object ในฐานข้อมูล

Team Development - ช่วยจัดการวงจรของการพัฒนาโปรแกรม มีการติดตามและการจัดการ ของ application ฟีเจอร์, to do, bugs และความคิดเห็นผู้ใช้

Administration - APEX workspace ถูกแยกออกมาเพื่อการพัฒนา ดังนั้นส่วนนี้จะใช้ในการจัดการกับ workspace ประกอบด้วย services(ร้องขอ schema, storage,...), ผู้ใช้, สังเกตุการณ์ เป็นต้น

*** ปัจจุบัน APEX เวอร์ชัน 4.0 ***
ตัวอย่างเช่น Install APEX 4.0 with Embedded PL/SQL Gateway

อ้างอิง
http://apex.oracle.com
ข้อเขียนนี้ช่วยฉัน:  

Saturday, June 26, 2010

JSF 2.0 Navigation Rules

ฟังคนเขียนพร่ามก่อนเริ่มเนื้อหากันหน่อยครับ ล่าสุดก็ให้เพือนที่เก่ง(กว่าผม) ช่วยตรวจ #jsftutorial ที่ผ่านมาหลายๆตอน ก็ได้มีการแก้ไขจุกจิก เพิ่มรายละเอียดเข้าไปนิดๆหน่อย เอาเป็นว่าถ้าใครอ่านแล้ว งง สงสัย ก็แจ้งกันไว้ทาง comment ได้เลยครับ หรือถ้าใครว่างก็ลองกลับไปไล่อ่านอันเก่าๆใหม่บ้างนะครับ เผือผมกลับไปเพิ่มอะไรไว้ได้ไม่พลาดไป ถือซะว่าเป็นการทบทวนกันไปในตัว เพราะอันนี้ก็เขียนกันแบบฉุกละหุก แต่ละบทความใช้เวลา เขียน รวมรวม ทำตัวอย่าง ที่ประมาณสามชั่วโมงเท่านั้น(ดูก็รู้ว่าคนเขียนไม่ตั้งใจสุดๆ 555+) จริงๆคือเนื้อหามันเยอะมากครับ กลัวเขียนไม่จบ สรุปว่าคงต้องให้คนอ่านช่วยครับ รบกวนลองทำตามกันแล้วถ้าใครสะดุดยังไง ติดตรงไหนก็ comment กันเข้ามาได้แก้ได้ แต่ตอนนี้เรามาดูกันต่อดีกว่าครับ

วันนี้คงจะพูดถึงเรื่อง Navigation Rules ครับ คืออะไร ก็เป็นเหมือนข้อกำหนดสำหรับไว้ทำเวลาที่เรา action กลับไปที่ backing bean แล่้วพอจบให้มัน return ไปที่หน้าไหนต่อนั่งเอง โดยใน JSF2.0 นั่นเรายังต้องไปสร้าง navigation rules ใน faces-config.xml เหมือนใน 1.x แต่เราจะมี default มาเลยด้วย

จริงๆแล้วเราเคยผ่านการใช้งาน Navigation ของ JSF ผ่านมาแล้วครับ ถ้านึกไม่ออกผมจะย้อนให้ดูกัน

helloform ----> helloManagedBean ----> hello จำกันได้ยังครับใน action hello ใน helloManagedBean นั่นเราได้มีการ return "hello" จะเห็นว่าหลังจบ action มันได้ forward เราไปที่หน้า hello.jsf นั่นเอง เห็นยังครับ navi แบบ default ก็คือชื่อไฟล์ xhtml เรานี่เองแต่ตัด .xhtml ออกไป ทีนี้ถ้าเราอยากให้มัน forward ไปที่อื่นเราก็แค่เปลี่ยน String ที่ return ตอนจบ action ใน ManagedBean นั่นๆซะ
แต่ถ้าไฟล์ xhtml อยู่ใน sub directory เราก็ต้องใส่ชื่อ directory นั่นๆด้วยตามนี้

$WEB-FOLDER/
----$WEB-INF/
----$SUB-DIRECTORY1/abc.xhtml


default navigation rules สำหรับ abc.xhtml ก็จะเป็น /$SUB-DIRECTORY1/abc นั่นเอง
เรายังมี default อีกอย่างคือ return null ครับ ความหมายถือให้ redirect กลับไปที่หน้าเดิม

ต่อๆ แล้วถ้าเกิดว่าเราคิดว่าแบบข้างบนยาวไปหร่ะเราจะทำไงได้ ก็ทำให้สั่นลงครับด้วย xml config ด้านล่างนั่นเอง

<navigation-rule>
----<description />
----<display-name />
----<icon />
----<from-view-id />
----<navigation-case>
--------<description />
--------<display-name />
--------<icon />
--------<from-action />
--------<from-outcome />
--------<to-view-id />
--------<redirect />

<description />, <display-name />, <icon /> : สามอันนี้เป็นแค่ meta-data ครับ ไม่ต้องสนใจ (จุดประสงค์ทำให้เปิดมาอ่านแล้วไม่งงกับทำให้พวก GUI Tool ทั่้งหลายใช้ซะมากกว่า

<from-view-id >helloform.xhtml</from-view-id > : อันนี้สำหรับไว้กำหนดเป็น rules สำหรับ pages ไหนครับ (สามารถใส่ * ได้แทนความว่า apply rules เข้ากับทุกหน้า)

<from-action >#{helloManagedBean.hello}</from-action >, <from-outcome>hello</from-outcome> : จะมีสี่กรณีที่เป็นไปได้ครับ
1. กรณีที่ไม่มีทั้งสองตัวจะหมายถึง default ของ rule นั้นๆ ในกรณีที่ไม่ตรงกับ criteria อะไรเลย
2. กรณีที่มีแค่ <from-action /> คือไม่ว่าจะ return อะไรที่มาจาก action ที่กำหนดไว้จะไปที่ <to-view-id />
3. กรณีที่มีแค่ <from-outcome/> คือจะไปที่ <to-view-id /> โดยไม่สนว่ามาจาก action ไหนๆ
4. กรณีสุดท้ายคือมีทั้งคู่ คือต้องเป็น outcome ที่มาจาก action นั่นๆเท่านั้นถึงจะไปที่ <to-view-id /> ที่กำหนดไว้

<to-view-id>hello.xhtml</to-view-id> : สำหรับกำหนด jsf page ของ rule นั้นๆ

<redirect /> : อันนี้สำหรับกำหนดว่าจะให้มันไปแบบ forward, redirect ครับ (รายละเอียดอ่านได้ในเนื้อหาเกี่ยวกับ Servlet)
** ใน 1 <navigation-rules> สามารมี <navigation-case> ได้มากกว่า 1 นะครับ

อ่ะ เสร็จแล้วๆ อะฮิๆ ทีนี้ก็ Checkout/Update Code ลงมาแล้วลุยกันเลยครับ โดยไฟล์สำหรับดูเรื่อง Navigation rules จะมีดังนี้ NavigationManagedBean.java, navigation.xhtml, bangkok.xhtml, tokyo.xhtml, paris.xhtml, faces-config.xml

ปล. รอบนี้แอบใจร้ายนะครับ เพราะว่าทั้งใน faces-config.xml, NavigationManagedBean ยังไม่เสร็จทั้งคู่ โดยผมได้ใส่ @TODO ไว้แล้วว่าต้องทำอะไรเพิ่มบ้าง

copyright 2010 @nuboat in wonderland
ข้อเขียนนี้ช่วยฉัน:  

Thursday, June 24, 2010

การตรวจเช็คบนฐานข้อมูล(oracle) ตอนที่ 10

หลังจากที่ได้นำไอเดียจาก Oracle Support(ID 122669.1) มาเรียบเรียง เป็นการตรวจสอบฐานข้อมูล Oracle เบื้องต้นนี้ จนถึงเรื่องสุดท้าย

10. Logging & Tracing
10.1 Alert File
alert log ไฟล์ของฐานข้อมูล จะเก็บสิ่งที่เปลี่ยนแปลงในฐานข้อมูล อันได้แก่
- internal errors (ORA-600), block corruption errors (ORA-1578), และ deadlock errors (ORA-60)
- SQL เช่น CREATE/ALTER/DROP DATABASE/TABLESPACE และจาก Oracle Enterprise Manager หรือ SQL*Plus ที่เกี่ยวกับ STARTUP, SHUTDOWN, ARCHIVE LOG, RECOVER
- Errors เกี่ยวกับ shared server และ dispatcher processes
- Errors ขณะที่ materialized view (refresh)

การที่เรามี alert log ไฟล์ ขนาดใหญ่ จะเป็นการใช้พื้นที่ของ Disk โดยที่ไม่จำเป็น และส่งผลต่อประสิทธิภาพในการเขียนลง Disk ของ OS
ก่อน 11g:
SQL> show parameter background_dump_dest

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest string /oracle/admin/orcl/bdump
11g ->: จะใช้ diagnostic_dest พารามิเตอร์
SQL> show parameter background_dump_dest

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest string /oracle/diag/rdbms/orcl/orcl/trace

SQL> show parameter diagnostic_dest

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
diagnostic_dest string /oracle
10.2 Max_dump_file_size
Oracle server process จะสร้าง trace ไฟล์ เพื่อเก็บความผิดพลาด เราสามารถใช้ trace ไฟล์ เพื่อวิเคราะห์ในแก้ปัญหาและปรับปรุง ส่วน max_dump_file_size จะจำกัดขนาดของ trace ไฟล์
SQL> show parameter max_dump_file_size

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
max_dump_file_size string unlimited

SQL> alter system set max_dump_file_size=10240;

System altered.

SQL> show parameter max_dump_file_size

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
max_dump_file_size string 10240
user_dump_dest พารามิเตอร์ จะเป็นพื้นที่ ที่ใช้เก็บข้อมูล trace ไฟล์ ที่เกิดจาก user processes
ส่วนบน Oracle 11g พื้นที่ดังกล่าว จะถูกควบคุมโดย 'diagnostic_dest' พารามิเตอร์

*** audit ไฟล์ ***
โดยปกติการเชื่อมต่อฐานข้อมูลด้วย SYS หรือ SYSDBA จะมีการเก็บเข้า OS ไฟล์ โดยพื้นที่ ที่ใช้เก็บจะถูกควบคุมด้วย พารามิเตอร์ 'audit_file_dest'
ถ้าพารามิเตอร์นี้ ไม่ได้กำหนดจะเป็น $ORACLE_HOME/rdbms/audit
SQL> show parameter audit_file_dest

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest string /oracle/admin/orcl/adump
ตัวอย่างอื่นๆ (ตรวจสอบการ ใช้งาน sys กับการใช้ syslog)

*** บน 11g เราจำเป็นที่จะต้องเรียนรู้กับ Automatic Diagnostic Repository (ADR) ***
ADR เป็นที่เก็บข้อมูลเพื่อใช้ในการวินิจฉัย เช่น trace files, alert log, และ Health Monitor reports. ส่วนที่ตั้งของ ADR จะถูกควบคุมด้วย 'diagnostic_dest' พารามิเตอร์

การตรวจเช็คบนฐานข้อมูล เป็นสิ่งที่จำเป็นสำหรับผู้ดูแลระบบ ผมหวังว่าบทความเหล่านี้จะมีประโยชน์บ้างนะครับ

อ้างอิง
http://support.oracle.com
http://tahiti.oracle.com
ข้อเขียนนี้ช่วยฉัน:  

Wednesday, June 23, 2010

JSF 2.0 Expression Language

มาแล้วตอนต่อของ JSF 2.0 ก่อนหน้านี้พอดีมีคนมาถามเรือง Session ในทวิตเตอร์ครับ ก็ขอโทษทีช้านะครับ อาจจะช้าๆกันสักนิดนะครับ ผมเผาเนื้อหาให้ไม่ทันค้าบบบ JSF ไ่ม่ใช่น้อยๆนะ ได้บ่นก่อนเขียนแล้วก็มาดูกันต่อดีกว่า ก่อนหน้านี้เราก็ได้เห็น Expression Language หรือ #{helloManagedBean.name} พวกนี้แทรกๆอยู่ตามหน้า xhtml ต่างๆของเรานะครับ ทีนี้แหละเราจะมาดูส่วนนี้แบบละเอียดๆ กันครับว่าเราจะใช้ EL ได้ในรูปแบบใดๆบ้างนะครับ

1. เราจะใช้มันในการ set/get data ระหว่างหน้าจอกับ bean ครับผมแบ่นเป็นให้ดูเป็นสามรูปแบบนะครับ
1.1 อ้างถึง Element แบบธรรมดาก่อนละกันครับ เช่น
#{helloManagedBean.name} หรืออาจจะ nested ลงไปก็ได้เช่นถ้าให้ userView เป็น POJO ที่มี name เป็น property อีกทีก็ #{expressionManagedBean.userView.name}

1.2 อ้างถึง Element ที่เป็น array, list ต่างๆ ดังรูปแบบนี้นะครับ #{bean.array[index]}
#{expressionManagedBean.listdata[0]}
#{expressionManagedBean.listdata[1]}
ตามตัวออย่างนี้ listdata เป็น String[] listdata = new String[4]
#{expressionManagedBean.userList[0].name}
#{expressionManagedBean.userList[0].username}
#{expressionManagedBean.userList[0].group}
#{expressionManagedBean.userList[1].name}
#{expressionManagedBean.userList[1].username}
#{expressionManagedBean.userList[1].group}
ตามตัวออย่างนี้ userListเป็น List<UserView> userList = new LinkedList<UserView>()

1.3 อ้างถึง Element ที่เป้น Map, Hash โดยจะมีรูปแบบดังนี้คือ #{bean.hashtable[key]}
#{expressionManagedBean.mapdata["HOTMAIL"]}
#{expressionManagedBean.mapdata["GMAIL"]}
ตามตัวออย่างนี้ Map<String, String> mapdata = new HashMapString, String>()
ex. <h:inputText value="#{helloManagedBean.name}" /> หรือใช้ print ตรงๆ เลยก็ได้ {helloManagedBean.name}

โดยการทำแบบนี้นั้นตัว HelloManagedBean ก็ต้องมีการประกาศ set/get ของ property name ไว้ด้วยเพือให้สามารถเข้าถึงข้อมูลได้นะครับ


2. เราจะใช้ในการให้ JSF call ไปที่ action ต่างๆของ ManagedBean ตัวนี้ดูง่ายครับ ก็เรียกตรงๆได้เลย
ex. <h:commandButton value="OK" action="#{helloManagedBean.hello}" />
hello เป็น method นะครับไม่ใช่ property ไม่ต้องสร้าง getHello นะครับ ;P

3. ใช้ EL Operators ต่างๆ ดังนี้
Arithmetic :: – +-*/div%mod
Relational :: Use eq, ne, lt, gt, ge, instead of ==, !=, <, >, >=
Logical :: Use and, or, not instead of &&, ||, !
Empty :: empty โดยที่จะเป็น true เมือเป็น null, empty string, empty array, empty list, empty map และเป็น False ในกรณี่อื่นๆ

ex. #{3+2-1}, #{3+2-1}, #{3%2}, #{3/4 == 0.75}, #{ null == "test" }, #{true ? 'true' : 'false'}

update svn แล้วก็มาลองรันกันดูเลยครับ
1. http://127.0.0.1:8080/easyjsf/expression.jsf
2. http://127.0.0.1:8080/easyjsf/operators.jsf


copyright 2010 @nuboat in wonderland
ข้อเขียนนี้ช่วยฉัน:  

Tuesday, June 22, 2010

JSF 2.0 ManagedBean

ผ่านไปแล้วกับ Getting Started นะครับ ในส่วนนั้นเราคงไม่มีอะไรมาก นอกจากแค่อยากให้ทุกคนสามารถที่จะ Startup project ได้แบบ full loop คือ New -> Implement -> Build -> Deploy -> Test และในส่วนตัวผม ผมว่าทุกเรื่องนี่ยากที่สุดก็ Startup นี่แหละครับแต่พอมันได้แล้วที่เหลือมันก็ได้ไปเรื่อยๆเองนั่นแหละ เท่ากับว่าทุกคนจงดีใจได้เลยเราว่าผ่านส่วนที่ยากที่สุดของ JSF มาแล้วนั่นเอง (หุหุ ใครจะเชือผมมั่งเนี่ย)

JSF คือไรก็ได้บอกไปแล้ว ทีนี้ JSF มีส่วนสำคัญคืออะไร ก็คงเป็น ManagedBean ที่เราจะมาดูกันต่อนี่แหละ มันมีไว้ทำไม ก็เป็นส่วนที่ไว้คำนวนทุกอย่างที่เราต้องการให้โปรแกรมทำได้นั่นแหละครับ โดยในบทที่แล้วเราก็จะเห็นว่า JSF สร้าง ManagedBean ได้ง่ายๆ โดยการใส่ @ManagedBean ไว้ที่ส่วนหัวของ Class IndexManagedBean, HelloManagedBean แค่นั่นเอง แต่จริงๆแล้ว Annotation ที่มีสำหรับ ManagedBean มันมีมากกว่านั่นนะสิครับ ทีนี้แหละที่เราจะมาดูกันว่ามันมีอะไรกันบ้าง

โดยผมแบ่งเป็นสองกลุ่มใหญ่ๆครับ
1. สำหรับกำหนดให้ Class ที่ถูกกำหนดเป็น ManagedBean ซึ่งใช้
@ManagedBean( name="", eager = true/false )
name จะไว้สำหรับกำหนดชือสำหรับเรียกครับ โดย default จะเป็นชื่อ Class ที่เปลี่ยนชือตัวหน้าเป็นตัวเล็กนั่นแหละครับ เช่น helloManagedBean, indexManagedBean แต่จริงแล้วเราสามารถที่จำกำหนดให้มันเองเลยก็ได้ (เดี๊ยวไปดูในตัวอย่างละกันครับ) ส่วน eager=true จะมีผมแค่ตอนที่ Scope เป็น @ApplicationScoped เท่านั้น จะเป็นการสั่งให้ Container สร้าง ManagedBean ไว้ก่อนเลย (ถ้าเป็นปกติจะสร้างเมือมีการเรียกเข้ามาครั้งแรก)

2. สำหรับกำหนด Scope ของ Data ว่าจะให้เป็นอะไร เช่น (request, session, application)
@RequestScoped
@SessionScoped
@ApplicationScoped
@ViewScoped
@CustomScoped(value="#{somemap}")
@NoneScoped

โดยเราจะมาดูที่ 4 อันแรกครับ
1. @RequestScoped - จะมีการสร้างและทำลายทุกๆครั้งที่จบ http request
2. @SessionScoped - จะมีการสร้างและไม่ทำลายจนกว่าจะมีการสร้างทำลาย session หรือ session timeout(ตามค่าใน web.xml)
3. @ApplicationScoped - จะมีการสร้างครั้งแรกเท่านั้นจากนั้นจะไม่สร้างอีกแล้ว
4. @ViewScoped - จะมีการสร้างและคงไว้ตราบเท่าที่เรายังอยู่ในหน้านั่นๆ ไม่เปลี่ยนหน้าไปไหน (ใช้สำหรับงานประเทภ AJAX) นั่นแหละครับและอยู่บนพื้นฐานว่า session ต้องยังไม่หมดอายุด้วยถ้าเป็น request ใหม่ก็หายนะครับ (สำหรับตัวนี้คงไปเห็นภาพ

@CustomScoped, @NoneScoped คงยังไม่พูดถึง (คือผมก็ยังไม่ได้อ่านหรือลองมันดูจริงๆเลยครับ) พอดีผมทำโปรเจคด้วย JSF1.2 ครับ แต่เห็นว่าไหนๆจะเขียนแล้วก็เลยมาเขียนที่ JSF2.0 ไปเลยดีกว่า


โอเคเรียบร้อยแล้วครับ http://easyjsf.googlecode.com/svn/trunk/EasyJSF2.0 easyjsf-read-only แล้วลองรัน scope.xhtml (http://127.0.0.1:8080/easyjsf/scope.jsf) กันดูเลยครับ

ขี้เกียจก๊อปโค้ดมาใส่ครับ เอาว่าถ้าอ่านแล้วเอาจากโค้ดลงมาแล้วไม่เข้าใจผมจะอธิบายเพิ่มให้อีกทีนะครับ (ดึกแล้วไม่ไหวแล้วแหะๆ)

ถ้าดู scope.xhtml จะเห็นว่าตัว JSF ทำให้เราสามารถทำให้ .xhtml ต่อกับ java ได้แบบ 1-n ซึ่งผิดกับสมัยก่อนที่ใช้พวก Servlet, Struts ที่จะเป็นลักษณะ 1-1 ( a.jsp -> Servlet/StrutsAction) ถ้าใช้ไปเรือยๆแล้วจะรู้ว่ามันช่วยในการ reuse code ส่วน mvc มากครับ แต่คงไม่เห็นกันตอนนี้หรอกจะเห็นเมือได้เอาไปทำในโปรเจคที่เป็นรุปธรรมซะมากกว่า สำหรับผมผมว่าอันนี้แหละเป็นส่วนที่เก่งที่สุดของ JSF เลยหร่ะ

ปล. เรายังยืนยันว่า Tutorial นี้เหมาะสำหรับคนที่พอรู้ Web Programming มาบ้างแล้วครับ ^ ^

copyright 2010 @nuboat in wonderland
ข้อเขียนนี้ช่วยฉัน:  

Sunday, June 20, 2010

การตรวจเช็คบนฐานข้อมูล(oracle) ตอนที่ 9

9. การจัดการกับหน่วยความจำ (Memory Management)
การจัดการกับหน่วยความจำของฐานข้อมูล Oracle จะมีความแตกต่างกันไป ซึ่งขึ้นอยู่กับ oracle เวอร์ชัน เพราะ oracle เองได้มีการเพิ่มคุณสมบัติ ในการจัดการกับหน่วยความจำกับฐานข้อมูลเวอร์ชันใหม่ๆ เพื่อให้ง่ายและมีประสิทธิภาพ ดังนั้นเรามักจะถูกแนะนำให้ใช้คุณสมบัติในการจัดการกับหน่วยความจำ ด้วยวิธีอัตโนมัติ9.1 ก่อน Oracle 9i
องค์ประกอบหน่วยความจำที่แตกต่างกัน (SGA และ PGA) ต้องการที่จะถูกกำหนดในการเริ่มต้นของฐานข้อมูล(startup) ค่าเหล่านี้เป็นค่าคงที่ ดังนั้นหากหนึ่งในองค์ประกอบของหน่วยความจำที่ต่ำเกินไป และจำเป็นต้องเปลี่ยนแปลง ฐานข้อมูลจำเป็นต้อง restart เพื่อให้ฐานข้อมูลใช้ค่าใหม่ที่ได้เปลี่ยนแปลง
ตัวอย่าง พารามิเตอร์ที่อาจใช้ผิดบ่อยๆ เช่น sort_area_size
SQL> show parameter sort_area_size

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sort_area_size integer 1024000
พารามิเตอร์ sort_area_size กำหนด จำนวนหน่วยความจำที่สามารถใช้ในการเรียงลำดับ ค่านี้เป็นส่วนหนึ่งของ User Global Area (UGA) ดังนั้นจะถูกจัดสรรให้แต่ละผู้ใช้
หากผู้ใช้เข้ามาใช้งานพร้อมกันเป็นจำนวนมาก ในการเรียงลำดับข้อมูลขนาดใหญ่ ระบบอาจจะใช้หน่วยความจำจำนวนมาก
เช่น sort_area_size ของ 1MB กับผู้ใช้ 200 คน เข้ามาพร้อมกันในฐานข้อมูล อย่างไรก็ตามหน่วยความจำนี้ถูกจัดสรรแบบไดนามิก มันสามารถจัดสรรหน่วยความจำถึง 200MB และอาจทำให้เกิดการใช้ SWAP บนระบบ

9.2 Oracle 9i
เริ่มต้นจาก Oracle 9i พวกเราจะพบพารามิเตอร์:
workarea_size_policy = [AUTO | MANUAL]
pga_aggregate_target = <value>

ซึ่งยอมให้เรากำหนดพื้นที่หน่วยความจำสำหรับ PGA โดยที่จะถูกใช้ร่วมกันของ sessions
ถ้าค่านี้น้อยเกินไป (pga_aggregate_target) บ่อยครั้งที่เราจะพบ ORA-4030
SQL> show parameter workarea_size_policy

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
workarea_size_policy string AUTO

SQL> show parameter pga_aggregate_target

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target big integer 500M
ถ้า workarea_size_policy เป็น AUTO หน่วยความจำสำหรับ work area (sort area) จะถูกจัดการอัตโนมัติ จากค่า pga_aggregate_target
ตัวอย่าง work area:
- Sort-based operators (ORDER BY, GROUP BY, ROLLUP, window functions)
- Hash-join
- Bitmap merge
- Bitmap create
อันได้แก่ พารามิเตอร์ *area_size
SQL> show parameter area_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
bitmap_merge_area_size integer 1048576
create_bitmap_area_size integer 8388608
hash_area_size integer 131072
sort_area_size integer 65536
ถ้า workarea_size_policy เป็น MANUAL หน่วยความจำสำหรับ work area (sort area) จะไม่ใช้ pga_aggregate_target เราต้องมีการจัดการกับพารามิเตอร์ *area_size แต่ละตัวเอง
การตรวจสอบ PGA เช่น ข้อมูลการใช้PGA
SELECT * FROM V$PGASTAT;
หรือ คำแนะนำเพื่อการปรับค่าของ PGA
SELECT round(PGA_TARGET_FOR_ESTIMATE/1024/1024) target_mb,
ESTD_PGA_CACHE_HIT_PERCENTAGE cache_hit_perc,
ESTD_OVERALLOC_COUNT
FROM V$PGA_TARGET_ADVICE;
หรือการตรวจสอบ PGA แต่ละ session
set pages500 lines110 trims on
clear col
col name format a30
col username format a20
break on username nodup skip 1
select vses.username||':'||vsst.sid||','||vses.serial# username, vstt.name, max(vsst.value) value
from v$sesstat vsst, v$statname vstt, v$session vses
where vstt.statistic# = vsst.statistic# and vsst.sid = vses.sid and vstt.name in
('session pga memory','session pga memory max','session uga memory','session uga memory max',
'session cursor cache count','session cursor cache hits','session stored procedure space',
'opened cursors current','opened cursors cumulative') and vses.username is not null
group by vses.username, vsst.sid, vses.serial#, vstt.name order by vses.username, vsst.sid, vses.serial#, vstt.name;
การประมาณค่า PGA_AGGREGATE_TARGET:
- สำหรับระบบ OLTP
PGA_AGGREGATE_TARGET = (<Total Physical Memory > * 80%) * 20%
- สำหรับระบบ DSS
PGA_AGGREGATE_TARGET = (<Total Physical Memory > * 80%) * 50%
9.3 Oracle 10g
Automatic Shared Memory Management (ASMM) ถูกแนะนำใน Oracle เวอร์ชัน 10g คุณลักษณะการจัดการหน่วยความจำอัตโนมัติ ทำได้โดยการตั้งค่าพารามิเตอร์ SGA_TARGET ให้มากกว่าศุนย์
คุณลักษณะนี้มีประโยชน์ ช่วยให้เราสามารถแบ่งปันทรัพยากรหน่วยความจำในส่วนต่างๆ และการจัดสรรทรัพยากรณ์จะเป็นไปโดยอัตโนมัติ ด้วย Oracle

SGA_TARGET พารามิเตอร์มีผลต่อ องประกอบหน่วยความจำ:
- Fixed SGA และ other internal ที่ต้องการโดย Oracle Database instance
- Log buffer
- Shared pool
- Java pool
- Buffer cache
- keep และ recycle buffer caches (ถ้าระบุ)
- Nonstandard block size buffer caches (ถ้าระบุ)
- Streams pool

เมื่อเราเซตค่าสำหรับ SGA_TARGET, Oracle 10g จะกำหนดขนาดส่วนประกอบอันได้แก่
- Shared pool (SQL และ PL/SQL execution)
- Java pool (Java execution state)
- Large pool (large allocations เช่น RMAN backup buffers)
- Buffer cache
- Streams pool
SQL> show parameter sga_target

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sga_target big integer 512M
การตรวจสอบข้อมูลการใช้ SGA
select * from v$sgastat;
select * from v$sgainfo;
หรือ คำแนะนำเพื่อการปรับค่าของ SGA
select * from v$sga_target_advice order by sga_size;
หรือตรวจสอบการเพิ่มค่าหรือลดค่า ของส่วนประกอบ SGA
select * from v$sga_dynamic_components;
และ
ALTER SESSION SET nls_date_format = 'DD/MM/YYYY:HH24:MI:SS';
SET PAGESIZE 900
SET LINESIZE 255
COL COMPONENT FORMAT A25
COL INITIAL_SIZE FORMAT A10
COL TARGET_SIZE FORMAT A10
COL FINAL_SIZE FORMAT A10
COL OPER_TYPE FORMAT A10
select START_TIME, component, oper_type, oper_mode,status, initial_size/1024/1024 "INITIAL", target_size/1024/1024 "TARGET", FINAL_SIZE/1024/1024 "FINAL", END_TIME
from v$sga_resize_ops
order by start_time, component;
ส่วนการจัดการหน่วยความจำ PGA อัตโนมัติ ยังใช้งานได้ผ่าน workarea_size_policy และ pga_aggregate_target พารามิเตอร์

9.4 Oracle 11g
Automatic Memory Management (AMM) ถูกแนะนำใน Oracle เวอร์ชัน 11g ช่วยให้ปรับค่า PGA และ SGA โดยอัตโนมัติ กับค่าพารามิเตอร์ MEMORY_MAX_TARGET และ MEMORY_TARGET
SQL> show parameter MEMORY_MAX_TARGET
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
memory_max_target big integer 800M

SQL> show parameter MEMORY_TARGET
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
memory_target big integer 800M
การตรวจสอบองค์ประกอบของหน่วยความจำที่ใช้ AMM
select * from V$MEMORY_DYNAMIC_COMPONENTS;
ตรวจสอบการเพิ่มและลดขององค์ประกอบใน AMM ด้วย V$MEMORY_RESIZE_OPS
หรือ คำแนะนำเพื่อการปรับค่าสำหรับ AMM
select * from v$memory_target_advice order by memory_size;
บทความนี้เป็นตัวอย่างคร่าวๆ ในการจัดการกับหน่วยความจำของฐานข้อมูล Oracle, เราสามารถหาอ่านเพิ่มได้จาก Oracle Documents, Oracle Support และ อื่นๆ

อ้างอิง
http://support.oracle.com
http://tahiti.oracle.com
ข้อเขียนนี้ช่วยฉัน:  

Getting Started with JSF 2.0 (ต่อ)

มาดู WEB.XML config กันก่อนดีกว่าครับ อันนี้ก็ถ้าใครไม่รู้พื้นฐาน Servlet ผมก็ช่วยไม่ได้นะครับแนะนำว่าให้กลับไปอ่านบทความเก่าผมเรือง Servlet ที่ http://thaidev.org ก่อนถ้าสนใจแบบละเอียด แต่ตอนนี้เรามาดู config เฉพาะที่เกี่ยวข้องกับ jsf กันก่อนดีกว่าครับ

<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
อันนี้จะทำให้เวลา JSF เกิด Error มันจะพ่น log มากกว่าปกติเพือช่วยให้แก้ปัญหาได้ดีขึ้น(จริงหรือเปล่า ?)

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
อันนี้เป็นตัวที่เราจะให้มันทำงานเมื่อเราเรียกไปที่ xxx.jsf สามารถเปลี่ยนเป็นอะไรก็ได้เช่น *.htm, *.pl, *.php, *.xxx (แต่ตัวไฟล์เราจะใช้เป็น .xhtml) นะครับ

ต่อไปเราจะมาสร้าง ManagedBean สำหรับ Process งานของ JSF กันครับ

เอาแบบง่ายๆก่อนคือเราจะสร้าง ManagedBean สำหรับโชว์ข้อมูลบนหน้า JSF
1. สร้าง package cc.nuboat.easyjsf.managedbean
2. สร้าง IndexManagedBean.java
/*
* copyright 2010
*/

package cc.nuboat.easyjsf.managedbean;

import javax.faces.bean.ManagedBean;

/**
*
* @author nuboat
*/

@ManagedBean
public class IndexManagedBean {
private String hellostr;

public IndexManagedBean() {
hellostr = "Hello from Facelets";
}

public String getHellostr() {
return hellostr;
}

public void setHellostr(String hellostr) {
this.hellostr = hellostr;
}

}

แก้ index.xhtml ในส่วนของ body ตามด้านล่าง
<h:body>
#{indexManagedBean.hellostr}
</h:body>

ทดลองรันดูเลยครับ พอเสร็จแล้วก็กลับไปแก้ IndexManagedBean
public IndexManagedBean() {
hellostr = "Hello from IndexManagedBean";
}
save แล้วลองไปรัน browser ดูใหม่ว่า text มันเปลี่ยนไปหรือยังนะครับ

มาดู requirement ต่อไปกันดีกว่าครับทีนี้จะยากขึ้นหน่อยคือให้มีหน้าจอสำหรับรับข้อมูลชื่อทาง Textbox แล้วก็ มีปุ่ม Submit แล้วให้ไปหน้าแสดงผลที่โชว์ว่า Hello [Name]. นะครับ เราจะมามองก่อนว่าเราต้องสร้างอะไรบ้าง

1. hello.xhtml
2. helloform.xhtml
3. HelloManagedBean.java

hello.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Hello</title>
</h:head>
<h:body>
Hi Khun. #{helloManagedBean.name}.
</h:body>
</html>


helloform.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f ="http://java.sun.com/jsf/core">
<h:head>
<title>Hello Form</title>
</h:head>
<h:body>
<h:form>
What's your name? : <h:inputText value="#{helloManagedBean.name}" /> : <h:commandButton value="OK" action="#{helloManagedBean.hello}" /> <br />
</h:form>
</h:body>

</html>

HelloManagedBean.java
/*
* copyright 2010
*/

package cc.nuboat.easyjsf.managedbean;

import javax.faces.bean.ManagedBean;

/**
*
* @author nuboat
*/
@ManagedBean
public class HelloManagedBean {
private String name;

public String hello() {
return "hello";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}


ปล. ใครอยากได้ Sourcecode ก็สามารถมา checkout ลงไปดูกันได้ครับ
svn checkout http://easyjsf.googlecode.com/svn/trunk/EasyJSF2.0 easyjsf-read-only


copyright 2010 @nuboat in wonderland
ข้อเขียนนี้ช่วยฉัน:  

Saturday, June 19, 2010

Getting Started with JSF 2.0

สวัสดีครับ ก็จะมาแนะนำ Tutorial ของ JSF 2.0 ครับ อืมจะว่าไงดีนะ ไม่ได้เขียนบทความมานานแถมผมยังเป็นพวกที่คนบอกกันว่า พูดภาษาคนไม่รู้เรื่องซะด้วย ยังไงก็ตั้งใจอ่านกันหน่อยละกันครับ อ๋อ แนะนำตัวกันก่อน ก็ @nuboat ครับเป็นคนที่ว่ารักในการเขียนโปรแกรมก็ว่าได้ ปัจจุบันก็เป็น System Analyst and Banking Specialist ที่แบงค์สีเขียวแห่งหนึ่ง ก็มีหน้าที่ออกแบบและพัฒนาระบบเกี่ยวกับ Treasury ครับ เป็นคนที่ใช้ Java อยู่เป็นนิจ เรียกได้ว่าผมมีประสบการ์ณกับ Java กันแทบทุก platform เลยทีเดียว JavaSE, JavaME, JavaEE, JavaCard ... ว่าไปขาด JavaFX แหะ นอกเรื่องนาน มาดูกันดีกว่ากับ JSF 2.0

JSF เป็นอะไร เอาจากที่ตัวผมเห็นมานะครับ JSF เป็น Web Framework ตัวหนึ่งแต่มันมีลักษณะเหมือน Window Programming มากกว่า Web ที่เป็น Request, Response นะสิครับ ทีนี้ ถ้าคิดจะพัฒนาโปรแรกมด้วย JSF ผมอยากให้คนที่มีพื้นฐานการพัฒนาเว็บเปลี่ยนมุมมองมาเป็นว่ากำลังพัฒนา Window Application ที่เป็น

จริงๆ อยากให้เข้าใจแก่นของ JSF จริงๆก่อน coding แต่ผมว่าเราไป coding กันก่อนให้ชินกับ JSF แล้วค่อยมาดูมันก็ยังไม่สายครับ

ทีนี้เนื่องจาก JavaEE เป็นสิ่งที่มีปัญหาเรื่อง การ config, setup, build, deploy มากพอดู (มากมากเลยแหละ) เพื่อไม่ให้เกิดปัญหา ผมขอบังคับให้ใช้ทุกอย่างตามนี้นะครับ ถ้าใครใช้ไม่เหมือนผมแล้วมาถามว่า Error อะไร ก็ ... ช่วยตัวเองกันครับ 555+

จากการไปเป็น TA ให้กับ #springtrainingday ของ spring66.com ตลอดทุกครั้งคือ แต่ละคนมี environment เป็นของตัวเองกันทั้งนั้น แล้วทีนี้อะไรเกิดขึ้นหร่ะ กว่าจะแค่ทำให้รันได้นี่อย่างเหนือย แล้วนะถ้าคนที่เข้าใจ java architecture จริงๆก็ง่าย ... แต่ความจริงคือหลายคนไม่รู้นะสิ อาจจะเขียน java ได้แต่ไม่เข้าใจมันในหลายๆเรื่อง ทีนี้เพือให้งานนี้ smooth ผมจะขอบังคับ IDE ละกันครับเพราะอยากให้ scope ความรู้ไปที่ JSF จริงๆ

1. JavaSE JDK 1.6 u14 up

2. Netbeans 6.8 up ต้องเป็น release ที่ support Java Web and EE
* default netbeans จะไม่ติดตั้ง tomcat ให้แต่ผมแนะนำให้ customize แล้วเลือกมันมาด้วยเพราะเล็กและง่ายกว่า

โอเค ถ้าเตรียมตัวกันเรียบร้อยก็เริ่มกันเลยครับ เปิด Netbeans แล้วกด New Project กันเลย

1. เลือก Categories เป็น Java Web -> Web application
2. ตั้งชื่อ Project แล้วก็ Browse ไปที่ path ที่จะวาง Projec
3. เลือก Server เป็น Tomcat 6.x Java EE version Java EE 5, context path เป็น /easyjsf
4. เลือก Java Server Faces ,ไปที่ Tap Libraries เลือก Registered Libraries เป็น JSF2.0
5. แล้วไปที่ Tap Confuguration ที่ JSF Servlet URL Pattern ให้กำหมดเป็น *.jsf
6. Finish ได้เลยครับ


เสร็จแล้วยังไม่ต้องคิดอะไรครับ คลิกขวาที่ project แล้วสั่ง deploy เลยครับ
จากนั้นลองเข้า browser ด้วย URL ตามนี้ครับ http://127.0.0.1:8080/easyjsf/index.jsf

จะขึ้นหน้าเปล่าๆ ว่า "Hello from Facelets" .... หวังว่าจะไม่มี error กันทุกคนนะครับ

copyright 2010 @nuboat in wonderland
ข้อเขียนนี้ช่วยฉัน:  

Thursday, June 17, 2010

การ set ให้ Web server เราสามารถรองรับคนจำนวนมากได้

วันนี้ผมได้รับคำถามจาก Twitter (@oracleinth) อีกแล้วครับ โดยที่คำถามเค้าได้ถามมาว่า...
"ขอถามหน่อยนะครับว่า ถ้าเราลง apache tomcat 6.x เพื่อรัน jsp เป็น Web server เราต้องเซตอะไรบ้างเพื่อให้มันรองรับคนจำนวนมากๆ ? "

ถ้าจะพูดถึงการ set ให้ Web server ของเราสามารถรองรับคนจำนวนมากนั้น สามารถทำได้หลายวิธี ซึ่งถ้าเป็นวิธีพื้นฐานเลย นั่นคือ การ set session timeout วิธีนี้ก็จะช่วยได้ในระดับนึง แต่ set session timeout นั้นมันไม่ได้ช่วยอะไรได้มากเท่าไร จากประสบการณ์ที่เคยเจอมากับตัวนะครับ แต่อีกเรื่องนึงที่พอเราไป set รับรองว่ารับคนได้เยอะขึ้นชัวร์คือไปเพิ่ม memory ให้กับ java นั่นเอง

การไป set parameter ดังนี้
JVM option passed to Resin Meaning
-Xms initial java heap size
-Xmx maximum java heap size
-Xmn the size of the heap for the young generation

แต่การเพิ่มพวกนี้ Ram ต้องเยอะด้วยนะ

การไป set ต้องไป set ที่ Environment variable ของ OS เช่นที่ Windows

set JAVA_OPTS=-Xms512m -Xmx1024m

นอกจากจะ set ที่ Environment variable ของ OS ยังไป set ที่ Tomcat ตรงๆได้ ไป set ที่ file %TOMCAT_HOME%\bin\catalina.bat
ไป search ที่ parameter JAVA_OPTS แล้วไปแก้ไขตรงนั้น

ที่เห็นผลได้ชัดเจน client รองรับได้เยอะขึ้น

...จะบอกว่าการ config อย่างเดียวมันก็ไม่ได้ช่วยได้ที่จะทำให้ Tomcat รองรับได้เยอะขึ้น
อย่างการเพิ่ม memory ให้กับ java, การ set session timeout เป็นการแก้ปัญหาที่ปลายเหตุทั้งสิ้น ถึงการแก้แบบนี้จะรองรับ client ได้เยอะขึ้นแต่เอาเข้าจริงไม่มีทางเกินหลักพัน (ใช้พร้อมกัน) เคยลองใช้ jmeter ลองจำลอง client พันตัวพร้อมกันก็ไม่ไหวแล้ว

พอดีผมได้ฟังประสบการณ์ที่มาจากรุ่นพี่ ซึ่งเค้าเคยทำงานกับ web ที่ uip เป็นหลักหมื่นต่อวัน
ซึ่ง web นี้ใช้ php เป็นภาษา developer ส่วน database ก็เป็นเพียง mysql หรือง่ายๆก็คือ LAMP

ผมเลยถามเค้าว่าทำยังไงถึงได้รองรับ user ได้เยอะขนาดนี้ ?
เค้าก็ตอบว่าทำ web ยังไงก็ได้อย่าให้มีการติดต่อ database เป็นดีที่สุด อย่าไปดึงมาเด็ดขายไม่งั้น web ล่มแน่
พี่เค้าก็บอกว่า เชื่อหรือไม่ว่าหน้าแรกของ web ดังทั้งหลายในไทยเป็น HTML ล้วนๆ โดยจะมีการ generate หน้าแรกตั้งทิ้งไว้เป็น HTML จากนั้นเวลาที่ใครมาเรียกก็จะเรียกจากหน้าที่ generate นั้น (ตรงนี้การแยก HTTP server กับ Servlet Container ออกจากกันจะช่วยให้ทำงานได้ดีมากขึ้น เพราะ PHP ก็ต้องแยกเหมือนกัน)

แล้วผมก็ถามต่อว่าถ้าเป็นหน้าข่าวที่มีคน comment เรื่อยๆหละจะทำยังไง เค้าบอกว่าใช้เทคโนโลยี Caches เข้ามาช่วย จะทำการติดต่อ database ก็ต่อเมื่อ insert, update, และ delete เท่านั้น ถ้าจะ select จะ select แค่ครั้งเดียวเท่านั้น แต่จะ select ใหม่ถ้ามีการ update โดยข้อมูลทั้งหมดจะถูกเก็บลง cache ทั้งหมด ที่ต้องเก็บลง cache ทั้งหมดนั้นจะดีกว่าการ select ใหม่ทุกครั้ง เพราะจะมี overhead สูงมากในการติดต่อ DB

ซึ่งใน java นั้นก็มีอยู่นะ เยอะด้วยยกตัวอย่าง Coherence Caches ของ oracle http://www.oracle.com/technology/pub/articles/vohra-coherence.html ซึ่งเคยได้ยินมา แต่ไม่เคยทดลองเล่นดู...

นอกจาก database cache แล้วใน java ยังมี lib หลายๆส่วนที่สามารถทำ cache ได้ อย่างเช่น connection cache ของการติดต่อ DB (Connection Pooling), การทำ cache ของ object เป็นต้น

และมีอีกประเด็นที่จะเสริมเกี่ยวกับการใช้งาน tomcat เพื่อรับ load จำนวนมาก ควร config tomcat เข้ากับ apache(http server) เพื่อแยกงานการ render web (html) กับงานประมวลผล Java ออกจากกัน
จะทำให้ประสิทธิภาพโดยรวมดีขึ้น

ดูที่ http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html

Credit by @plaumkamon, Kim
ข้อเขียนนี้ช่วยฉัน:  

การ recovery PFILE และ SPFILE

บทความนี้ ผมขอเอาใจ DBA ทุกท่านโดยเฉพาะเลย สมมุติว่าถ้า DBA เผลอทำ parameter file หาย และ shutdown instance ไปแล้วด้วย, แถมยังไม่เคยมีการ backup ไว้ก่อนเลย, DBA สามารถแก้ไขอย่างไรได้บ้าง ? โดยปกติแล้ว ถ้าเกิดเราทำ file ใด ๆ ในเครื่องคอมหาย การจะกู้คืนกลับมาเราจะใช้การ recovery, ฉะนั้น เรามาดู วิธีการ recovery PFILE และ SPFILE ที่ไม่ได้มีการ backup ไว้กันเลยดีกว่า

ผมได้ทดสอบทำดู เลยจะขอแจงแจงรายละเอียดเป็นขั้นตอนต่อไปนี้ครับ

1. ทำการ shutdown instance และลบไฟล์ทั้ง 2 file นะครับ คือ PFILE และ SPFILE โดย
PFILE จะอยู่ที่ Path /oracle/admin/orcl/pfile
SPFILE จะอยู่ที่ Path /oracle/db11201/dbs

2. ไปเปิด alert log เพื่อดู parameter โดย alert log จะอยู่ที่ Path
/oracle/diag/rdbms/orcl/orcl/trace
โดยมีชื่อไฟล์ว่า alert_orcl.log

3. ทำการ copy ในส่วนนี้ของไฟล์ alert log มานะครับ
processes                = 150
  memory_target            = 812M
  control_files            = "/oracle/oradata/orcl/control01.ctl"
  control_files            = "/oracle/flash_recovery_area/orcl/control02.ctl"
  db_block_size            = 8192
  compatible               = "11.2.0.0.0"
  db_recovery_file_dest    = "/oracle/flash_recovery_area"
  db_recovery_file_dest_size= 3852M
  undo_tablespace          = "UNDOTBS1"
  remote_login_passwordfile= "EXCLUSIVE"
  db_domain                = "co.th"
  dispatchers              = "(PROTOCOL=TCP) (SERVICE=orclXDB)"
  audit_file_dest          = "/oracle/admin/orcl/adump"
  audit_trail              = "DB"
  db_name                  = "orcl"
  open_cursors             = 300
  diagnostic_dest          = "/oracle"
4. ทำการสร้าง PFILE ชื่อ initorcl.ora ไว้ที่ Path /oracle/db11201/dbs โดยนำ content ของ alert log ที่ copy มาใส่ลงไปในไฟล์

5. เข้า sqlplus ด้วย user sys และทำการ start instance
$ sqlplus /nolog
sql> conn / as sysdba
sql> startup

6. ทำการสร้าง SPFILE จาก PFILE ไปไว้ที่ Path /oracle/db11201/dbs ด้วยคำสั่งต่อไปนี้
sql> create spfile='spfileorcl.ora'
       from pfile='/oracle/db11201/dbs/initorcl.ora';
7. เราจะได้ spfile ที่ชื่อ spfileorcl.ora มานะครับ

8. ทดสอบ startup instance อีกครั้ง พบว่าสามารถ start ได้ครับ
SQL> startup
ORACLE instance started.

Total System Global Area  849530880 bytes
Fixed Size                  1339824 bytes
Variable Size             499125840 bytes
Database Buffers          343932928 bytes
Redo Buffers                5132288 bytes
Database mounted.
Database opened.
SQL> 

เท่านี้เราก็สามารถนำ PFILE และ SPFILE กลับมาได้เหมือนเดิมแล้วครับ :)

Credit by Ice
ข้อเขียนนี้ช่วยฉัน:  

Tuesday, June 15, 2010

มารู้จักกับ Oracle interMedia กันดีกว่า

Oracle interMedia เป็น feature ที่ทำให้ Oracle Database สามารถที่จะทำการเก็บ บริหารจัด หรือกู้คืนข้อมูลประเภท image, audio, video หรือ media data อื่นๆ โดย Oracle interMedia เพิ่ม reliacility, availability และ data management ในด้านของ multimedia ให้กับ Oracle Database ที่ multimedia เป็นเนื้อหาหรือส่วนต่างๆของ internet, e-commerce และ media-rich application

แต่ Oracle interMedia ไม่ได้ทำการควบคุม media capture หรือ output ของ device เนื่องจากส้วนนี้เป็นหน้าที่ของ application software

โดย Oracle interMedia ทำการบริหารจัดการกับ multimedia โดยรองรับสิ่งต่างๆเหล่านี้
  • การจัดเก็บและการกู้คืน
  • การบริหารจัดการกับ metadata ของ media และ application
  • สามารถที่จะรองรับได้หลาย format
  • สามารถ access ผ่านแบบปกติ และได้กับ web interface
  • ทำการ query ด้วยการใช้ความสัมพันธ์ของข้อมูล
  • ทำการ query ด้วย extracted metadata
  • ทำการ query ด้วยการใช้ media content ที่มี optional specialized indexing
Oracle interMedia รองรับ media content สำหรับ Oracle JDeveloper, Oracle Content Management SDK, Oracle Application Server Porta และ Oracle Partner ด้วย

ตัวอย่างการใช้งาน Oracle interMedia

1. ทำการ connect เข้า database ด้วย sqlplus และทำการ สร้าง table ที่ชื่อว่า "image_table" เพื่อใช้ในการเก็บรูป
connect hr/hr
create table image_table (id number primary key, image ordsys.ordimage);
2. ทำการสร้าง directory ที่เก็บรูปไว้โดย ตั้งให้ตรงกับ directory ที่เก็บรูปไว้อยู่ ด้วย user sys และทำการให้สิทธิในการอ่าน directory แก่ user hr
connect / as sysdba
create or replace directory imagedir as '/home/oracle/quickstart/';
grant read on directory imagedir to hr;
3. ใช้ user hr ในการสร้าง PL/SQL procedure ในการ import รูปเข้ามายัง table
create or replace procedure image_import(dest_id number, filename varchar2) is
img ordsys.ordimage;
ctx raw(64) := null;
begin
delete from image_table where id = dest_id;
insert into image_table (id,image)
values (dest_id, ordsys.ordimage.init())
returning image into img;

img.importFrom(ctx, 'file', 'IMAGEDIR', filename);
update image_table set image=img where id=dest_id;
end;
/
! ที่ IMAGEDIR จะต้องพิมพ์เป็นตัวใหญ่ทั้งหมด แม้ในตอนที่สร้าง directory ขึ้นมาจาพิมพ์ด้วยตัวพิมพ์เล็กก็ตาม

4. ทดลองเรียกใช้ procedure ที่สร้างขึ้นมา
call image_import(1,’book2.jpg’);
call image_import(2,’check.png’);
เสร็จแล้วรูปทั้งสองรูปจะถูกเพิ่มเข้าไปยัง table

5. ตรวจสอบรูปภาพด้วยคำสั่ง select ต่อไปนี้ โดยสามารถใช้ดูได้หลายคุณสมบัติของรูป แต่คำสั่งในตัวอย่างนี้จะเป็นการดูความกว้างความยาวของรูป
SQL> select id,t.image.getheight(),t.image.getwidth() from image t;

ID T.IMAGE.GETHEIGHT() T.IMAGE.GETWIDTH()
---------- ------------------- ------------------
1                 134                572
2                 464                667

ในลิ้งค์อ้างอิงยังมีตัวอย่างการใช้ Oracle interMedia อีก แต่ขอยกตัวอย่างมาเพียงเท่านี้ครับ

Credit by Ice

อ้างอิง
ข้อเขียนนี้ช่วยฉัน:  

Sunday, June 13, 2010

การตรวจเช็คบนฐานข้อมูล(oracle) ตอนที่ 8

8. AUTO vs MANUAL undo
ในฐานข้อมูล Oracle เวอร์ชั่นก่อนๆ เราจัดการกับ RollBack Segments ด้วย manual undo. ส่วน automatic undo(เริ่มใช้ Oracle 9i) จะถูกใช้เมื่อเซต UNDO_MANAGEMENT เป็น AUTO
SQL> show parameter UNDO_MANAGEMENT

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
แต่ถ้าหาไม่เซตค่า UNDO_MANAGEMENT หรือเซตเป็น MANUAL จะใช้กลไก 'old' rollback segment อย่างไรก็ตาม Oracle แนะนำให้ใช้ AUTO

8.1 AUTO UNDO
การกำหนดเวลาในการเก็บ undo นั้นจะถูกควบคุมด้วย UNDO_RETENTION (วินาที)
undo_retention เป็นพารามิเตอร์ใหม่ที่พบบน Oracle 9i และยังเป็นพารามิเตอร์ที่สนับสนุน "flashback query" ฟีเจอร์
SQL> show parameter UNDO_RETENTION;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900

SQL> alter system set UNDO_RETENTION=3600;

System altered.

SQL> show parameter UNDO_RETENTION;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 3600
บน Oracle 10g คุณอาจเลือกใช้ GUARANTEE เพื่อให้แน่ใจว่า undo ข้อมูล ไม่ถูกขียนทับก่อน undo_retention ที่กำหนด
SQL> show parameter undo_tablespace;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTBS1

SQL> alter tablespace UNDOTBS1 retention GUARANTEE;

Tablespace altered.
V$UNDOSTAT view สามารถใช้ในการตรวจสอบการใช้ประโยชน์พื้นที่ undo
คำนวณจำนวน undo block ต่อวินาที:
SQL> SELECT (SUM(undoblks))/ SUM ((end_time - begin_time) * 86400) FROM v$undostat;

(SUM(UNDOBLKS))/SUM((END_TIME-BEGIN_TIME)*86400)
------------------------------------------------
57.8207692
หรือ คำนวณจำนวน Byte ที่ต้องการ
SQL> SELECT (UR * (UPS * DBS)) + (DBS * 24) AS "Bytes" FROM (SELECT value AS UR FROM v$parameter WHERE name = 'undo_retention'),(SELECT (SUM(undoblks)/SUM(((end_time - begin_time)*86400))) AS UPS FROM v$undostat),(select block_size as DBS from dba_tablespaces where tablespace_name=(select upper(value) from v$parameter where name = 'undo_tablespace'));

Bytes
----------
751016.081
เรายังใช้ DBA_UNDO_EXTENTS เพื่อตรวจสอบรายละเอียด extents และพื้นที่ใช้ใน undo tablespace ปัจจุบัน
SQL> SELECT DISTINCT STATUS, SUM(BYTES), COUNT(*) FROM DBA_UNDO_EXTENTS GROUP BY STATUS;

STATUS SUM(BYTES) COUNT(*)
--------- ---------- ----------
ACTIVE 1048576 1
EXPIRED 172687360 250
UNEXPIRED 49938432 57
ACTIVE - Undo Extent เป็น Active, ใช้โดย transaction.
EXPIRED - Undo Extent ถูก expire (Exceeded the Undo Retention).
UNEXPIRED - Undo Extent ที่ยังขึ้นอยู่กับค่า UNDO_RETENTION.

8.2 MANUAL UNDO
- rollback มีปัญหาอาจ ส่งผลต่อการเปิดฐานข้อมูล
เช่น เซต rollback_segments เป็น RBS1 แต่ไม่พบ 'RBS1' rollback segment เมื่อเปิดฐานข้อมูล
ORA-01534: rollback segment 'RBS1' doesn't exist
Error 1534 happened during db open, shutting down database
- rollback segment ขนาดเล็ก หรือไม่เพียงพอ จะมีผลกระทบต่อการทำงานของฐานข้อมูล ดังนั้นเราต้องตรวจสอบ
SQL> create rollback segment rbs1;

Rollback segment created.

SQL> show parameter UNDO_MANAGEMENT

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string MANUAL

SQL> show parameter rollback_segments

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
rollback_segments string RBS1

SQL> select d.segment_name, d.tablespace_name, s.waits, s.shrinks, s.wraps, s.status from v$rollstat s, dba_rollback_segs d where s.usn = d.segment_id order by 1;

SEGMENT_NAME TABLESPACE_NAME WAITS SHRINKS WRAPS STATUS
------------------------------ ------------------------------ ---------- ---------- ---------- ---------------
RBS1 SYSTEM 0 0 10 ONLINE
SYSTEM SYSTEM 0 0 0 ONLINE
ถ้าไม่กำหนด rollback_segments จะมี "SYSTEM" rollback segment เดียว
SQL> show parameter UNDO_MANAGEMENT

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string MANUAL

SQL> show parameter rollback_segments

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
rollback_segments string

SQL> select d.segment_name, d.tablespace_name, s.waits, s.shrinks, s.wraps, s.status from v$rollstat s, dba_rollback_segs d where s.usn = d.segment_id order by 1;

SEGMENT_NAME TABLESPACE_NAME WAITS SHRINKS WRAPS
STATUS
------------------------------ ------------------------------ ---------- ---------- ---------- ---------------
SYSTEM SYSTEM 0 0 0 ONLINE
จากข้างต้นขอขยายความ MANUAL UNDO เพียงคร่าวๆ (more)
อย่างไรก็ตามขอแนะนำให้ใช้ AUTO UNDO (อย่างกรณีฟีเจอร์ Total Recall ก็ต้องการ AUTO UNDO)
ข้อเขียนนี้ช่วยฉัน:  

Thursday, June 10, 2010

มาลดเวลาการ Start Oracle Database ด้วย Auto Start กันเถอะ

โดยปกติ เวลาผมจะ Start Database นั้น ผมจะ Start แบบ manual มีวันนึงผมก็เริ่มขี้เกียจมา อยากจะให้ Database มัน Start เองเลยหลังจาก Boot OS เสร็จ...ผมเลยไปหาวิธีที่จะให้มัน Auto Start Database หลังจากการ boot OS เลยโดยที่ผมไม่ต้องไปทำ manual start อีกต่อไป วันนี้เลยอยากจะแชร์บทความนี้ไว้ เผื่อใครอยากทำบ้างนะครับ

มาดูวิธีที่จะทำให้ Oracle Database auto start ขึ้นมาหลังจากการ boot OS โดยที่ admin ไม่ต้อง manual start กันเลยดีกว่า

1. login root

2. เข้าไปแก้ที่ /etc/oratab
โดยสังเกตุที่บรรทัด orcl:/oracle/db11201:N
ถ้าเป็น N อยู่ให้เปลี่ยนเป็น Y ดังนี้ orcl:/oracle/db11201:Y

3.สร้างไฟล์ใหม่ชื่อ dbora ไว้ที่ /etc/init.d/ โดยรายละเอียดตามด้านล่าง

#!/bin/sh
#chkconfig: 345 99 10
#description: Oracle auto start-stop script.
#
#Set ORA_HOME to be equivalent to the $ORACLE_HOME
#from which you wish to execute dbstart and dbshut;
#
#Set ORA_OWNER to the user id of the owner of the
#Oracle database in ORA_HOME.

ORA_HOME=/oracle/db11201
ORA_OWNER=oracle

if [ ! -f $ORA_HOME/bin/dbstart ]
then
echo "Oracle startup: cannot start"
exit
fi

case "$1" in
'start')
#Start the Oracle databases:
#The following command assumes that the oracle login
#will not prompt the user for any values
su - $ORA_OWNER -c "$ORA_HOME/bin/emctl start dbconsole" &
su - $ORA_OWNER -c "$ORA_HOME/bin/dbstart $ORA_HOME"
touch /var/lock/subsys/dbora
;;
'stop')
#Stop the Oracle databases:
#The following command assumes that the oracle login
#will not prompt the user for any values
su - $ORA_OWNER -c "$ORA_HOME/bin/emctl stop dbconsole" &
su - $ORA_OWNER -c "$ORA_HOME/bin/dbshut $ORA_HOME"
rm -f /var/lock/subsys/dbora
;;
esac

ข้อควรระวัง ต้องแก้ส่วน path ORA_HOME ให้ตรงตามที่เราเซ็ต $ORACLE_HOME ไว้ด้วย

4. ทำการ execute โดยใช้คำสั่งตามด้านล่างนี้

#chmod 750 /etc/init.d/dbora
#ln -s /etc/init.d/dbora /etc/rc.d/rc0.d/K01dbora
#ln -s /etc/init.d/dbora /etc/rc.d/rc3.d/S99dbora
#ln -s /etc/init.d/dbora /etc/rc.d/rc4.d/S99dbora
#ln -s /etc/init.d/dbora /etc/rc.d/rc5.d/S99dbora
#ln -s /etc/init.d/dbora /etc/rc.d/rc6.d/K01dbora

5. ทำการ reboot เครื่องใหม่ ก็เป็นอันเสร็จ

เราจะทราบได้อย่างไรว่าสิ่งที่เราทำไป database ได้ start หรือ shutdown ได้ถูกต้องจริงๆ
  • ตรวจสอบ log file เมื่อเปิดเครื่อง ที่ $ORACLE_HOME/startup.log
  • ตรวจสอบ log file ไฟล์เมื่อปิดเครื่อง ที่ $ORACLE_HOME/shutdown.log

Credit by Bie

อ้างอิงจาก
ข้อเขียนนี้ช่วยฉัน:  

Tuesday, June 8, 2010

ทำไมการใช้ index จึงทำให้ query ข้อมูลได้ไวขึ้น?

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

ในฐานข้อมูลการทำ index ก็จะทำให้กับ field หรือคอลัมน์ที่เรามีเงื่อนไขในการ query บ่อยๆ การดึงข้อมูลก็จะไปดูที่ index แล้วกระโดดไปยังตำแหน่งที่เก็บข้อมูลเลยโดยไม่ต้องค้นหาทุกแถวในตาราง

ตัวอย่างเช่น การทำ index ให้กับตาราง employees ที่คอลัมน์ emp_id
1rowid
2rowid
3rowid
..
..
..

เมื่อมีการ query

SELECT *
FROM employees
WHERE emp_id = 3;

Database ก็จะวิ่งไปดึงข้อมูลยังตำแหน่งที่เก็บข้อมูลของ emp003 มาแสดง โดยที่ไม่ต้องวิ่งไปหาทุกๆ แถวในตาราง employees

Oracle Database มี Index อยู่หลายประเภทแต่ที่ถูกใช้กันทั่วไปคือ B-Tree Indexes

(รูปภาพจาก www.oracle.com)

จากรูปจะเห็นว่า B-tree Index นั้นมี block อยู่สองประเภทด้วยกันคือ Branch blocks ไว้สำหรับการค้นหา และ leaf blocks สำหรับเก็บค่า ในการค้นหาก็จะแบ่งเป็นช่วงๆ ตามขอบเขตแต่ละ block ทำให้การค้นหานั้นมีประสิทธิภาพ

ซึ่ง การใช้ index นั้น ยังมีรายละเอียดเสริมเพื่อเพิ่มความเข้าใจอีก โดย คุณ Siamnobita ได้อธิบายเกี่ยวกับ index ด้วยกัน 5 ข้อดังต่อไปนี้

1. สิ่งที่ทำให้เราสามารถค้นหาใน index ได้เร็วนั้นเนื่องจากมีการ sort ตามค่าในคอลัมน์ด้วย เคยมีคนตั้งคำถามใน narisa ประมาณว่าทำไม oracle ถึงไม่เรียงลำดับข้อมูลในตารางซะเลย จะได้ไม่ต้องใช้ index คำตอบก็คือการจัดเก็บแบบเรียงลำดับนั้นทำได้ยากกว่าและเกิดต้นทุนตามมาเช่น เวลาที่ใช้เมื่อมีการเพิ่ม record ใหม่ พื้นที่ว่างเมื่อเกิดการ split block เป็นต้น อย่างไรก็ดีหากเราไม่มีปัญหากับต้นทุนเหล่านี้ เราก็สามารถจัดเก็บข้อมูลในตารางแบบเรียงลำดับได้เลย นั่นคือใช้ index-organized table (IOT) ซึ่งถือเป็นวิธีที่เร็วที่สุดในการค้นหาข้อมูลตาม primary key

2. ปกติเวลา oracle อ่านข้อมูลจะอ่านทีละ block ไม่ใช่ทีละแถว ดังนั้นจะดูว่าเร็วหรือช้า จะนับจากว่า oracle ต้อง access ข้อมูลจำนวนกี่ block เช่น

ถ้าดูจากรูปด้านบน index มี 3 level
เมื่อเรา select * from ... where index_column = ??
oracle จะอ่านข้อมูลทั้งสิ้น 4 block คือ root block ตัวบนสุด, branch block ตัวกลาง, leaf block ตัวล่างสุด, table block ซึ่งรู้ได้ทันทีเมื่อรู้ค่า rowid จำนวน level ที่น้อยที่สุดที่เป็นไปได้คือ 1 level คือเก็บ rowid ไว้ใน root block เลย ซึ่งจะเกิดในกรณีที่ข้อมูลมีจำนวนไม่มาก ( โดย default ขนาดของ block ประมาณ 8K )

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

3.1 ในการ full table scan นอกจากตัว block ที่เก็บ data แล้วยังต้องอ่าน header block ด้วยจึงมี cost ที่เกิดขึ้นไม่ใช่แค่ 1 I/O เมื่อเทียบกับ index ที่ใช้ 2 I/O (root block + data block) ก็พอ ๆ กัน

3.2 ในการ full table scan จะเก็บ data ที่อ่านมาบน buffer cache ด้าน LRU ซึ่งจะอยู่ใน memory ได้ไม่นาน ขณะที่ index scan จะวางไว้ด้าน MRU ทำให้มีโอกาสใช้ประโยชน์จากการอ่านจาก memory โดยตรงได้มากกว่า โดยเฉพาะเมื่อมีการเรียกใช้ข้อมูลจาก table บ่อย ๆ

4. ในข้อ 3 เขาทดสอบเฉพาะกรณี index unique scan เช่นค้นตาม primary key เท่านั้น หากเป็น index range scan จะเป็นอีกกรณีหนึ่ง ซึ่งทุก rowid ที่เจอใน index ก็จะต้องมีการ access table block หนึ่งครั้ง แม้ว่า block นั้นจะอยู่บน memory แล้วก็ยังเป็น cost อยู่ดี ดังนั้น full table scan ก็อาจจะคุ้มกว่าขึ้นกับจำนวนแถวที่ต้องการ

5. ประโยชน์ของ index อีกข้อ คือโดยปกติจำนวน column ใน index จะน้อยกว่า column ใน table มาก ๆ ดังนั้นขนาดของ index ก็จะเล็กกว่า table มาก ๆ ด้วย หากเราต้องการดูเฉพาะข้อมูลที่อยู่ใน index อยู่แล้ว เราก็อาจ full scan ที่ index แทน table ไปเลยก็ได้ ซึ่งกรณีนี้จะเป็นการ fast full scan ซึ่งอ่าน index แบบ multi block เหมือน table scan ( full scan ใน index มี 2 แบบ full scan เฉย ๆ กับ fast full scan แบบแรกอ่านทีละ block ซึ่งช้ากว่า แต่ข้อดีคือ ผลลัพธ์มีการ sort ตาม index แบบหลังจะไม่มีการเรียงลำดับ

ปล. ต้องขอบคุณคำอธิบายดี ๆ จาก คุณ Siamnobita มาก ๆ ครับ

Credit by Paley (@ratipong)

อ้างอิง
ข้อเขียนนี้ช่วยฉัน:  

Friday, June 4, 2010

การเลือก Shutdown database ให้เหมาะสม

หลายท่านที่ได้ทำ Database ต้องรู้จักการ Shutdown database อย่างแน่นอน ซึ่งบางคนก็จะใช้แต่คำสั่ง Shutdown immediate แต่คุณรู้ไหมว่าจริง ๆ แล้วการ shutdown นั้น มีหลายแบบแต่ละแบบนั้นมีความแตกต่างกันขึ้นอยู่กับความเหมาะสมของแต่ละงาน ฉะนั้น เรามาดูกันดีกว่าว่า เราควรจะ Shutdown database แบบไหนให้เหมาะสมที่สุด...


Mode ในการ Shutdown database มีด้วยกัน 4 mode ดังนี้

SHUTDOWN NORMAL mode นี้จะเป็น mode ปกติ ที่ต้องรอให้ผู้ใช้ ใช้งานเสร็จทั้งหมดก่อนถึงจะ shutdown ให้
  • หลังทำการรันคำสั่งนี้แล้ว จะไม่อนุญาตให้มีการเชื่อมต่อเข้ามาใหม่ และ จะรอจนกว่าการเชื่อมต่อที่มีอยู่ทำการยกเลิกการเชื่อมต่อก่อนจึงจะ shutdown
  • การ startup ครั้งต่อไป จะไม่มีการทำ instance recovery

SHUTDOWN TRANSACTIONAL mode นี้จะเป็นการ shutdown ไม่ต้องรอให้ผู้ใช้คนอื่นทำ sessions เสร็จก่อน โดยจะทำการปิด sessions ให้เลย แต่ถ้ายังมีการทำ transactions อยู่ก็รอจนกว่าจะทำเสร็จถึงจะปิดให้
  • หลังทำการรันคำสั่งนี้แล้ว จะไม่อนุญาตให้มีการเชื่อมต่อเข้ามาใหม่ รวมถึง transaction ที่ยังไม่ได้รัน
  • จะรอให้ Transaction ที่ทำงานค้างอยู่ทำงานให้เสร็จก่อน จากนั้นจะทำการยกเลิกการเชื่อมต่อทั้งหมด
  • มีประโยชน์สำหรับการป้องกันไม่ให้งานที่ทำอยู่เกิดข้อผิดพลาด เนื่องจากจะรอให้ทำ transaction ต่างๆที่ค้างอยู่เสร็จก่อน
  • การ startup ครั้งต่อไป จะไม่มีการทำ instance recovery

SHUTDOWN IMMEDIATE mode ไม่ต้องรอใน transactions mode นี้จะปิดให้เลยโดยไม่เลย transactions จบ
  • หลังทำการรันคำสั่งนี้แล้ว จะไม่อนุญาตให้มีการเชื่อมต่อเข้ามาใหม่ รวมถึง transaction ที่ยังไม่ได้รัน
  • Transaction ใดๆที่ยังไม่ได้มีการ commit จะถูก roll back ไปทั้งหมด
  • การเชื่อมต่อทั้งหมดจะถูกยกเลิกทันที
  • การ startup ครั้งต่อไป จะไม่มีการทำ instance recovery

SHUTDOWN ABORT mode นี้จะเป็นการ shutdown เร็วที่สุด เพราะ mode นี้จะไม่ต้องรออะไร
  • หลังทำการรันคำสั่งนี้แล้ว จะไม่อนุญาตให้มีการเชื่อมต่อเข้ามาใหม่ รวมถึง transaction ที่ยังไม่ได้รัน
  • SQL Statement ที่กำลังทำงานอยู่จะถูก terminate ทันที
  • Transaction ใดๆที่ยังไม่ได้มีการ commit จะไม่ถูก roll back
  • การเชื่อมต่อทั้งหมดจะถูกยกเลิกทันที
  • การ startup ครั้งต่อไป จะมีการทำ instance recovery

หรือสามารถดูสรุปได้จากตารางด้านล่างครับ

Database Behavior ABORT IMMEDIATE TRANSACTIONAL NORMAL

Permits new user connections

No

No

No

No

Waits until current sessions end

No

No

No

Yes

Waits until current transactions end

No

No

Yes

Yes

Performs a checkpoint and closes open files

No

Yes

Yes

Yes

Credit by Yong(@stigmatise)

อ้างอิง
ข้อเขียนนี้ช่วยฉัน: