Android房间组合主键,排序顺序

Android room composite primary key, sort order

为了将旧数据库迁移到房间库,我必须等同于行

primary key(id1, id2 desc)

来自

create table t(
id1 integer not null, 
id2 integer not null,
.... 
primary key(id1, id2 desc)
)

我找不到如何定义复合索引或主键的排序顺序。好像Android房间没有特别的注解,或者注解参数见androidx.room.Entityandroidx.room.Index.

不支持吗?解决问题的其他方法是什么?在 id1id2 上创建常规复合键,并在所有 select 查询中设置 排序依据 ?

你可以像

那样做

SELECT select_list 从 table 订购方式 column_1 升序, column_2 描述;

详情https://www.sqlitetutorial.net/sqlite-order-by/

除非你的 table 是 WITHOUT ROWID,否则你的 table 中的主键只是一个单独的唯一索引。

所以你只需要在创建 table 之后创建你自己的索引。

Is an index needed for a primary key in SQLite?

查看 sqlite3 示例 - sqlite 只是为您创建一个单独的 sqlite_autoindex_t_with_pk_1 以及手动创建的索引。

sqlite> create table t_with_pk(id1 integer not null, id2 integer not null, primary key(id1, id2 desc));

sqlite> create table t_no_pk(id1 integer not null, id2 integer not null);    
sqlite> create unique index t_uniq_idx on t_no_pk(id1, id2 desc);

sqlite> select * from sqlite_master;

table|t_with_pk|t_with_pk|2|CREATE TABLE t_with_pk(id1 integer not null, id2 integer not null, primary key(id1, id2 desc))
index|sqlite_autoindex_t_with_pk_1|t_with_pk|3|
table|t_no_pk|t_no_pk|4|CREATE TABLE t_no_pk(id1 integer not null, id2 integer not null)
index|t_uniq_idx|t_no_pk|5|CREATE UNIQUE INDEX t_uniq_idx on t_no_pk(id1, id2 desc)

行为也相同

sqlite> explain query plan select * from t_with_pk order by id1, id2 desc;
QUERY PLAN
`--SCAN TABLE t_with_pk USING COVERING INDEX sqlite_autoindex_t_with_pk_1
sqlite> explain query plan select * from t_no_pk order by id1, id2 desc;
QUERY PLAN
`--SCAN TABLE t_no_pk USING COVERING INDEX t_uniq_idx

另请注意(关于@Developer 的回答)仅在 SELECT 语句中反转顺序需要 sqlite 创建临时索引

sqlite> explain query plan select * from t_no_pk order by id1, id2;
QUERY PLAN
|--SCAN TABLE t_no_pk USING COVERING INDEX t_uniq_idx
`--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY

Room 通过 RoomDatabase.Callback 支持原始查询,因此您可以覆盖 onCreate 回调方法并执行创建索引的原始 sql。