HarmonyOS 鸿蒙Next数据库中使用'bigint'类型字段,需要用于排序、大于、小于查询

HarmonyOS 鸿蒙Next数据库中使用’bigint’类型字段,需要用于排序、大于、小于查询 数据库存储某个字段类型’bigint’

现在需要通过这个字段进行greaterThanlessThan、greaterThanOrEqualTo、order等查询操作,有什么替换方案或者方法吗?

该字段使用雪花算法生成,例:1998643673155383296

背景知识:https://developer.huawei.com/consumer/cn/forum/topic/0202197197810247483?fid=0109140870620153026


更多关于HarmonyOS 鸿蒙Next数据库中使用'bigint'类型字段,需要用于排序、大于、小于查询的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

直接用字符串拼接的sql语句替代那些谓词操作吧!

尴尬的点就在这里,雪花算法生成的是64位的整数,sqlite3的integer类型也是64位的整数,完美匹配。但是ts的number就会导致精度丢失,而用ts用bigint数据库就要对应UNLIMITED INT类型,这个就不支持那些谓词操作。

有个思路你可以试试,关系数据库中就用integer类型,数据库的增删改查就用字符串拼接的sql语句,查询到的这个雪花id字段,就用getString,然后在转为bigint如果值类型为INTEGER,值大于 Number.MAX_SAFE_INTEGER 或小于 Number.MIN_SAFE_INTEGER 且不希望丢失精度,建议使用getString接口获取。

更多关于HarmonyOS 鸿蒙Next数据库中使用'bigint'类型字段,需要用于排序、大于、小于查询的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


参考:

一、替代方案核心思路

1. 转换为字符串存储(推荐)

通过将bigint数值转换为固定长度字符串存储,利用字符串的字典序比较特性实现范围查询:

// 建表示例
const CREATE_TABLE_SQL = `
  CREATE TABLE IF NOT EXISTS data_table (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    bigint_str TEXT  -- 存储定长字符串格式的bigint
  )`;

// 数值转定长字符串(示例为10位)
function toFixedLengthString(value: bigint): string {
  return value.toString().padStart(10, '0');  // 不足位数补零
}

// 查询时使用字符串比较
condition.greaterThan("bigint_str", toFixedLengthString(BigInt(1000)));

2. 拆分高低位存储

将bigint拆分为高位和低位两部分,存储为两个INTEGER字段:

// 建表示例
const CREATE_TABLE_SQL = `
  CREATE TABLE IF NOT EXISTS data_table (
    id INTEGER PRIMARY KEY,
    high INTEGER,  -- 存储高位
    low INTEGER    -- 存储低位
  )`;

// 范围查询时组合条件
condition.greaterThan("high", 0)
  .or()
  .and(condition.equalTo("high", 0), condition.greaterThan("low", 1000));

3. 应用层过滤(小数据量适用)

先获取全量数据,在内存中进行过滤和排序:

// 查询全量数据
let resultSet = await database.query(condition);

// 应用层处理
let filteredData = resultSet.resultList.filter(item => 
  BigInt(item.bigintField) > BigInt(1000)
).sort((a, b) => 
  Number(BigInt(a.bigintField) - BigInt(b.bigintField))
);

二、方案选择建议

方案 适用场景 优点 缺点
字符串转换 数值范围较大且长度固定 支持原生谓词查询 需要严格补零控制
高低位拆分 超大数值范围(超过2^53) 支持复杂范围查询 查询逻辑复杂
应用层过滤 数据量小(千级以下) 实现简单 性能差,内存消耗大

三、注意事项

  • 精度保障:若使用number类型替代(当数值在Number.MAX_SAFE_INTEGER范围内时),需注意:
// 建表使用INTEGER类型
CREATE TABLE data_table (value INTEGER);

// 查询时可直接使用谓词
condition.greaterThan("value", 1000);
  • 数据转换风险:若原bigint字段已存在数据,需要执行ALTER TABLE迁移时,应通过临时表方案实现字段类型变更。
  • 排序性能:字符串方案在排序时可能比数值类型慢,建议结合索引优化。

雪花ID转成字符串存入数据库,数据库查询字符串会通过ASCII转义成数字,只要雪花ID有规律,则字符串转ASCII的结果就有规律。就能完成排序查询,代码不够严谨,但逻辑可行,真实实践通过。 这算不算运行在BUG上的功能?

开发者您好,您现在是怎么完成该字段的排序查询的,字符串转义成数字是数据库排序查询时的默认行为,还是说你们使用了什么数据库函数去转义成字符串,您当前是怎么排序查询的请确认下,方便的话也请提供下您的查询字段的代码片段,

雪花算法生成的 bigint 通常包含时间戳、机器ID、序列号等信息,可以考虑将 bigint 拆分为高位和低位两部分存储,然后进行排序查询

感谢帮助,查询时怎么查双字段并列查询吗,

在HarmonyOS鸿蒙Next中,数据库支持使用bigint类型字段进行排序、大于、小于查询。bigint类型用于存储大整数,适用于需要大范围整数值的场景。在查询时,可以直接在SQL语句中使用ORDER BY进行排序,或使用>、<等比较运算符进行范围查询。

在HarmonyOS Next中,如果需要在数据库中对bigint类型字段(如雪花算法生成的ID)进行排序、大于、小于等查询,可以使用以下方案:

  1. 使用字符串类型存储:将bigint值转换为字符串(如String类型)存入数据库。查询时,直接对字符串进行greaterThanlessThanorder操作。由于字符串按字典序比较,对于数字型字符串(如"1998643673155383296"),排序和比较结果与数值比较一致。但需确保所有值长度一致(如补零),否则可能导致比较错误(如"100"比"99"小)。

  2. 使用数值范围拆分:如果bigint值范围可控,可拆分为两个integer字段存储(如高位和低位)。查询时对高位和低位分别比较,但逻辑较复杂,适用于特定场景。

  3. 应用层处理:将数据加载到内存中,在应用层进行排序和过滤。适用于数据量小的场景,不推荐大数据量操作。

推荐方案: 使用字符串存储bigint值,并利用数据库的字符串比较功能。例如:

  • 存储时:将1998643673155383296转为"1998643673155383296"
  • 查询时:直接使用greaterThan("1998643673155383296")order()等操作。

此方法简单高效,且兼容HarmonyOS Next的数据管理能力。注意确保字符串格式统一,避免前导零等问题影响比较结果。

回到顶部