代码之家  ›  专栏  ›  技术社区  ›  Alexander Solovets

向SQLite发出提示,说明始终对特定列进行排序

  •  0
  • Alexander Solovets  · 技术社区  · 6 年前

    我在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引擎 这些行将添加“time”列,该列始终具有递增值(类似于AUTO_INCREMENT),如果出现问题,我将承担所有责任 ".

    有可能吗?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Gordon Linoff    6 年前

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

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

    这将为 log 基于主键。在其他数据库中,这种结构称为“聚集索引”。你可能已经读过 documentation 但我还是在引用它。

        2
  •  1
  •   MikeT    6 年前

    您是否会有问题,取决于您认为您不能使用的方式:-

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

    因为:-

    每个没有ROWID表的表都必须有主键。出现错误 如果带有WITHOUT ROWID子句的CREATE TABLE语句缺少 主键。 Clustered Indexes and the WITHOUT ROWID Optimization

    所以你最好把 时间 列主键。


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

    然后,您可以使用复合主键,其中所需的精度由多个列(第二列可能已足够)满足,可能沿以下行:-

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

    time_microsecondpart列不一定是微秒,它可以是从另一个表派生的计数器,类似于 sqlite_序列 使用自动增量时使用表(不需要包含行所附加表的名称的列)。