# SET
**SET key value [EX seconds] [PX milliseconds] [NX|XX]**
將字符串值 `value` 關聯到 `key` 。
如果 `key` 已經持有其他值, [SET](#set) 就覆寫舊值,無視類型。
對于某個原本帶有生存時間(TTL)的鍵來說, 當 [_SET_](#set) 命令成功在這個鍵上執行時, 這個鍵原有的 TTL 將被清除。
**可選參數**
從 Redis 2.6.12 版本開始, [_SET_](#set) 命令的行為可以通過一系列參數來修改:
* `EX second` :設置鍵的過期時間為 `second` 秒。 `SET key value EX second` 效果等同于 `SETEX key second value` 。
* `PX millisecond` :設置鍵的過期時間為 `millisecond` 毫秒。 `SET key value PX millisecond` 效果等同于 `PSETEX key millisecond value` 。
* `NX` :只在鍵不存在時,才對鍵進行設置操作。 `SET key value NX` 效果等同于 `SETNX key value` 。
* `XX` :只在鍵已經存在時,才對鍵進行設置操作。
Note
因為 [_SET_](#set) 命令可以通過參數來實現和 [_SETNX_](setnx.html#setnx) 、 [_SETEX_](setex.html#setex) 和 [_PSETEX_](psetex.html#psetex) 三個命令的效果,所以將來的 Redis 版本可能會廢棄并最終移除 [_SETNX_](setnx.html#setnx) 、 [_SETEX_](setex.html#setex) 和 [_PSETEX_](psetex.html#psetex) 這三個命令。
**可用版本:**
>= 1.0.0
**時間復雜度:**
O(1)
**返回值:**
在 Redis 2.6.12 版本以前, [_SET_](#set) 命令總是返回 `OK` 。
從 Redis 2.6.12 版本開始, [_SET_](#set) 在設置操作成功完成時,才返回 `OK` 。如果設置了 `NX` 或者 `XX` ,但因為條件沒達到而造成設置操作未執行,那么命令返回空批量回復(NULL Bulk Reply)。
```
# 對不存在的鍵進行設置
redis 127.0.0.1:6379> SET key "value"
OK
redis 127.0.0.1:6379> GET key
"value"
# 對已存在的鍵進行設置
redis 127.0.0.1:6379> SET key "new-value"
OK
redis 127.0.0.1:6379> GET key
"new-value"
# 使用 EX 選項
redis 127.0.0.1:6379> SET key-with-expire-time "hello" EX 10086
OK
redis 127.0.0.1:6379> GET key-with-expire-time
"hello"
redis 127.0.0.1:6379> TTL key-with-expire-time
(integer) 10069
# 使用 PX 選項
redis 127.0.0.1:6379> SET key-with-pexpire-time "moto" PX 123321
OK
redis 127.0.0.1:6379> GET key-with-pexpire-time
"moto"
redis 127.0.0.1:6379> PTTL key-with-pexpire-time
(integer) 111939
# 使用 NX 選項
redis 127.0.0.1:6379> SET not-exists-key "value" NX
OK # 鍵不存在,設置成功
redis 127.0.0.1:6379> GET not-exists-key
"value"
redis 127.0.0.1:6379> SET not-exists-key "new-value" NX
(nil) # 鍵已經存在,設置失敗
redis 127.0.0.1:6379> GEt not-exists-key
"value" # 維持原值不變
# 使用 XX 選項
redis 127.0.0.1:6379> EXISTS exists-key
(integer) 0
redis 127.0.0.1:6379> SET exists-key "value" XX
(nil) # 因為鍵不存在,設置失敗
redis 127.0.0.1:6379> SET exists-key "value"
OK # 先給鍵設置一個值
redis 127.0.0.1:6379> SET exists-key "new-value" XX
OK # 設置新值成功
redis 127.0.0.1:6379> GET exists-key
"new-value"
# NX 或 XX 可以和 EX 或者 PX 組合使用
redis 127.0.0.1:6379> SET key-with-expire-and-NX "hello" EX 10086 NX
OK
redis 127.0.0.1:6379> GET key-with-expire-and-NX
"hello"
redis 127.0.0.1:6379> TTL key-with-expire-and-NX
(integer) 10063
redis 127.0.0.1:6379> SET key-with-pexpire-and-XX "old value"
OK
redis 127.0.0.1:6379> SET key-with-pexpire-and-XX "new value" PX 123321
OK
redis 127.0.0.1:6379> GET key-with-pexpire-and-XX
"new value"
redis 127.0.0.1:6379> PTTL key-with-pexpire-and-XX
(integer) 112999
# EX 和 PX 可以同時出現,但后面給出的選項會覆蓋前面給出的選項
redis 127.0.0.1:6379> SET key "value" EX 1000 PX 5000000
OK
redis 127.0.0.1:6379> TTL key
(integer) 4993 # 這是 PX 參數設置的值
redis 127.0.0.1:6379> SET another-key "value" PX 5000000 EX 1000
OK
redis 127.0.0.1:6379> TTL another-key
(integer) 997 # 這是 EX 參數設置的值
```
## 使用模式
命令 `SET resource-name anystring NX EX max-lock-time` 是一種在 Redis 中實現鎖的簡單方法。
客戶端執行以上的命令:
* 如果服務器返回 `OK` ,那么這個客戶端獲得鎖。
* 如果服務器返回 `NIL` ,那么客戶端獲取鎖失敗,可以在稍后再重試。
設置的過期時間到達之后,鎖將自動釋放。
可以通過以下修改,讓這個鎖實現更健壯:
* 不使用固定的字符串作為鍵的值,而是設置一個不可猜測(non-guessable)的長隨機字符串,作為口令串(token)。
* 不使用 [_DEL_](../key/del.html#del) 命令來釋放鎖,而是發送一個 Lua 腳本,這個腳本只在客戶端傳入的值和鍵的口令串相匹配時,才對鍵進行刪除。
這兩個改動可以防止持有過期鎖的客戶端誤刪現有鎖的情況出現。
以下是一個簡單的解鎖腳本示例:
```
if redis.call("get",KEYS[1]) == ARGV[1]
then
return redis.call("del",KEYS[1])
else
return 0
end
```
這個腳本可以通過 `EVAL ...script... 1 resource-name token-value` 命令來調用。
- Redis 教程
- Redis 簡介
- Redis 安裝
- Redis 配置
- Redis 數據類型
- Redis 命令
- Redis 數據備份與恢復
- Redis 安全
- Redis 性能測試
- Redis 客戶端連接
- Redis 管道技術
- Redis 分區
- Java 使用 Redis
- Java 使用 Redis
- PHP 使用 Redis
- PHP 使用 Redis
- Redis 命令參考
- Key(鍵)
- DEL
- DUMP
- EXISTS
- EXPIRE
- EXPIREAT
- KEYS
- MIGRATE
- MOVE
- OBJECT
- PERSIST
- PEXPIRE
- PEXPIREAT
- PTTL
- RANDOMKEY
- RENAME
- RENAMENX
- RESTORE
- SORT
- TYPE
- SCAN
- String(字符串)
- APPEND
- BITCOUNT
- BITOP
- DECR
- DECRBY
- GET
- GETBIT
- GETRANGE
- GETSET
- INCR
- INCRBY
- INCRBYFLOAT
- MGET
- MSET
- MSETNX
- PSETEX
- SET
- SETBIT
- SETEX
- SETNX
- SETRANGE
- STRLEN
- Hash(哈希表)
- HDEL
- HEXISTS
- HGET
- HGETALL
- HINCRBY
- HINCRBYFLOAT
- HKEYS
- HLEN
- HMGET
- HMSET
- HSET
- HSETNX
- HVALS
- HSCAN
- List(列表)
- BLPOP
- BRPOP
- BRPOPLPUSH
- LINDEX
- LINSERT
- LLEN
- LPOP
- LPUSH
- LRANGE
- LREM
- LSET
- LTRIM
- RPOP
- RPOPLPUSH
- RPUSH
- RPUSHX
- Set(集合)
- SADD
- SCARD
- SDIFF
- SDIFFSTORE
- SINTER
- SINTER
- SINTERSTORE
- SISMEMBER
- SMEMBERS
- SMOVE
- SPOP
- SRANDMEMBER
- SREM
- SUNION
- SUNIONSTORE
- SSCAN
- SortedSet(有序集合)
- ZADD
- ZCARD
- ZCOUNT
- ZINCRBY
- ZRANGE
- ZRANGEBYSCORE
- ZRANK
- ZREM
- ZREMRANGEBYRANK
- ZREMRANGEBYSCORE
- ZREVRANGE
- ZREVRANGEBYSCORE
- ZREVRANK
- ZSCORE
- ZUNIONSTORE
- ZINTERSTORE
- ZSCAN
- Pub/Sub(發布/訂閱)
- PSUBSCRIBE
- PUBLISH
- PUBSUB
- PUNSUBSCRIBE
- SUBSCRIBE
- UNSUBSCRIBE
- Transaction(事務)
- DISCARD
- EXEC
- MULTI
- UNWATCH
- WATCH
- Script(腳本)
- EVAL
- EVALSHA
- SCRIPT EXISTS
- SCRIPT FLUSH
- SCRIPT KILL
- SCRIPT LOAD
- Connection(連接)
- AUTH
- ECHO
- PING
- QUIT
- SELECT
- Server(服務器)
- BGREWRITEAOF
- BGSAVE
- CLIENT GETNAME
- CLIENT KILL
- CLIENT LIST
- CLIENT SETNAME
- CONFIG GET
- CONFIG RESETSTAT
- CONFIG REWRITE
- CONFIG SET
- DBSIZE
- DEBUG OBJECT
- DEBUG SEGFAULT
- FLUSHALL
- FLUSHDB
- INFO
- LASTSAVE
- MONITOR
- PSYNC
- SAVE
- SHUTDOWN
- SLAVEOF
- SLOWLOG
- SYNC
- TIME
- 免責聲明