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.Entity或androidx.room.Index.
不支持吗?解决问题的其他方法是什么?在 id1 和 id2 上创建常规复合键,并在所有 select 查询中设置 排序依据 ?
你可以像
那样做
SELECT
select_list
从
table
订购方式
column_1 升序,
column_2 描述;
除非你的 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。
为了将旧数据库迁移到房间库,我必须等同于行
primary key(id1, id2 desc)
来自
create table t(
id1 integer not null,
id2 integer not null,
....
primary key(id1, id2 desc)
)
我找不到如何定义复合索引或主键的排序顺序。好像Android房间没有特别的注解,或者注解参数见androidx.room.Entity或androidx.room.Index.
不支持吗?解决问题的其他方法是什么?在 id1 和 id2 上创建常规复合键,并在所有 select 查询中设置 排序依据 ?
你可以像
那样做SELECT select_list 从 table 订购方式 column_1 升序, column_2 描述;
除非你的 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。