阿帕奇点燃 "Update of composite key column is not supported"
Apache Ignite "Update of composite key column is not supported"
我有一个以 AffinityKey 作为键的缓存,我想插入一个条目。如果我尝试使用 SQL-Insert 语句插入条目,我会收到一个异常,指出“不支持更新复合键列”,我猜这是因为 AffinityKey 是一个复合键。
在 https://ignite.apache.org/docs/latest/SQL/indexes#indexing-nested-objects i have read that if you are using indexed nested objects you will no longer be able to use insert or update statements but it is not mentioned on https://ignite.apache.org/docs/latest/data-modeling/affinity-collocation 上用于复合键。
使用复合键是否也会导致插入和更新语句不再可用或者我是否遗漏了什么?
示例:
// creating cache using QueryEntities
cache = ignite.CreateCache<AffinityKey, MyClass>(new CacheClientConfiguration(cacheConfiguration)
{
Name = "MyCache",
QueryEntities = new[]
{
new QueryEntity(typeof(AffinityKey), typeof(MyClass)){ TableName = "MyTable" }
},
});
// insert statement
cache.Query(
new SqlFieldsQuery(
"INSERT INTO " +
"MyTable ( " +
"_key, " +
$"{nameof(MyClass.Text)} ) " +
"VALUES ( " +
"?, " +
"? )"
)
{
Arguments = new object[]
{
new AffinityKey("Key1", "AffinityKey1"),
"TextValue"
},
});
解法:
正如@Alexandr Shapkin 在下面所述,将“IGNITE_SQL_ALLOW_KEY_VAL_UPDATES”设置为 true 可以通过 SQL 更新使用复合键添加的条目。
任何感兴趣的人 https://ignite.apache.org/docs/latest/setup#setting-ignite-system-properties 展示了如何列出可用的点燃 properties/environment 变量并附有简短说明。
你在混淆概念。
在 Apache Ignite 中,您可以通过多种方式访问或插入数据。一种是使用缓存 API,如 cache#get
、cache#put
,另一种选择是 - 使用 SQL,如 INSERT
、SELECT
,等等
因为最终一切都只是下面的一对 key-value,Ignite 提供了一个特殊的 SQL _key
和 _val
属性来访问相应的值。
问题是 - 如果您不需要交替使用缓存 API 和 SQL 并且可以只使用 SQL,那么您不需要设置 _key
完全没有。
另一方面,如果您需要使用两个 API,例如,就像在您的示例中一样用 QueryEntity
定义,则需要正确指定 _key
字段。
考虑 this 示例:
IgniteCache<AffinityKey<Long>, Person> colPersonCache = Ignition.ignite().cache(PERSON_CACHE);
Person p1 = new Person(org1, "John", "Doe", 2000, "John Doe has Master Degree.");
colPersonCache.put(p1.key(), p1);
...
这样做很好:
colPersonCache.query(new SqlFieldsQuery(
"INSERT INTO Person (id, orgId, firstName, lastName, salary, resume) " +
"VALUES ( ?, ?, ?, ?, ?, ?)")
.setArgs(6, 2, "first", "last", 1, "Master Degree")).getAll();
但在那种情况下,您将无法使用缓存定位记录 API:
// the following line returns null, but you can use SQL to locate the record
colPersonCache.get(new AffinityKey<Long>(6L,2L));
但是如果你使用_key
:
colPersonCache.query(new SqlFieldsQuery(
"INSERT INTO Person (_key, id, orgId, firstName, lastName, salary, resume) " +
"VALUES (?, ?, ?, ?, ?, ?, ?)")
.setArgs(new AffinityKey<Long>(6L,2L), 6, 2, "first", "last", 1, "Master Degree")).getAll();
缓存 API 现在执行 return 值:
colPersonCache.get(new AffinityKey<Long>(6L,2L));
//Person [id=6, orgId=2, lastName=last, firstName=first, salary=1.0, resume=Master Degree]
注.
有一个特殊的限制来避免可能的密钥不同步,为了使最新的查询(和问题中的原始查询)工作,您必须设置以下环境 属性:
System.setProperty(IgniteSystemProperties.IGNITE_SQL_ALLOW_KEY_VAL_UPDATES, "true");
我有一个以 AffinityKey 作为键的缓存,我想插入一个条目。如果我尝试使用 SQL-Insert 语句插入条目,我会收到一个异常,指出“不支持更新复合键列”,我猜这是因为 AffinityKey 是一个复合键。 在 https://ignite.apache.org/docs/latest/SQL/indexes#indexing-nested-objects i have read that if you are using indexed nested objects you will no longer be able to use insert or update statements but it is not mentioned on https://ignite.apache.org/docs/latest/data-modeling/affinity-collocation 上用于复合键。
使用复合键是否也会导致插入和更新语句不再可用或者我是否遗漏了什么?
示例:
// creating cache using QueryEntities
cache = ignite.CreateCache<AffinityKey, MyClass>(new CacheClientConfiguration(cacheConfiguration)
{
Name = "MyCache",
QueryEntities = new[]
{
new QueryEntity(typeof(AffinityKey), typeof(MyClass)){ TableName = "MyTable" }
},
});
// insert statement
cache.Query(
new SqlFieldsQuery(
"INSERT INTO " +
"MyTable ( " +
"_key, " +
$"{nameof(MyClass.Text)} ) " +
"VALUES ( " +
"?, " +
"? )"
)
{
Arguments = new object[]
{
new AffinityKey("Key1", "AffinityKey1"),
"TextValue"
},
});
解法: 正如@Alexandr Shapkin 在下面所述,将“IGNITE_SQL_ALLOW_KEY_VAL_UPDATES”设置为 true 可以通过 SQL 更新使用复合键添加的条目。
任何感兴趣的人 https://ignite.apache.org/docs/latest/setup#setting-ignite-system-properties 展示了如何列出可用的点燃 properties/environment 变量并附有简短说明。
你在混淆概念。
在 Apache Ignite 中,您可以通过多种方式访问或插入数据。一种是使用缓存 API,如 cache#get
、cache#put
,另一种选择是 - 使用 SQL,如 INSERT
、SELECT
,等等
因为最终一切都只是下面的一对 key-value,Ignite 提供了一个特殊的 SQL _key
和 _val
属性来访问相应的值。
问题是 - 如果您不需要交替使用缓存 API 和 SQL 并且可以只使用 SQL,那么您不需要设置 _key
完全没有。
另一方面,如果您需要使用两个 API,例如,就像在您的示例中一样用 QueryEntity
定义,则需要正确指定 _key
字段。
考虑 this 示例:
IgniteCache<AffinityKey<Long>, Person> colPersonCache = Ignition.ignite().cache(PERSON_CACHE);
Person p1 = new Person(org1, "John", "Doe", 2000, "John Doe has Master Degree.");
colPersonCache.put(p1.key(), p1);
...
这样做很好:
colPersonCache.query(new SqlFieldsQuery(
"INSERT INTO Person (id, orgId, firstName, lastName, salary, resume) " +
"VALUES ( ?, ?, ?, ?, ?, ?)")
.setArgs(6, 2, "first", "last", 1, "Master Degree")).getAll();
但在那种情况下,您将无法使用缓存定位记录 API:
// the following line returns null, but you can use SQL to locate the record
colPersonCache.get(new AffinityKey<Long>(6L,2L));
但是如果你使用_key
:
colPersonCache.query(new SqlFieldsQuery(
"INSERT INTO Person (_key, id, orgId, firstName, lastName, salary, resume) " +
"VALUES (?, ?, ?, ?, ?, ?, ?)")
.setArgs(new AffinityKey<Long>(6L,2L), 6, 2, "first", "last", 1, "Master Degree")).getAll();
缓存 API 现在执行 return 值:
colPersonCache.get(new AffinityKey<Long>(6L,2L));
//Person [id=6, orgId=2, lastName=last, firstName=first, salary=1.0, resume=Master Degree]
注.
有一个特殊的限制来避免可能的密钥不同步,为了使最新的查询(和问题中的原始查询)工作,您必须设置以下环境 属性:
System.setProperty(IgniteSystemProperties.IGNITE_SQL_ALLOW_KEY_VAL_UPDATES, "true");