当前位置: 首页 > news >正文

SQLite数据类型

目录

1 SQLite的类型概述

1.1 存储类(Storage Classes)

1.2 类型亲和性(Type Affinity)

2 类型亲和性分配规则

3  数据类型详细说明

3.1 INTEGER类型

3.2 REAL类型

3.3 TEXT类型

3.4 BLOB类型

3.5 NULL类型

3.6 NUMERIC类型

4 特殊类型和类型转换

4.1 BOOLEAN

4.2 DATE, DATETIME, TIMESTAMP

4.3 DECIMAL和精确数值

5 类型转换和兼容性

5.2 显式类型转换

5.2 隐式类型转换规则

5.3 类型灵活性示例

6 数据类型的实际应用示例

6.1 主键和ROWID

6.2 处理二进制数据(BLOB)

6.3 存储和查询JSON数据

6.4 日期时间处理

6.5 高效存储大表的考虑

7 数据类型的最佳实践

8 SQLite类型系统的优缺点

8.1 优点

8.2 缺点

9 总结


SQLite采用了一种不同于大多数其他SQL数据库的类型系统,称为"动态类型系统"或"存储类系统"。下面将详细介绍SQLite的数据类型体系、类型亲和性、类型存储及其使用特点。

1 SQLite的类型概述

1.1 存储类(Storage Classes)

SQLite有5种基本存储类:

存储类描述存储方式
NULL表示空值NULL
INTEGER有符号整数1, 2, 3, 4, 6或8字节,取决于存储的数值大小
REAL浮点数8字节的IEEE浮点数
TEXT文本字符串UTF-8、UTF-16BE或UTF-16LE编码
BLOB二进制大对象按照输入存储(完全保留)

1.2 类型亲和性(Type Affinity)

当创建表时,SQLite会为每列分配一种类型亲和性。类型亲和性决定了SQLite如何尝试转换存储的值:

  1. INTEGER - 倾向于将数据存储为INTEGER

  2. TEXT - 倾向于将数据存储为TEXT

  3. REAL - 倾向于将数据存储为REAL

  4. NUMERIC - 尝试存储为INTEGER或REAL;如果不行则为TEXT

  5. BLOB - 不做任何类型转换,按原样存储

2 类型亲和性分配规则

SQLite根据列的声明类型决定其类型亲和性,规则如下:

  1. INTEGER亲和性:如果类型包含字符串"INT"(不区分大小写)

    • 例如:INT, INTEGER, BIGINT, SMALLINT, TINYINT

  2. TEXT亲和性:如果类型包含以下任一字符串(不区分大小写):

    • “CHAR”, “CLOB”, “TEXT”

    • 例如:VARCHAR, NCHAR, CLOB, TEXT

  3. BLOB亲和性:仅当列的声明类型为"BLOB"(不区分大小写)

  4. REAL亲和性:如果类型包含以下任一字符串(不区分大小写):

    • “REAL”, “FLOA”, “DOUB”

    • 例如:REAL, FLOAT, DOUBLE, DOUBLE PRECISION

  5. NUMERIC亲和性:所有其他情况,包括:

    • NUMERIC, DECIMAL, BOOLEAN, DATE, DATETIME

3  数据类型详细说明

3.1 INTEGER类型

CREATE TABLE example (id INTEGER PRIMARY KEY,count INTEGER,big_num BIGINT,small_num SMALLINT
);

注意事项:  

  • 存储有符号整数值

  • 最大可达8字节(64位),范围:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807

  • 可用于主键(特别是INTEGER PRIMARY KEY)

  • 与JavaScript不同,SQLite的INTEGER可以精确表示大整数,不会有精度损失

3.2 REAL类型

CREATE TABLE measurements (temperature REAL,distance FLOAT,calculation DOUBLE
);

注意事项:  

  • 存储8字节的IEEE浮点数

  • 范围约为±1.79×10^308,精度为15-16位十进制数字

  • 所有FLOAT, DOUBLE等类型都会映射为REAL

  • 受浮点数固有的精度限制影响

3.3 TEXT类型

CREATE TABLE messages (message TEXT,name VARCHAR(100),description NVARCHAR(200)
);

注意事项:  

  • 存储文本字符串,默认为UTF-8编码

  • 也可以存储为UTF-16BE或UTF-16LE

  • 没有固定的长度限制(除了整个数据库的大小限制)

  • VARCHAR(N)中的长度限制仅作为文档说明,不强制执行

3.4 BLOB类型

CREATE TABLE files (file_id INTEGER PRIMARY KEY,file_name TEXT,file_data BLOB
);

注意事项:  

  • 原样存储二进制数据

  • 适用于图像、音频、视频、加密数据等任何二进制内容

  • 不进行任何编码或转换

  • 没有大小限制(除了数据库大小限制) 

3.5 NULL类型

CREATE TABLE users (user_id INTEGER PRIMARY KEY,middle_name TEXT DEFAULT NULL
);

注意事项:  

  • 表示缺少值

  • 与其他数据库的NULL类似

  • NULL是一个特殊值,不等于零、空字符串或任何其他值

3.6 NUMERIC类型

CREATE TABLE financial (amount NUMERIC,tax DECIMAL(10,2),is_completed BOOLEAN,transaction_date DATE
);

注意事项:  

  • 可以存储为INTEGER、REAL或TEXT,具体取决于值

  • 整数值优先存储为INTEGER

  • 非整数数值存储为REAL

  • 不符合数值格式的值存储为TEXT

4 特殊类型和类型转换

4.1 BOOLEAN

SQLite没有专门的布尔类型,通常用以下方式表示:

CREATE TABLE settings (feature_enabled BOOLEAN  -- 实际存储为INTEGER: 0(false)或1(true)
);

注意事项: 

  • 存储为INTEGER: 0(false)或1(true)

  • 在查询中,所有非0值和非NULL值都被视为true

4.2 DATE, DATETIME, TIMESTAMP

SQLite没有专门的日期或时间类型,通常以以下方式存储:

CREATE TABLE events (event_date DATE,          -- 实际上是TEXT、REAL或INTEGERcreated_at TIMESTAMP,     -- 实际上是TEXT、REAL或INTEGERmeeting_time DATETIME     -- 实际上是TEXT、REAL或INTEGER
);

常见日期时间存储格式:

  1. TEXT格式(推荐)- 如 ‘2023-05-15 15:30:00’

  • ISO8601格式: ‘YYYY-MM-DD HH:MM:SS.SSS’
  • 最便于人类阅读和理解
  1. INTEGER格式 - Unix时间戳(自1970-01-01 00:00:00 UTC以来的秒数)

  • 适合于日期比较和计算
  1. REAL格式 - Julian日期格式(自公元前4714年起的天数)

  • 可以精确到毫秒级别

SQLite提供内置日期函数处理这些格式:

  • date()time()datetime()

  • strftime()

  • julianday()

4.3 DECIMAL和精确数值

SQLite没有专门的DECIMAL或MONEY类型:

CREATE TABLE financial (price DECIMAL(10,2)  -- 实际上是NUMERIC亲和性
);

对于需要精确计算的财务数据,有两种方案:

  1. 整数存储:将金额乘以100或10000存储为INTEGER

    -- 存储$123.45为12345
    INSERT INTO financial(price_cents) VALUES (12345);
    -- 查询时除以100
    SELECT price_cents/100.0 AS price FROM financial;
  2. TEXT存储:将精确小数存储为TEXT,需要计算时转换

5 类型转换和兼容性

5.2 显式类型转换

-- INTEGER转换
SELECT CAST('123' AS INTEGER);  -- 返回123
SELECT CAST(123.45 AS INTEGER); -- 返回123 (截断)
​
-- REAL转换
SELECT CAST('123.45' AS REAL);  -- 返回123.45
SELECT CAST(123 AS REAL);       -- 返回123.0
​
-- TEXT转换
SELECT CAST(123 AS TEXT);       -- 返回'123'
SELECT CAST(123.45 AS TEXT);    -- 返回'123.45'

5.2 隐式类型转换规则

SQLite会根据上下文自动转换类型:

  1. 数值上下文中的TEXT

    SELECT '123' + 456;  -- 579 (TEXT转为INTEGER)
    SELECT '123.45' + 1; -- 124.45 (TEXT转为REAL)
  2. TEXT上下文中的数值

    SELECT 123 || 'abc';  -- '123abc' (INTEGER转为TEXT)
    SELECT 123.45 || 'x'; -- '123.45x' (REAL转为TEXT)
  3. 比较操作中的混合类型

    SELECT 123 = '123';  -- 1 (true,比较前进行转换)

5.3 类型灵活性示例

CREATE TABLE flexible(x);
INSERT INTO flexible VALUES(NULL),(42),(3.14159),('hello'),(x'ABCD');  -- BLOB值
​
SELECT typeof(x), x FROM flexible;

结果:

typeof(x)   x
---------   ------
NULL        NULL
INTEGER     42
REAL        3.14159
TEXT        hello
BLOB        ABCD

6 数据类型的实际应用示例

6.1 主键和ROWID

-- 使用INTEGER PRIMARY KEY (推荐)
CREATE TABLE users (user_id INTEGER PRIMARY KEY, -- 与内部ROWID关联username TEXT UNIQUE
);
​
-- 隐式ROWID
CREATE TABLE messages (content TEXT-- 自动创建一个隐藏的ROWID列
);
​
-- 显式禁用ROWID
CREATE TABLE settings (key TEXT PRIMARY KEY,value TEXT
) WITHOUT ROWID; -- 节省空间,但不自动生成ID

6.2 处理二进制数据(BLOB)

-- 存储图像文件
CREATE TABLE images (image_id INTEGER PRIMARY KEY,name TEXT,data BLOB,  -- 存储二进制图像数据mime_type TEXT
);
​
-- C#代码示例
// 读取图像到SQLite
byte[] imageData = File.ReadAllBytes("image.jpg");
using (var command = new SQLiteCommand(connection)) {command.CommandText = "INSERT INTO images(name, data, mime_type) VALUES (@name, @data, @mime)";command.Parameters.AddWithValue("@name", "sample.jpg");command.Parameters.AddWithValue("@data", imageData);command.Parameters.AddWithValue("@mime", "image/jpeg");command.ExecuteNonQuery();
}

6.3 存储和查询JSON数据

-- 创建包含JSON的表
CREATE TABLE products (product_id INTEGER PRIMARY KEY,name TEXT,attributes TEXT -- 存储JSON数据
);
​
-- 插入JSON数据
INSERT INTO products(name, attributes) 
VALUES ('Smartphone', '{"color":"black","memory":"128GB","camera":"12MP"}');
​
-- 使用JSON函数查询(SQLite 3.9.0+)
SELECT name, json_extract(attributes, '$.color') AS color,json_extract(attributes, '$.memory') AS memory
FROM products;
​
-- 使用JSON路径操作符(SQLite 3.38.0+)
SELECT name,attributes->>'$.color' AS color,attributes->>'$.memory' AS memory
FROM products;

6.4 日期时间处理

-- 创建日期时间表
CREATE TABLE events (event_id INTEGER PRIMARY KEY,title TEXT,event_date TEXT, -- ISO格式日期created_at TEXT DEFAULT (datetime('now'))
);
​
-- 插入日期
INSERT INTO events(title, event_date)
VALUES ('Conference', '2023-12-15 09:00:00');
​
-- 日期计算和过滤
SELECT title, event_date 
FROM events
WHERE date(event_date) > date('now');
​
-- 日期格式化
SELECT title, strftime('%Y-%m-%d', event_date) AS date_only,strftime('%H:%M', event_date) AS time_only
FROM events;
​
-- 日期差值计算(天数)
SELECT title,julianday('now') - julianday(event_date) AS days_diff
FROM events;

6.5 高效存储大表的考虑

-- 为大表选择高效数据类型
CREATE TABLE log_entries (id INTEGER PRIMARY KEY,  -- 比BIGINT更节省空间timestamp INTEGER,       -- Unix时间戳比ISO日期字符串更紧凑level TINYINT,           -- 使用更小的整数类型(虽然存储还是INTEGER)message TEXT             -- 可变长度字符串
);
​
-- 索引对类型的影响
CREATE INDEX idx_timestamp ON log_entries(timestamp);
-- 整数索引通常比文本索引更高效

7 数据类型的最佳实践

  1. 明确指定类型

    -- 推荐
    CREATE TABLE users (id INTEGER PRIMARY KEY,name TEXT NOT NULL,age INTEGER,score REAL
    );
    ​
    -- 不推荐
    CREATE TABLE users (id,name,age,score
    );
  2. 合理使用INTEGER PRIMARY KEY

    -- 推荐
    CREATE TABLE categories (category_id INTEGER PRIMARY KEY,name TEXT
    );
    ​
    -- 不推荐对常用ID列使用TEXT类型
    CREATE TABLE categories (category_id TEXT PRIMARY KEY,  -- 更慢,更占空间name TEXT
    );
  3. 日期时间存储策略

    -- 推荐(可读性好)
    CREATE TABLE appointments (appointment_date TEXT DEFAULT (datetime('now', 'localtime'))
    );
    ​
    -- 推荐(计算效率高)
    CREATE TABLE logs (timestamp INTEGER DEFAULT (strftime('%s', 'now'))
    );
  4. JSON存储与结构化数据的权衡

    -- 少量属性,经常作为整体访问:使用JSON
    CREATE TABLE user_preferences (user_id INTEGER PRIMARY KEY,settings TEXT  -- JSON数据
    );
    ​
    -- 频繁查询特定字段:使用结构化表
    CREATE TABLE user_preferences_structured (user_id INTEGER PRIMARY KEY,theme TEXT,notifications BOOLEAN,language TEXT
    );
  5. 使用约束增强类型安全

    CREATE TABLE employees (id INTEGER PRIMARY KEY,name TEXT NOT NULL,email TEXT UNIQUE CHECK(length(email) > 3 AND email LIKE '%@%'),salary REAL CHECK(salary >= 0),department_id INTEGER REFERENCES departments(id)
    );

8 SQLite类型系统的优缺点

8.1 优点

  1. 灵活性:可以存储任何类型的数据到任何列

  2. 简单性:不需要像其他数据库那样处理复杂的类型系统

  3. 兼容性:容易从其他系统导入数据,不会遇到严格类型不匹配问题

  4. 紧凑存储:值按实际需要的空间存储,而不是预分配固定大小

8.2 缺点

  1. 类型安全性较低:没有严格的类型检查,可能导致数据一致性问题

  2. 隐式转换可能导致意外行为:在操作中类型可能自动转换

  3. 与其他SQL数据库不完全兼容:迁移代码时需要注意类型差异

  4. 缺少专门的DECIMAL/金融类型:需要应用层面处理精确计算

9 总结

SQLite的数据类型系统虽然简单,但非常灵活且强大:

  • 它提供5种基本存储类型:NULL, INTEGER, REAL, TEXT, BLOB

  • 使用类型亲和性机制来尝试转换数据到合适的存储类型

  • 不强制执行类型约束,但通过CHECK约束可以实现类型安全

  • 灵活性使其非常容易使用,但需要在应用层面确保数据一致性

相比其他关系型数据库,SQLite的类型系统更加灵活,但也需要开发者更加谨慎地使用,确保数据的一致性和完整性。特别是在处理财务数据、精确计算和日期时间时,需要采取适当的存储策略。以上就是SQLite数据类型的全部内容啦,期待我们下期的相遇,下期将介绍SQLite的函数以及如何使用SQLite函数。


相关文章:

  • Class AB OPA corner 仿真,有些corenr相位从0开始
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第十一讲)
  • 人工智能100问☞第15问:人工智能的常见分类方式有哪些?
  • 2025年软件工程与数据挖掘国际会议(SEDM 2025)
  • Three.js和WebGL区别、应用建议
  • 大模型在宫颈癌诊疗全流程预测与应用研究报告
  • 【免费试用】LattePanda Mu x86 计算模块套件,专为嵌入式开发、边缘计算与 AI 模型部署设计
  • [论文阅读]MCP Guardian: A Security-First Layer for Safeguarding MCP-Based AI System
  • VMware搭建ubuntu保姆级教程
  • NGINX `ngx_http_browser_module` 深度解析与实战
  • 数据中台架构设计
  • 分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
  • IP-Adapter
  • Caffeine快速入门
  • R语言助力森林生态研究:从数据处理到群落稳定性分析的完整流程,结合机器学习与案例写作
  • Kali Linux 安装 Rust 环境简明教程
  • js获取uniapp获取webview内容高度
  • 从零实战:在Xilinx Zynq PS端移植VxWorks 6.9系统
  • uniapp 全局混入:监听路由变化,路由变化即执行
  • oceanbase不兼容SqlSugarCore的问题
  • 诺和诺德一季度减重版司美格鲁肽收入增83%,美国市场竞争激烈下调全年业绩预期
  • 国新办将于5月8日10时就《民营经济促进法》有关情况举行新闻发布会
  • 第四轮伊美核问题谈判预计5月11日举行
  • 云南禄丰尾矿坍塌事故搜救正在进行,被掩埋的四辆工程车已找到
  • 新华每日电讯头版聚焦上海:科创高地向未来
  • 湖南新宁一矿厂排水管破裂,尾砂及积水泄漏至河流,当地回应