尽管主键顺序是 desc,但行的 SQLite 顺序是杂乱的

SQLite order of the rows is juggled though primary key order is desc

已经创建了一个 SQLite table 如下

CREATE TABLE HIST_DATA (DT INTEGER NOT NULL PRIMARY KEY DESC, DateOfEntry TEXT);

主键是UNIXEPOCH秒。插入查询是

INSERT INTO HIST_DATA (DT, DateOfEntry) VALUES (strftime('%s', '2020-01-31', 'start of month'), '2020-01-31');

触发查询

SELECT * FROM HIST_DATA;

结果是

DT          DateOfEntry
----------  -----------
1577836800  2020-01-31
1580515200  2020-02-28
1583020800  2020-03-31
1585699200  2020-04-30
1588291200  2020-05-31
1590969600  2020-06-30
1546300800  2019-01-31
1548979200  2019-02-28
1551398400  2019-03-31
1554076800  2019-04-30
1556668800  2019-05-31

即使在主键上指定了 DESC 顺序,为什么 table 没有按主键的降序排列?有人可以指导我吗?


更新:

我希望在不使用 ORDER BY DT DESC 的情况下从 table 获取第一行,因为我认为这会减慢查询速度并最终减慢 API,这只是一个误解。可以通过简单的SELECT * FROM HIST_DATA ORDER BY DT DESC LIMIT 1;.

来实现

您似乎假设 table 具有固有的顺序,以某种方式基于主键,因此以下查询将 return 行按顺序排列:

SELECT * FROM HIST_DATA;

事实并非如此。 SQL tables 表示无序的行集。没有固有的顺序。获得排序结果的唯一方法是在查询中添加一个 ORDER BY 子句:

SELECT * FROM HIST_DATA ORDER BY DT DESC;

没有 ORDER BY 子句,结果集中行的顺序是未定义的。数据库可以随意对行进行排序,结果可能不一定与同一查询的后续执行一致。

您正在混合使用 DATA 和 INDEXES。

你的数据进入你的table以下时间:最晚进入,最晚在table。因此,您可能会假设它是您的行的逻辑顺序 :: 你会错的,因为这种顺序是不确定的,这意味着如果您没有为查询指定 ORDER BY 子句,您可能会在随机顺序。

您的查询 SELECT * FROM HIST_DATA; 保持了正确的顺序(最后插入),但这只是运气。请始终注意,如果您不指定 ORDER BY 子句,情况可能并非总是如此。

当您定义 PRIMARY KEY DESC 时,它会创建一个索引,其中最大的 DT 是索引中的第一个,最小的 DT 是索引中的最后一个。但这根本不会修改您的数据顺序。它只是有助于 ORDER BY DT DESC 更快