ในหลักแล้ว DynamoDB เป็น NoSQL database ที่เสนอ key-value และ document data structures มาเข้าใจกันดีกว่า ผมคิดว่านักพัฒนาส่วนใหญ่ที่อ่านอยู่ คุ้นเคยกับ traditional relational database systems ที่เกี่ยวข้องกับ well-defined schemas และ data normalized ไปใน tables, rows และ columns ระหว่าง tables มี "relationships" ใช้ foreign keys ในทางตรงข้าม DynamoDB เป็น schemaless แม้ทุก table ต้องมี primary key แต่ไม่มี constraints อื่นๆ บน non-key attributes อื่นๆ แล้วเมื่อไหร่จะมีประโยชน์? 來了解為什麼 Amazon 創建了 DynamoDB
Amazon ประกาศแผน release DynamoDB สำหรับ public use ในปี 2012 Amazon พัฒนา Dynamo เองหลังเทศกาลวันหยุด 2004 เมื่อหลายแอปพลิเคชันล้มเหลวจาก traffic สูงมาก
เมื่อไหร่ควรพิจารณาใช้ DynamoDB?
DynamoDB เป็นตัวเลือกที่แข็งแกร่งสำหรับแอปพลิเคชันที่ต้องรองรับ concurrent users จำนวนมาก (พันขึ้นไป) และดังนั้น reads/writes ต่อวินาทีหลายหมื่นครั้ง ตัวอย่างเช่น social networks, games และ IoT devices อาจเป็น candidates ที่ดีสำหรับ DynamoDB เช่น Lyft, Airbnb และ Redfin ใช้ Dynamo แม้ adoption จะเบาในตอนแรก และความต้องการ performance ไม่จำเป็นทันที เริ่มต้นด้วย DynamoDB อาจได้เปรียบ over traditional SQL database เช่น Postgres หากคุณจะ build for scale ในที่สุด อย่างไรก็ตาม หากคุณสร้าง data warehouse หรือ OLAP application ที่ users จะ query บ่อย schemaless database อาจไม่ใช่ design choice ที่ดี นอกจากนี้ ในขณะที่ RDMS optimized สำหรับ storage DynamoDB optimized สำหรับ compute Amazon โฆษณาว่า DynamoDB ส่งมอบ single-digit millisecond performance ที่ any scale รองรับ 10 trillion+ requests ต่อวัน พร้อม peaks 20 ล้าน+ requests ต่อวินาที Wow!
เพิ่มเติม AWS เสนอ suite ของ features อื่นๆ ที่ทำให้ DynamoDB เหมาะสำหรับแอปที่ต้องการ data retention และ/หรือ security
Encryption at rest: DynamoDB รักษาข้อมูลทั้งหมดใน encrypted table รวมถึง primary key Users เลือกได้ 3 ตัวเลือก: AWS-owned customer master key (CMK), AWS-managed CMK (key เก็บใน account จัดการโดย AWS Key Management Service) หรือ customer-managed CMK (key เก็บใน account สร้าง/ครอบครอง/จัดการโดยคุณ) สิ่งโคดคือแต่ละ table ใช้ตัวเลือกต่างกันได้ อ่านเพิ่มเติม encryption at rest ที่นี่ (official AWS docs)
On-demand backups/point-in-time recovery: DynamoDB ให้ restore table ไปยังจุดเวลาใดก็ได้ใน ~30 วันที่ผ่านมา ไม่ต้องกังวล accidental writes หรือ deletes อีกต่อไป!
พื้นฐานของ DynamoDB
DynamoDB มี 3 core components: tables, items และ attributes มาแยกแต่ละอย่าง
- Table: collection ของ items
- Item: collection ของ attributes
- Attribute: fundamental data element ที่ไม่ต้องแยกเพิ่มเติม
ตัวอย่าง หากทำแอปจัดการ rental properties อาจมี table "Houses" ด้วย items:
{ "HouseID": 1, "AddressLine1": "123 Main St", "City": "Atlanta", "State": "GA", "Zip": 30322, "Rented": true, "Tenant": "John Smith" }
{ "HouseID": 2, "AddressLine1": "456 Square St", "City": "Nashville", "State": "TN", "Zip": 37211, "Rented": true, "Tenant": "Mary Jane" }
HouseID, AddressLine1, City, State, Zip, Rented และ Tenant เป็น attributes ของ items สามารถเปรียบเทียบ item กับ row และ attribute กับ column ใน SQL database แบบเดิม แต่ขอแนะนำหลีกเลี่ยงการเปรียบเทียบ NoSQL database เช่น DynamoDB กับ SQL database แบบเดิม เพราะเป็นสัตว์ชนิดต่างกัน
สังเกตว่าแต่ละ item มี unique primary key (DynamoDB รองรับ single partition keys และ composite primary keys) แต่除了 HouseID table Houses เป็น schemaless ดังนั้น attributes และ data types ไม่ต้อง define ไว้ล่วงหน้า ต่างจาก SQL database แบบเดิมที่ต้อง define Zip ใน schema พร้อม type integer
อาจสงสัยว่า indexes ทำงานกับ DynamoDB ยังไง ถ้าเป็นคำถามดี! มาลอง pretend ว่าอยากสร้าง index บน attributes rented และ zip ของ table Houses (คือ given zip code ได้ rented properties ทั้งหมดใน zip นั้น) หากใช้ SQL database อาจสร้าง migration แบบนี้:
CREATE INDEX RentedAndZipIndex ON Houses (rented, zip);
ในทางตรงข้าม หากใช้ DynamoDB จะอยาก setup secondary index ต้องระบุ partition key และ sort key ในตัวอย่าง zip เป็น partition key และ rented เป็น sort key มีอะไรเพิ่มเติมมากเกี่ยว indexes กับ DynamoDB แต่เพื่อบทความนี้จะหยุดที่นี่ สนใจเรียนรู้เพิ่ม อ่านที่นี่
ใช้ DynamoDB กับ Ruby และ Ruby on Rails
AWS เสนอ SDKs ในหลายภาษาสำหรับ DynamoDB (Java, JavaScript, Node.js, .NET, PHP, Python และ Ruby ปัจจุบัน) เพื่อใช้ DynamoDB กับ Ruby มี 2 ทางเลือก:
1) Download DynamoDB locally หากแค่ทดสอบแอป ตัวเลือกนี้ดี! พร้อม production แล้ว ลบ local endpoint และ point ไป web service 2) ใช้ DynamoDB web service ต้องการ AWS access key และ creds
เพื่อ interact กับ DynamoDB อาจอยาก download CLI ไม่ก็ใช้ console หรือแค่ API
สุดท้าย สำหรับ series นี้ ต้องมี Ruby installed และ AWS SDK for Ruby
สำหรับ Rails มี gem น่าสนใจเพิ่มในโปรเจกต์ ชื่อ Dynamoid แต่ยังต้องการ AWS credentials
ตัวอย่าง Rails
Step 1: Setup
ใน Gemfile เพิ่ม gems ต่อไปและรัน bundle install:
gem 'dynamoid'
gem 'aws-sdk'
ต่อไป สร้างไฟล์ aws.rb ใน directory config/initializers และเพิ่ม:

หมายเหตุ: ควรใช้ environment variables เก็บ credentials อย่า hard-code ลงโปรเจกต์!
Step 2: กำหนด Document
สำหรับตัวอย่างนี้ ผมสร้างไฟล์ house.rb ใน app/models 长这样:

มาทำความเข้าใจสิ่งที่มีอยู่:
- ต้อง
include Dynamoid::Documentเสมอเมื่อกำหนด tables - บรรทัด 4 กำหนด table name, key และ capacity mode Dynamoid gem มี sensible defaults ดังนั้น technically ไม่ต้อง include ข้างบน แต่การกำหนดจะ override defaults สามารถกำหนด
read_capacityและwrite_capacityได้ แต่เนื่องจากกำหนดcapacity_modeเป็นon_demandoptions นี้จะถูก ignore เนื่องจากon_demandcapacity mode บอก AWS ให้ auto scale up หรือ down - ต่อไป กำหนด fields สำหรับ table ต้อง define ทุก fields บน model และ data type (จะถือเป็น
stringหากละเลย)
Gem dynamoid มาพร้อม rake task สร้าง table:
rake dynamoid:create_tables
Step 3: 互動กับ Objects
แม้บางอย่างดูแปลก แต่มีข่าวดี! ส่วนยอดเยี่ยมของ gem dynamoid คือ features อื่นๆ ที่คุ้นเคยกับ Active Record ทำงานเหมือนกันมาก
Associations
ตัวอย่าง Dynamoid รองรับ associations: has_many, has_one, has_and_belongs_to_many, and belongs_to กำหนดได้เหมือน ActiveRecord ปกติ อาจจินตนาการ rental properties app มี document table อีกอัน Lease บน table House อาจ define:
has_one :lease
และบน table Lease:
belongs_to :house
Validations
Dynamoid ยัง baked in ActiveModel validations พร้อมใช้งาน! Documentation ที่นี่
Callbacks
before_ หรือ after_ callbacks พร้อมสำหรับ save, update, destroy actions สามารถ define ใน lease.rb แบบนี้:
before_save :validate_signature
Creation
Syntax สร้าง objects เหมือน ActiveRecord หนูน้อย สร้างแบบนี้:
h = House.new(address_line_1: "123 Main St", city: "Cool City", state: "Iowa", zip: 52302)
h.rented = true
h.save
หรือใช้ .create method:
House.create(address_line_1: "123 Main St", city: "Cool City", state: "Iowa", zip: 52302)
Querying
รู้สึกซ้ำๆ แต่เดาได้ไหม querying ทำงานยังไง? ถูกต้อง เหมือน ActiveRecord
.findรับ ID.whereรับ matching criteria หลายตัว.find_by_xโดยxคือ attribute
อยากได้เพิ่ม?
มีอะไร เยอะมาก เรียนรู้เกี่ยวกับ gem Dynamoid แต่หวังว่าเพียงพอเริ่มเล่นได้ แนะนำเช็ค official GitHub page ที่นี่ อ่าน features ที่พร้อมใช้งาน!
ต่อไป
มีอะไรมากมายให้ย่อย! หวังว่ารู้สึกเข้าใจมากขึ้นว่า 'NoSQL' หมายถึงอะไร และทำไม DynamoDB ถึงอาจเป็น choice ที่ดีสำหรับโปรเจกต์ที่ต้องการ schemaless database นอกจากนี้เราเดินผ่าน basic setup ของการใช้ dynamoid gem กับ Rails project
ในบทความต่อไปของ series นี้ เราจะ setup DynamoDB locally และลอง features ของ Ruby SDK