3. 数据存储设计:SQLite数据库表结构

好,咱们接着聊。传感器数据采集上来了,总得有个地方存吧?

我个人习惯用 SQLite。为什么?轻量、免安装、一个文件搞定。在嵌入式设备或者 PC 上做原型验证,它都是首选。你想想看,要是为了存几个温度值就去装个 MySQL,是不是有点大炮打蚊子?

3.1 核心表:sensor_data

这是最核心的一张表。所有传感器采集到的历史数据,最终都会落在这里。

我在项目中遇到过一个问题:一开始只设计了「温度」和「湿度」两个字段,后来客户要加「光照强度」和「CO2浓度」,结果只能改表结构。嗯,这其实挺麻烦的。所以我的建议是——把传感器类型和数值拆开

来看我推荐的表结构:

CREATE TABLE sensor_data (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    sensor_id   TEXT    NOT NULL,       -- 传感器编号,比如 'temp_01'
    sensor_type TEXT    NOT NULL,       -- 传感器类型,比如 'temperature'
    value       REAL    NOT NULL,       -- 采集到的数值
    unit        TEXT    NOT NULL,       -- 单位,比如 '°C', '%RH'
    timestamp   TEXT    NOT NULL,       -- 采集时间,ISO 8601 格式
    quality     INTEGER DEFAULT 1      -- 数据质量标记:1=正常,0=异常
);

为什么要这么设计?说白了,就是为了灵活。以后加任何新传感器,都不需要改表结构,直接往里插数据就行。

关键点:sensor_id 和 sensor_type 分开。sensor_id 是具体设备,sensor_type 是测量类型。同一个传感器可能同时测温度和湿度,所以这两者不能混为一谈。

3.2 辅助表:sensor_info

光有数据还不够。你总得知道每个传感器装在哪个位置、量程是多少、校准日期是什么时候吧?

所以我通常会再加一张辅助表:

CREATE TABLE sensor_info (
    sensor_id       TEXT PRIMARY KEY,   -- 传感器编号
    sensor_type     TEXT NOT NULL,      -- 传感器类型
    location        TEXT,               -- 安装位置,比如 '温室A区-3号架'
    range_min       REAL,               -- 量程下限
    range_max       REAL,               -- 量程上限
    install_date    TEXT,               -- 安装日期
    calibration_date TEXT,              -- 最近校准日期
    notes           TEXT                -- 备注
);

这张表平时查询不多,但做数据分析或者排查故障时特别有用。我曾经有一次发现某个温度值异常偏高,查了 sensor_info 才发现那个传感器装在暖气管道旁边——嗯,位置信息帮了大忙。

3.3 索引设计

数据量大了以后,查询速度会变慢。这时候索引就派上用场了。

我建议至少建这两个索引:

CREATE INDEX idx_sensor_data_time 
ON sensor_data(timestamp);

CREATE INDEX idx_sensor_data_sensor_time 
ON sensor_data(sensor_id, timestamp);

第一个索引用于按时间范围查询。第二个索引用于查某个传感器在某个时间段的数据。这两个查询场景在实际项目中出现频率最高。

小技巧:不要给所有字段都建索引。索引虽然能加速查询,但会拖慢写入速度。对于「温室环境数据」这种写入频繁的场景,索引要精不要多。

3.4 数据归档策略

数据会越积越多。一年下来,几百万条记录很正常。

我的做法是:按月份分表。比如 sensor_data_2024_01、sensor_data_2024_02……查询时根据时间范围自动路由到对应的表。

当然,如果你不想搞那么复杂,也可以保留一张大表,定期删除旧数据。比如只保留最近 90 天的数据。

注意:删除数据前一定要备份!我曾经手滑删错了月份,结果客户要查三个月前的数据,我只能从备份里恢复。那滋味,不好受。

3.5 完整建表脚本

最后,给你一个可以直接用的完整脚本:

-- 传感器信息表
CREATE TABLE IF NOT EXISTS sensor_info (
    sensor_id       TEXT PRIMARY KEY,
    sensor_type     TEXT NOT NULL,
    location        TEXT,
    range_min       REAL,
    range_max       REAL,
    install_date    TEXT,
    calibration_date TEXT,
    notes           TEXT
);

-- 传感器数据表
CREATE TABLE IF NOT EXISTS sensor_data (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    sensor_id   TEXT    NOT NULL,
    sensor_type TEXT    NOT NULL,
    value       REAL    NOT NULL,
    unit        TEXT    NOT NULL,
    timestamp   TEXT    NOT NULL,
    quality     INTEGER DEFAULT 1,
    FOREIGN KEY (sensor_id) REFERENCES sensor_info(sensor_id)
);

-- 索引
CREATE INDEX IF NOT EXISTS idx_sensor_data_time 
ON sensor_data(timestamp);

CREATE INDEX IF NOT EXISTS idx_sensor_data_sensor_time 
ON sensor_data(sensor_id, timestamp);

嗯,这个结构我用了好几年,在好几个项目里都验证过。你直接拿去用,基本不会出大问题。

下一章咱们聊聊怎么用 Python 操作这个数据库,把数据写进去、读出来。