วันพุธที่ 21 ตุลาคม พ.ศ. 2552

ความสำคัญของ ROWID

เคยคิดมั้ยครับว่าการที่เรา query เพื่อต้องการข้อมูลซัก 1 row ใน table ตามเงื่อนไขที่เราต้องการนั้น ตัวออราเคิลเองมันทำงานอย่างไรถึงสามารถดึงข้อมูลมาให้เราได้อย่างรวดเร็วภายในพริบตา ถึงแม้ว่าใน database เราจะมีข้อมูลอยู่เป็นล้าน ๆ เรคคอร์ดก็ตาม การที่ออราเคิลทำอย่างนี้ได้แสดงว่าในแต่ละ row จะต้องมีการเก็บตำแหน่งเพื่อบอกว่า row นั้น ๆ อยู่ตรงไหนใน database เพื่อให้เข้าถึงข้อมูล row นั้น ๆ ได้โดยสะดวก เปรียบเสมือนกับเวลาที่เราต้องการค้นหาคำ ๆ หนึ่งในหนังสือ เราก็มักจะเปิดไปที่หน้าดัชนีซึ่งอยู่ท้ายเล่มเพื่อหาว่าคำที่ต้องการอยู่ในหน้าที่เท่าไรของหนังสือเล่มนั้น ออราเคิลเรียกตัวระบุตำแหน่งของ row นี้ว่า ROWID

ROWID ในความหมายของออราเคิลก็คือ pseudocolumn(คอลัมน์สมมุติ) เพื่อใช้บอกถึงตำแหน่งทาง physical ของข้อมูลแต่ละ row ใน table ว่าอยู่ที่ data file อะไร บล็อกไหนและอยู่ที่ row ที่เท่าไรใน data block โดยที่ค่าของ ROWID นี้จะเป็นค่า unique สำหรับแต่ละ row ใน table ที่ไม่ซ้ำกันเลย เราสามารถดูค่าของ ROWID ได้ด้วยคำสั่งดังนี้

SQL> select rowid from table_name;

ROWID
------------------
AAANUqAAGAAAVM2AAA
AAANUqAAGAAAVM2AAB
AAANUqAAGAAAVM2AAC
AAANUqAAGAAAVM2AAE

ค่าของ ROWID ที่แสดงให้เราเห็นนั้นถูกเก็บแบบเข้ารหัส BASE64 มีขนาดเท่ากับ 18 character โดยเราสามารถใช้ฟังก์ชัน DBMS_ROWID เพื่อแปลความหมายของ ROWID ได้ดังนี้

เก็บอยู่ที่ Table อะไร
select object_name from dba_objects where data_object_id = dbms_rowid.rowid_object('AAANUqAAGAAAVM2AAA')

เก็บอยู่ที่ Data file อะไร
select file_name from dba_data_files where file_id = dbms_rowid.rowid_relative_fno('AAANUqAAGAAAVM2AAA')

เก็บอยู่ที่ block ที่เท่าไร
select dbms_rowid.rowid_block_number('AAANUqAAGAAAVM2AAA') from dual

หาว่าอยู่ row ที่เท่าไร
select dbms_rowid.rowid_row_number('AAANUqAAGAAAVM2AAA') from dual

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

delete from table_name a where exists (select 1 from table_name b where a.COL1 = b.COL1 and b.ROWID < a.ROWID)

ไม่มีความคิดเห็น:

แสดงความคิดเห็น