向SQLite暗示始终对特定列进行排序

时间:2018-11-12 07:34:24

标签: sql sqlite

我在SQLite数据库中有下表

CREATE TABLE `log` (
  `time` REAL NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `data` BLOB NOT NULL
) WITHOUT ROWID;

CREATE INDEX `time_index` ON `log`(`time`);

创建索引是因为查询频率最高

SELECT * FROM `log` WHERE `time` BETWEEN ? AND ?

由于添加新记录的时间将一直是当前时间,因此此处实际上并不需要索引。因此,我想“告诉” SQLite引擎,例如“ ”。这些行将与“时间”列一起添加,该列始终具有递增的值(类似于AUTO_INCREMENT),如果出现问题,我将承担全部责任”。

有可能吗?

2 个答案:

答案 0 :(得分:1)

您是否会遇到问题,取决于您认为无法使用的方式:-

CREATE TABLE `log` (
  `time` REAL NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `data` BLOB NOT NULL
) WITHOUT ROWID;

因为:-

  

每个WITHOUT ROWID表必须具有一个PRIMARY KEY。引发错误   如果带有WITHOUT ROWID子句的CREATE TABLE语句缺少   首要的关键。   Clustered Indexes and the WITHOUT ROWID Optimization

因此,您最好将时间列设置为主键。


  

,但问题是REAL的精度不足以处理   微秒分辨率,因此两个相邻记录可能具有   违反主键约束的相同时间值。

然后,您可以使用复合的PRIMARY KEY,其中所需的精度由多列(第二列可能会足够)满足,也许遵循:-

CREATE TABLE log (
    time_datepart INTEGER, 
    time_microsecondpart, 
     data BLOB NOt NULL, 
     PRIMARY KEY (time_datepart,time_microsecondpart)
) WITHOUT ROWID;

time_microsecondpart列不必一定是微秒,它可以是从另一个表派生的计数器,类似于使用AUTOINCREMENT时如何使用 sqlite_sequence 表(除了需要包含行附加到的表的名称)。

答案 1 :(得分:1)

您不需要单独的索引。您要声明该列为主键:

CREATE TABLE `log` (
  `time` REAL NOT NULL DEFAULT CURRENT_TIMESTAMP PRIMARY KEY,
  `data` BLOB NOT NULL
) WITHOUT ROWID;

这将基于主键为log创建单个b树索引。在其他数据库中,该结构将称为“聚集索引”。您可能已经读过documentation,但无论如何我还是在引用它。