問(wèn)題描述
我正在嘗試根據(jù)兩個(gè)不同列的組合使表中的項(xiàng)目保持唯一.
I'm trying to keep items in my table unique based on a combination of two different columns.
我有一個(gè) instanceId 和 imageId 列(以及其他列)并基于 Stackoverflow 上的幾篇帖子 和 AWS 論壇 以下應(yīng)該可以嗎?
I have an instanceId and imageId column (along with others) and based on a couple of posts on Stackoverflow and AWS Forums the below should work?
public void saveUnique(Server server) {
DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
Map<String, ExpectedAttributeValue> expectedAttributes =
ImmutableMap.<String, ExpectedAttributeValue>builder()
.put("instanceId", new ExpectedAttributeValue(false))
.put("imageId", new ExpectedAttributeValue(false))
.build();
saveExpression.setExpected(expectedAttributes);
saveExpression.setConditionalOperator(ConditionalOperator.AND);
try {
mapper.save(server, saveExpression);
} catch (ConditionalCheckFailedException e) {
//Handle conditional check
}
}
但是,每次我嘗試保存重復(fù)項(xiàng)(相同的 instanceId 和 imageId)時(shí),它都會(huì)成功保存到數(shù)據(jù)庫(kù)中.
However every time I try and save a duplicate item (same instanceId and imageId) it's successfully being saved into the database.
我還有什么遺漏嗎?
編輯 R.E notionquest 答案
更新到下面的答案.
我有一項(xiàng)工作,每分鐘運(yùn)行一次,輪詢 API.API 的響應(yīng)表示為 Server
POJO.Server
有一個(gè)名為instanceId
的屬性.
I have a job that runs once a minute polling an API. The response from the API is represented as a Server
POJO. The Server
has an attribute named instanceId
.
我想確保如果具有該 instanceId
的 Server
已經(jīng)在數(shù)據(jù)庫(kù)中,請(qǐng)不要保存它.
I want to make sure that if a Server
with that instanceId
is already in the database, don't save it.
Server
對(duì)象還有一個(gè)id
屬性,它被設(shè)置為表的主鍵.
The Server
object has another attribute of id
which is set as the table primary key.
public void saveUnique(Server server) {
DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
Map<String, ExpectedAttributeValue> expected = new HashMap<>();
expected.put("instanceId", new ExpectedAttributeValue(new AttributeValue(server.getInstanceId())).withComparisonOperator(ComparisonOperator.NE));
saveExpression.setExpected(expected);
try {
mapper.save(server, saveExpression);
} catch (ConditionalCheckFailedException e) {
LOGGER.info("Skipped saving as not unique...");
}
}
此代碼將一遍又一遍地保存 Server 對(duì)象,而不會(huì)引發(fā)異常.
This code will save the Server object over and over again with the exception never being thrown.
服務(wù)器 POJO
@DynamoDBTable(tableName = "Servers")
public class Server {
@Id
private String id = UUID.randomUUID().toString();
@DynamoDBTypeConvertedJson
private Task task;
@DynamoDBAttribute(attributeName = "instanceId")
private String instanceId;
public Server() {
}
@DynamoDBHashKey
public String getId() {
return id;
}
// other standard getters and setters
}
推薦答案
2019更新
在 2019 年,自提出問(wèn)題以來(lái),這里似乎沒(méi)有任何變化.在 DynamoDB 中為非主鍵字段提供唯一性仍然很棘手.這是最近在亞馬遜上發(fā)布的一篇文章:https://aws.amazon.com/blogs/database/simulating-amazon-dynamodb-unique-constraints-using-transactions/
基本上,作者建議在同一個(gè)表中創(chuàng)建輔助記錄,而不是使用如下所述的附加表.
Basically, instead of using an additional table as described below, the author proposes creating auxiliary records in the same table.
例如,在下圖中,為確保 instance_id=2c5d0cc8d900 是唯一值,您必須添加具有人工主鍵值instance_id#2c5d0cc8d900"的記錄.如果插入成功,您可以插入主記錄本身.
For example, on the below picture, for ensuring that instance_id=2c5d0cc8d900 is a unique value, you have to add a record with an artificial primary key value "instance_id#2c5d0cc8d900". If the insert succeeds, you can insert the main record itself.
+--------------------------+-------------------------+--------+----------------
| id | instance_id | attr1 | other fields...
| | | |
| (primary key) | (a non-key field, | |
| | must be unique) | |
+--------------------------+-------------------------+--------+----------------
| instance_id#2c5d0cc8d900 | | |
| a9fd702a | 2c5d0cc8d900 | qwerty | ...
雖然這種方法可能效果很好,但我個(gè)人仍然更喜歡使用單獨(dú)的表格,如下面的原始答案所述.因?yàn)?,?dāng)從包含此類輔助記錄的表中讀取數(shù)據(jù)時(shí),您必須注意從實(shí)際記錄中過(guò)濾它們.
While this approach may work fine, I personally still prefer to use a separate table like described below in my original answer. Because, when reading data from a table that contains such auxiliary records, you have to care about filtering them from actual ones.
如果我正確理解了這個(gè)問(wèn)題,您希望確保不是哈希鍵的字段的唯一性.
If I correctly understood the question, you'd like to ensure uniqueness for a field which is not the hash key.
(我不知道你為什么不使用 instanceId
作為 Servers 表的哈希鍵,我猜你是有原因的).
(I'm not sure why you do not use instanceId
as the hash key for Servers table, I guess you have a reason for that).
我的回答:看起來(lái)如果不使用輔助表就無(wú)法做到這一點(diǎn).
這是您現(xiàn)有的服務(wù)器表:
Here is your existing Servers table:
+----------------------------------------------+
| Servers |
+----------------------------------------------+
| * id the hash key |
| * instanceId non-key field, must be unique|
| |
| * ... |
| * other fields |
| * ... |
+----------------------------------------------+
我會(huì)創(chuàng)建一個(gè)帶有 instanceId 作為哈希鍵的附加表:
I would create an additional table with instanceId as the hash key:
+----------------------------------------------+
| Instance |
+----------------------------------------------+
| * instanceId the hash key |
+----------------------------------------------+
有了這樣的表,在將記錄保存到服務(wù)器之前,您必須首先確保 instanceId 值是唯一的,方法是向 Instance 添加一條記錄 (putItem),提供類似 attribute_not_exists(instanceId)
的 ConditionExpression.
Having such a table, before saving a record into Servers, you have to
ensure first that instanceId value is unique by adding a record (putItem) into Instance, providing a ConditionExpression like attribute_not_exists(instanceId)
.
只有當(dāng) put 操作完成且沒(méi)有出現(xiàn) ConditionalCheckFailedException
錯(cuò)誤時(shí),您才能繼續(xù)將記錄添加到服務(wù)器中.
And only if the put operation completes without an ConditionalCheckFailedException
error, you can proceed with adding the record into Servers.
如果您想根據(jù) instanceId 和 imageId 這兩個(gè)字段的組合來(lái)確保服務(wù)器中記錄的唯一性,而不是 instanceId 使用這些字段的連接值作為輔助表中的單個(gè)字段:
If you'd like to ensure uniqueness of records in Servers based on combination of two fields, instanceId and imageId, instead of just instanceId use concatenated values of these fields as a single field in your aux table:
+----------------------------------------------+
| Instance_Image |
+----------------------------------------------+
| * instanceId_imageId the hash key |
+----------------------------------------------+
這篇關(guān)于DynamoDBMapper 僅在唯一時(shí)保存項(xiàng)目的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!