ข้ามไปยังเนื้อหา

SET & GET

SET key value ใช้เก็บ string ส่วน GET key ใช้ดึงค่ากลับมา ถ้า key มีอยู่แล้ว SET จะ เขียนทับ ทันทีโดยไม่มีเงื่อนไข (เว้นแต่คุณจะเพิ่ม flag เงื่อนไขเข้าไป)

127.0.0.1:6379> SET city "Bangkok"
OK
127.0.0.1:6379> GET city
"Bangkok"
127.0.0.1:6379> SET city "Chiang Mai"
OK
127.0.0.1:6379> GET city
"Chiang Mai"

SET ใน Redis 7 รองรับหลาย option ในคำสั่งเดียว:

Optionความหมาย
EX secondsตั้งเวลาหมดอายุเป็นวินาที
PX millisecondsตั้งเวลาหมดอายุเป็นมิลลิวินาที
EXAT unix-time-secondsหมดอายุที่ Unix timestamp (วินาที)
PXAT unix-time-msหมดอายุที่ Unix timestamp (มิลลิวินาที)
NXset ก็ต่อเมื่อ key ยังไม่มี อยู่
XXset ก็ต่อเมื่อ key มี อยู่แล้ว
GETคืนค่าเดิมก่อนเขียนทับ
KEEPTTLคง TTL เดิมไว้แทนที่จะ reset
127.0.0.1:6379> SET token "abc123" EX 60
OK
127.0.0.1:6379> TTL token
(integer) 59
127.0.0.1:6379> SET counter 0 NX
OK
127.0.0.1:6379> SET counter 99 NX
(nil)
127.0.0.1:6379> GET counter
"0"
127.0.0.1:6379> SET city "Phuket" GET
"Chiang Mai"
127.0.0.1:6379> GET city
"Phuket"
SET token "abc123" EX 60
TTL token
SET counter 0 NX
SET counter 99 NX
GET counter
SET city "Phuket" GET
GET city

สองคำสั่งนี้เป็น alias แบบเก่าที่ใช้สะดวก — ใน Redis 7 นิยมใช้ SET พร้อม EX หรือ NX มากกว่า แต่คุณก็ยังเจอสองคำสั่งนี้ใน code เก่า ๆ อยู่:

127.0.0.1:6379> SETEX session:user1 3600 "token-xyz"
OK
127.0.0.1:6379> TTL session:user1
(integer) 3599
127.0.0.1:6379> SETNX lock:job1 "worker-A"
(integer) 1
127.0.0.1:6379> SETNX lock:job1 "worker-B"
(integer) 0
127.0.0.1:6379> GET lock:job1
"worker-A"
SETEX session:user1 3600 "token-xyz"
TTL session:user1
SETNX lock:job1 "worker-A"
SETNX lock:job1 "worker-B"
GET lock:job1

set หรือ get หลาย key ได้ในรอบเดียว วิธีนี้เร็วกว่าการยิงทีละคำสั่งอย่างเห็นได้ชัดเมื่อคุณต้องการหลาย key พร้อมกัน

127.0.0.1:6379> MSET user:1:name "Ada" user:1:lang "Python" user:2:name "Bob" user:2:lang "Go"
OK
127.0.0.1:6379> MGET user:1:name user:1:lang user:2:name user:2:lang
1) "Ada"
2) "Python"
3) "Bob"
4) "Go"
127.0.0.1:6379> MGET user:1:name user:99:name
1) "Ada"
2) (nil)
MSET user:1:name "Ada" user:1:lang "Python" user:2:name "Bob" user:2:lang "Go"
MGET user:1:name user:1:lang user:2:name user:2:lang
MGET user:1:name user:99:name

APPEND จะต่อค่าเข้าไปท้าย string เดิม (หรือสร้าง key ใหม่ถ้ายังไม่มี) ส่วน STRLEN จะคืนความยาวของค่าเป็นจำนวน byte

127.0.0.1:6379> SET log "2024-01-01 boot"
OK
127.0.0.1:6379> APPEND log " | 2024-01-01 ready"
(integer) 34
127.0.0.1:6379> GET log
"2024-01-01 boot | 2024-01-01 ready"
127.0.0.1:6379> STRLEN log
(integer) 34
SET log "2024-01-01 boot"
APPEND log " | 2024-01-01 ready"
GET log
STRLEN log
ตัวเลือกBenefitCost
SET key val NX (set แบบมีเงื่อนไข)atomic เช็ก-แล้ว-set ในคำสั่งเดียว ใช้ทำ lock/dedup เบื้องต้นได้ไม่มี ownership token ในตัว ต้องออกแบบเพิ่มเองถ้าต้องการปลดล็อกอย่างปลอดภัย
MSET/MGET (batch operation)ลด round-trip เมื่อต้อง set/get หลาย key พร้อมกันไม่ atomic ข้าม key ต่างชนิดกันแบบ transaction เต็มรูปแบบ (ใช้ MULTI/EXEC ถ้าต้องการ isolation จริง)
SET key val แบบไม่มีเงื่อนไขง่าย เขียนทับได้ทันทีโดยไม่ต้องเช็กก่อนเสี่ยง overwrite ข้อมูลของ client อื่นโดยไม่ตั้งใจถ้าไม่ได้ออกแบบ key ให้ unique พอ
  • ใช้ SET แบบไม่มีเงื่อนไขตอนที่ตั้งใจจะทำ “set ถ้ายังไม่มี” — ลืมใส่ NX ทำให้ข้อมูลเดิมถูกเขียนทับโดยไม่รู้ตัว ควรใช้ SET key val NX เมื่อ logic ต้องการ atomic check-then-set
  • ลืมว่า SET แบบธรรมดาจะ reset TTL เดิมของ key ทิ้ง — ถ้าอยากคง expiry เดิมไว้ตอนอัปเดตค่า ต้องเติม KEEPTTL เข้าไปด้วย ไม่งั้น key จะกลายเป็น persistent ทันที
  • ใช้ SETNX/SETEX (legacy command) ปนกับ SET ... NX/EX ในโค้ดเดียวกัน — ทำให้ style ไม่สม่ำเสมอ ควรเลือกใช้ SET พร้อม option เป็นมาตรฐานเดียวตามคำแนะนำของ Redis 7+

💡 ตัวอย่างจากของจริง

Stripe-style idempotency keys — ใช้ SET key val NX EX <ttl> เพื่อกันไม่ให้ request เดิมถูกประมวลผลซ้ำสองครั้ง โดย key ที่ set สำเร็จเพียงครั้งเดียวคือ request ที่ผ่านเข้าไปจริง

Feature-flag/config caches — ใช้ MSET/MGET ดึงค่า config หลายตัวพร้อมกันในคำสั่งเดียว แทนที่จะยิง GET แยกทีละ key ซึ่งเพิ่ม network round-trip โดยไม่จำเป็น

`SET key val NX` คืนค่าอะไรเมื่อ key มีอยู่แล้ว?
คำสั่งใดใช้ set หลาย key ได้ในรอบเดียว?
`SET key val GET` ทำอะไร?
STRLEN คืนความยาวของ string เป็นหน่วยอะไร?