NoSQL คืออะไร? ต่างจาก RDBMS หรือ SQL Database อย่างไร?
NoSQL นั้นย่อมาจาก “Non SQL” และต่อมาในภายหลังเพี้ยนเป็น “Not only SQL” ซึ่งสื่อความหมายเป็นนัยว่า มันเป็นอะไรที่มากกว่า SQL
ในสมัยก่อนที่ปริมาณข้อมูลมีจำนวนจำกัด และยังไม่มากในระดับที่เรียกว่า Big Data นั้น ข้อมูลแบบ structured data (หรือข้อมูลที่มีรูปแบบชัดเจน) ส่วนมากจะถูกจัดเก็บในระบบฐานข้อมูลแบบ Relational Database ซึ่งความนิยมในตัว RDBMS (Relational Database Management System) นี้เองที่ทำให้ภาษา SQL ได้ถูกนำไปใช้กันอย่างแพร่หลาย เนื่องจากเป็นภาษาที่ถูกคิดขึ้นมาเพื่อดึงข้อมูลออกจาก RDBMS โดยเฉพาะ
ดังนั้น SQL จึงเป็นเหมือนตราสัญลักษณ์ของ RDBMS ไปโดยปริยาย
คำว่า NoSQL ในความคิดผมเองก็เช่นกัน SQL ในที่นี้ไม่ได้สื่อถึงภาษา SQL เท่าไหร่ แต่เป็นการสื่อความหมายถึง Relational Database มากกว่า
NoSQL จึงหมายถึง “ระบบฐานข้อมูลที่ไม่ใช่ Relational Database” ฐานข้อมูลนี้ได้ถูกคิดค้นขึ้นมาเพื่อแก้ปัญหาหลักๆ 2 อย่างที่มีใน RDBMS คือ 1) เพิ่มความสามารถในการจัดเก็บ unstructured data (หรือข้อมูลที่มีรูปแบบไม่แน่นอน) และ 2) เพิ่มความสามารถในการขยายระบบในรูปแบบแนวนอน (Horizontal Scalability) เพื่อรองรับปริมาณข้อมูลที่มากขึ้นในยุคนี้
แล้วมันมีฐานข้อมูลแบบไหนอีกบ้างล่ะ ที่ไม่ใช่ Relational Database และต่างกันอย่างไรบ้าง?
ความต่างกันในแง่ของการเก็บข้อมูล (Data Store)
RDBMS มีการเก็บข้อมูลในรูปแบบของตาราง (table) ที่เรียบง่าย โดยที่ 1 record หรือ 1 row มีหลาย column และในแต่ละ table จะมีจำนวน column ที่แน่นอน ส่วน
NoSQL นั้นมีรูปแบบการเก็บข้อมูลที่ต่างออกไป โดยมี 4 รูปแบบหลักๆ ดังนี้
1. Wide-Column Store — ฐานข้อมูลแบบ RDBMS นั้นมีการเก็บข้อมูลในรูปแบบของ row ที่มี column ที่แน่นอน แต่ wide-column store นั้นมีการเก็บข้อมูลโดยแต่ละ row จะมีคู่ของ key column และ value column ที่อาจจะเหมือนหรือแตกต่างกันก็ได้ ตัวอย่างของฐานข้อมูลที่มีรูปแบบการเก็บข้อมูลแบบนี้เช่น HBase และ Cassandra เป็นต้น
2. Key-Value Pair — ฐานข้อมูลแบบนี้จะเน้นความเรียบง่าย เพราะแต่ละ record จะมีเพียงแค่ key และ value เท่านั้น สามารถเข้าถึงข้อมูลได้อย่างรวดเร็วด้วยการระบุค่า key ลงไปโดยไม่จำเป็นต้องใช้ SQL ในการดึงข้อเลย ตัวอย่างของฐานข้อมูลที่มีรูปแบบการเก็บข้อมูลแบบนี้เช่น Redis และ Oracle NoSQL Database (OND) เป็นต้น การเก็บข้อมูลแบบนี้ถูกนำไปใช้กับ Twitter
3. Graph Database — หากความสำคัญของข้อมูลที่เราจะเก็บอยู่ที่ความสัมพันธ์กันของข้อมูล Graph Database จะเป็นหนึ่งในตัวเลือกที่ดีที่สุด ยกตัวอย่างเช่น เดิมหากเราจะเก็บข้อมูลใน RDBMS ว่า music producer คนไหน produce อัลบั้มไหนของศิลปินคนใด เราอาจจะต้องแบ่งข้อมูลออกเป็น 3 tables ก่อน (album, artist, และ producer) แล้วจึงค่อยนำข้อมูลในแต่ละ table มา join กันทีหลังผ่าน SQL
ในทางกลับกันถ้าเราเก็บข้อมูลแบบ Graph Database ซึ่งเป็นการเก็บความสัมพันธ์ของข้อมูลตั้งแต่แรกอยู่แล้ว เราก็จะไม่จำเป็นต้องนำข้อมูลมา join กันเลย
4. Document Based — เก็บข้อมูลในรูปแบบของไฟล์ semi-structured data ต่างๆ เช่น JSON หรือ XML โดยภายในไฟล์ที่เก็บในแต่ละ table อาจจะไม่ต้องมีรูปแบบ (structure) ที่เหมือนกันก็ได้ ซึ่งเราจะสามารถ search หาข้อมูลในแต่ละ tag ได้
จะพบว่าแต่ละรูปแบบของการเก็บข้อมูลใน NoSQL database นั้นต่างมีลักษณะเฉพาะทาง และเหมาะกับงานเพียงบางงานเท่านั้น และถึงแม้ NoSQL database ที่ต่างกัน จะใช้รูปแบบการเก็บข้อมูลแบบเดียวกัน ก็ยังมี architecture ที่ไม่เหมือนกันอีกด้วย ทั้งนี้เนื่องมาจากความต้องการทำให้ performance ดีขึ้นในส่วนที่ต่างกัน เช่น NoSQL ค่ายหนึ่งอาจต้องการให้ database ของเขามีความสามารถในการ write ได้รวดเร็ว แต่ในขณะที่อีกค่ายนึงต้องการความสามารถในการ read มากกว่า
ความต่างกันในแง่ของคุณสมบัติ (ACID และ CAP Theorem)
ACID
ACID หรือ Atomicity, Consistency, Isolation, และ Durability คือกลุ่มคุณสมบัติพื้นฐานที่ทุกๆ ฐานข้อมูลโดยเฉพาะ RDBMS ต้องมี เพื่อที่จะสามารถประมวลผล transaction ได้
เรามาดูกันว่าแต่ละตัวเป็นยังไงครับ
Atomicity — ในที่นี้หมายถึง กระบวนการทำงานและขั้นตอนต่างๆ ที่ประกอบเป็น transaction ที่กระทำต่อ database หากทำสำเร็จก็จะต้องสำเร็จทุกขั้นตอน ถ้าหากมีขั้นตอนใดขั้นตอนนึงไม่สำเร็จ ผลลัพธ์ที่ได้ก็จะต้องเหมือนกับว่าไม่เคยมีขั้นตอนไหนถูกทำมาก่อน
ยกตัวอย่างเช่น transaction ของการโอนเงินของผมจำนวน 500 บาทให้เพื่อน จะประกอบไปด้วย 1) การตัดเงินในบัญชีของผม 500 บาท และ 2) การเพิ่มเงินในบัญชีเพื่อนผม 500 บาท จะเห็นว่าธนาคารจะต้องทำทั้ง 2 ขั้นตอนให้สำเร็จเท่านั้น กระบวนการโอนเงินถึงจะสำเร็จ หากการโอนไม่สำเร็จเพราะติดขัดในขั้นตอนที่ 2 ทางธนาคารก็จะต้องคืนเงิน 500 บาทกลับให้ผม เสมือนขั้นตอนที่ 1 ไม่เคยเกิดขึ้นมาก่อน
Consistency — เมื่อการโอนเงินของผมสำเร็จแล้ว หากเรียกดูเงินในบัญชีผมก็จะเห็นเป็น 0 บาทเสมอ ซึ่งสอดคล้องกันกับ transaction โอนเงิน
Isolation — หมายถึงว่า หากมี transaction เกิดขึ้นพร้อมๆ กัน แต่ละ transaction จะถูกประมวลผลตามลำดับไม่ทับซ้อนกัน ลองนึกภาพว่าถ้าผมสามารถทำ transaction การโอนเงิน 500 บาทพร้อมกัน 5 รายการได้ เงิน 500 บาทในบัญชีผม อาจจะถูกโอนไปให้เพื่อนได้หลายๆ คน สิ่งเหล่านี้จะไม่เกิดขึ้น ถ้าฐานข้อมูลมีคุณสมบัติ Isolation หากมีการทำ transaction โอนเงินพร้อมกัน 5 รายการ ระบบฐานข้อมูลจะประมวลผลทีละ transaction เมื่อ transaction แรกสำเร็จเงิน 500 บาทในบัญชีผมจะกลายเป็น 0 และไม่สามารถทำรายการที่ 2–5 ได้
Durability — เมื่อการโอนเงินสำเร็จแล้ว ก็จะสำเร็จตลอดไป ไม่ว่าจะเกิดเหตุการณ์เช่น ไฟดับ หรือ หรือปัญหาใดๆ ก็ตาม
ผมกำลังจะบอกว่า NoSQL เกือบทั้งหมด แทบจะไม่มีคุณสมบัติ ACID นี้เลยครับ!!! โดยเฉพาะ Consistency ทั้งนี้เพื่อแลกกับความเร็วและ Scalability
และนี่เป็นเหตุผลว่าทำไมระบบ facebook, amazon, uber จึงเร็วกว่าและล่มน้อยกว่าธนาคารครับ เพราะ database หลักของธนาคารไม่ใช่ NoSQL
CAP Theorem
CAP Theorem ถูกคิดค้นโดย Eric Brewer กล่าวคือ distributed database ทั้งหมดจะมีคุณสมบัติได้เพียง 2 จากทั้งหมด 3 อย่างตามด้านล่างเท่านั้น
Consistency [C]— หมายถึง ทุกครั้งที่เราอ่านข้อมูลจาก database จะได้ผลลัพธ์ล่าสุดหรือไม่ก็ error ไปเลยเท่านั้น
Availabilty [A]— หมายความว่า ถ้าเราดึงข้อมูลจาก database เราจะได้ผลลัพธ์กลับมาเสมอ (ไม่ error)
Partition Tolerance[P] — คือการที่ระบบสามารถทำงานต่อไปได้ หากมี node ใด node นึงใน distributed database ขาดการติดต่อหรือล่มอยู่
RDBMS แทบทั้งหมดนั้นมีคุณสมบัติ CA ต่างจาก NoSQL ที่ต้องเลือกระหว่าง เสีย Consistency หรือ Availability เพื่อแลกกับ Partition Tolerance นั่นเอง (จะแย่มาก หาก distributed database ไม่มีคุณสมบัติ Partition Tolerance)
NoSQL database ที่มีคุณสมบัติ A และ P แปลว่า มีการ backup ข้อมูลไว้ในหลายๆ Partition และหากเรายอมให้มี A ซึ่งก็คือทุกๆ การดึงข้อมูลจาก database เราจะได้ผลลัพธ์กลับเสมอ จะทำให้ระบบฐานข้อมูลนั้นขาดคุณสมบัติของ Consistency ทันที เนื่องจาก จะมีช่วงเวลาที่ข้อมูลใน node ใด node นึงถูกอัพเดต แต่ยังไม่ทันได้แจ้งให้ node อื่นๆ อัพเดตตาม หากดึงข้อมูลนั้นใน node ที่ยังไม่ได้อัพเดต เราก็จะไม่ได้ผลลัพธ์ล่าสุดครับ
NoSQL database ประเภท AP เช่น Cassandra นั้นจะมีคุณสมบัติที่เรียกว่า Eventual Consistency แทน ซึ่งหมายความว่า ในท้ายที่สุดแล้วทุกๆ node ก็จะมีข้อมูลล่าสุด เหมือนๆ กัน เมื่อเวลาผ่านไป
NoSQL database ที่มีคุณสมบัติ C และ P แปลว่า มีการป้องกันไม่ให้อ่านข้อมูลที่ถูกอัพเดตจนกว่าทุกๆ node จะอัพเดตข้อมูลให้ตรงกันแล้วเท่านั้น แปลว่าในช่วงเวลาดังกล่าว เราไม่สามารถที่จะส่งผลลัพธ์กลับไปได้ ทำให้ขาดคุณสมบัติ Availability