我正在学习Java 的android 开发。作为学习的一部分,我开始了一个使用 GTFS 数据开发 Transit App 的项目。
我有两个担忧:
数据文件大小:
性能: 如前所述,我尝试使用 FlatBuffer 来加速数据获取,看起来很有希望,但文件大小似乎是不使用 FlatBuffer 的缺点。因为您无法像我们在 sqlite db 中那样过滤字段上的数据。我尝试使用 FlatBuffer 从 A 站到 B 站单程。
任何专家建议将不胜感激?
谢谢
在 400 万行时,即使是最简单的表,例如
CREATE TABLE IF NOT EXISTS testit (id INTEGER PRIMARY KEY);
将占用 33Mb。
添加一个唯一的列,例如
CREATE TABLE IF NOT EXISTS testit (id INTEGER PRIMARY KEY, name TEXT UNIQUE);
然后基于将 A + id 值存储在名称列中,例如
....
大小跃升至133Mb。
如果没有 UNIQUE,那么只有 68Mb(即索引有空间成本(UNIQUE 约束使用索引))。
基于使用 Navicat 和以下 SQL 进行测试:-
DROP TABLE IF EXISTS testit;
CREATE TABLE IF NOT EXISTS testit (id INTEGER PRIMARY KEY/*, name TEXT UNIQUE*/);
WITH cte(counter) AS (SELECT 1 UNION ALL SELECT counter+1 FROM cte LIMIT 4000000)
INSERT OR IGNORE INTO testit SELECT counter/*,'A'||counter*/ FROM cte;
VACUUM;
-- DROP TABLE IF EXISTS testit;
考虑到上述情况,可能没有太大的空间来减少大小。特别是考虑快速浏览一下https://developers.google.com/transit/gtfs/examples/gtfs-feed
表示有可能使用更少的空间来存储某些数据。
Id 似乎使用整数(长整型)存储为文本。可以节省一些空间并且效率更高。也就是说,您对列使用
INTEGER PRIMARY KEY
。这将使它们成为 rowid 的别名,这将比其他索引更快。请参阅https://www.sqlite.org/rowidtable.html
- obviously references/ relationships would have to be amended accordingly.
- this would not only reduce the size of the table, but also the size of the index (primary key).
- The downside could be accommodating/converting new/changed/downloaded data
日期/时间
日期和时间似乎都是文本形式的,可以将它们存储为整数,从而减少大小。如果以与 SQLite 的日期/时间函数理解的格式一致的方式存储,则可以以合适的格式提取数据。请参阅https://sqlite.org/lang_datefunc.html
你不是说标准化吗?由于数据重复,反规范化可能会增加数据量。
参见 VACUUM (https://www.sqlite.org/lang_vacuum.html) 它可能会有用。
考虑日志记录模式,请参阅https://sqlite.org/wal.html。一个实体(表的触发器、视图、索引)将至少占用一个页面(默认页面大小为 4k)。
索引大小将与被索引的表的大小相关,因此请谨慎使用索引。
我建议使用 SQLite 工具(例如 DB Browser for SQLite)来确定最佳架构。
使用 EXPLAIN/EXPLAIN QUERY PLAN 来协助优化查询,参见 https://sqlite.org/lang_explain.html.
关于这个问题有什么消息吗? 我在尝试将具有近 100 万行以上的 stop_times.txt 的 GTFS 文件加载到 SQLite 时遇到同样的障碍。导入过程需要几十秒,在某些设备上我遇到 OOM 错误。