diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,6 @@
+## 0.1.1.0
+* Add new function: `moveId`.
+
 ## 0.1.0.1
 * Add lower bound for mysql-simple dependency.
 
diff --git a/mysql-json-table.cabal b/mysql-json-table.cabal
--- a/mysql-json-table.cabal
+++ b/mysql-json-table.cabal
@@ -1,5 +1,5 @@
 name: mysql-json-table
-version: 0.1.0.1
+version: 0.1.1.0
 category: Database
 synopsis: Using MySQL to store id-to-json tables.
 description: Visit the homepage for more information, or read the readme.
diff --git a/src/Database/MySQL/JSONTable.hs b/src/Database/MySQL/JSONTable.hs
--- a/src/Database/MySQL/JSONTable.hs
+++ b/src/Database/MySQL/JSONTable.hs
@@ -39,6 +39,7 @@
   , alterId
   , deleteId
   , replaceId
+  , moveId
     -- ** Streaming
   , sourceIds
     ) where
@@ -427,6 +428,23 @@
   let query = "UPDATE `" ++ idTableName itable ++ "` SET id=? WHERE key=?"
   _ <- SQL.execute conn (fromString query) (i,Key k)
   pure ()
+
+-- | Move an Id from one key to another. This fails if the original key
+--   doesn't exist or the target key already exists.
+moveId
+  :: (SQL.ToField key, Typeable a)
+  => SQL.Connection
+  -> IdTable key a
+  -> key -- ^ Original key
+  -> key -- ^ New key
+  -> IO ()
+moveId conn itable k k' = do
+  mi <- lookupId conn itable k
+  case mi of
+    Just i -> SQL.withTransaction conn $ do
+      deleteId conn itable k
+      insertId conn itable k' i
+    Nothing -> fail $ "Key not found: " ++ show (SQL.toField k) ++ "."
 
 -- | Stream all ids using a conduit.
 sourceIds
