非常教程

Sqlite参考手册

数据类 | Datatypes

Datatypes In SQLite version 2

数据类型在 SQLite 版本2中

1.0 无类型

SQLite 是“无类型的”。这意味着您可以在任何表的任何列中存储任何类型的数据,而不管该列的已声明数据类型。(请参阅下面第2.0节中对此规则的一个例外。)此行为是一个功能,而不是一个错误。数据库应该存储和检索数据,数据库对数据的格式应该没有关系。在大多数其他 SQL 引擎中发现的强大的键入系统,并且在 SQL语言规范中被编码是一种错误特性 - 这是一个例子通过界面显示的实现。SQLite 试图通过允许您将任何类型的数据存储到任何类型的列中并允许数据类型规范中的灵活性来克服这种错误特性。

SQLite 的数据类型是零个或多个名称的任意序列,可选地后跟带有一个或两个带符号整数的带括号的列表。特别注意,数据类型可能是零个或多个名称。这意味着就 SQLite 而言,空字符串是有效的数据类型。因此,您可以声明表中每个列的数据类型未指定的位置,如下所示:

CREATE TABLE ex1(a,b,c);

尽管 SQLite 允许省略数据类型,但将它包含在 CREATE TABLE 语句中仍然是一个好主意,因为数据类型通常可以为其他程序员提供有关打算放入列的内容的良好提示。如果您将代码移植到另一个数据库引擎,那么其他引擎可能需要某种数据类型。SQLite 接受所有通常的数据类型。例如:

CREATE TABLE ex2(
  a VARCHAR(10),
  b NVARCHAR(15),
  c TEXT,
  d INTEGER,
  e FLOAT,
  f BOOLEAN,
  g CLOB,
  h BLOB,
  i TIMESTAMP,
  j NUMERIC(10,5)
  k VARYING CHARACTER (24),
  l NATIONAL VARYING CHARACTER(16)
);

等等。基本上任何名称序列都可以选择跟随一个或两个带括号的有符号整数。

2.0 INTEGER 主键

SQLite 无类型的一个例外是一个类型为 INTEGER PRIMARY KEY 的列。(并且必须使用“INTEGER”而不是“INT”。INT PRIMARY KEY 类型的列与其他任何类型无关)。INTEGER PRIMARY KEY 列必须包含一个32位有符号整数。任何尝试插入非整数数据都会导致错误。

INTEGER PRIMARY KEY 列可用于实现等效的 AUTOINCREMENT。如果您尝试将 NULL 插入到 INTEGER PRIMARY KEY列中,则该列实际上将被填充的整数比表中已有的最大键大1。或者,如果最大的键是2147483647,那么该列将填充一个随机整数。无论哪种方式,INTEGER PRIMARY KEY 列都将被分配一个唯一的整数。您可以使用sqlite_last_insert_rowid() API 函数或在随后的 SELECT 语句中使用last_insert_rowid() SQL 函数来检索此整数。

3.0 比较和排序顺序

为了决定允许哪些数据存储在列中,SQLite 是无类型的。但是,在对数据进行排序和比较时,一些类型概念会发挥作用。出于这些目的,列或表达式可以是以下两种类型之一:数字文本。排序或比较可能会给出不同的结果,具体取决于正在对哪些类型的数据进行排序或比较。

如果数据是文本类型,则比较由标准C数据比较函数 memcmp()strcmp()确定。比较将逐个查看来自两个输入的字节,并返回第一个非零差值。字符串是'\ 000'结尾,所以较短的字符串在较长的字符串之前进行排序,就像您期望的那样。

对于数字数据,这种情况更为复杂。如果两个输入都看起来像格式良好的数字,则使用 atof()将它们转换为浮点值并进行数值比较。如果一个输入不是一个正确的数字,而是另一个输入,那么该数字被认为小于非数字。如果两个输入都不是格式正确的数字,则使用 strcmp()进行比较。

不要被列可能有“数字”数据类型的事实所迷惑。这并不意味着该列只能包含数字。它仅仅意味着如果列中包含一个数字,该数字将按数字顺序排序。

对于文本和数字值,NULL 都会在任何其他值之前排序。使用诸如“<”或“> =”等运算符的任何值与 NULL 的比较始终是错误的。

4.0 SQLite 如何确定数据类型

对于 SQLite 2.6.3及更早版本,所有值都使用数字数据类型。文本数据类型出现在2.7.0及更高版本中。在续集中,假设您正在使用 SQLite 的2.7.0或更高版本。

对于表达式,结果的数据类型通常由最外层的运算符决定。例如,算术运算符(“+”,“*”,“%”)总是返回数字结果。字符串连接运算符(“||”)返回文本结果。等等。如果您对表达式的数据类型有疑问,可以使用特殊的 typeof() SQL 函数来确定数据类型是什么。例如:

sqlite> SELECT typeof('abc'+123);
numeric
sqlite> SELECT typeof('abc'||123);
text

对于表列,数据类型由 CREATE TABLE 语句的类型声明确定。当且仅当类型声明包含一个或多个以下字符串时,数据类型为 text:

BLOB CHAR CLOB TEXT

当然,在类型声明中搜索这些字符串不区分大小写。如果上述任何字符串都出现在类型声明的任何位置,那么该列的数据类型是文本。请注意,类型“VARCHAR”包含“CHAR”作为子字符串,因此它被视为文本。

如果上述字符串中没有一个出现在类型声明的任何位置,那么数据类型是数字类型。请特别注意,具有空类型声明的列的数据类型是数字。

5.0 示例

考虑以下两个命令序列:

CREATE TABLE t1(a INTEGER UNIQUE);        CREATE TABLE t2(b TEXT UNIQUE);
INSERT INTO t1 VALUES('0');               INSERT INTO t2 VALUES(0);
INSERT INTO t1 VALUES('0.0');             INSERT INTO t2 VALUES(0.0);

在左侧的序列中,第二个插入将失败。在这种情况下,字符串'0'和'0.0'被视为数字,因为它们被插入到数字列中,但是0 == 0.0违反了唯一性约束。但是,右侧序列中的第二个插入是有效的。在这种情况下,常量0和0.0被视为一个字符串,这意味着它们是不同的。

为了比较,SQLite 总是将数字转换为双精度(64位)浮点数。这意味着只有在无意义的数字中有所不同的长数字序列才会在数字列中相等,但如果它们在文本列中则会比较不相等。我们有:

INSERT INTO t1                            INSERT INTO t2
   VALUES('12345678901234567890');           VALUES(12345678901234567890);
INSERT INTO t1                            INSERT INTO t2
   VALUES('12345678901234567891');           VALUES(12345678901234567891);

如前所述,左边的第二个插入将失败,因为比较会先将两个字符串转换为浮点数,并且字符串中的唯一区别在于第20个数字中超过64位浮点数的分辨率。相反,右边的第二个插入将起作用,因为在这种情况下,插入的数字是字符串,并使用 memcmp()进行比较。

数字和文本类型对 DISTINCT 关键字也有所不同:

CREATE TABLE t3(a INTEGER);               CREATE TABLE t4(b TEXT);
INSERT INTO t3 VALUES('0');               INSERT INTO t4 VALUES(0);
INSERT INTO t3 VALUES('0.0');             INSERT INTO t4 VALUES(0.0);
SELECT DISTINCT * FROM t3;                SELECT DISTINCT * FROM t4;

左边的 SELECT 语句返回一行,因为'0'和'0.0'被视为数字,因此不清楚。但是右边的 SELECT 语句返回两行,因为0和0.0被视为不同的字符串。

 SQLite is in the Public Domain.

数据类 | Datatypes相关

Sqlite

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来

主页 https://sqlite.org/
源码 https://www.sqlite.org/src/
发布版本 3.21.0

Sqlite目录

1.C界面 | C Interface
2.C Interface: Session Module
3.CLI
4.数据库文件表 | Database File Format
5.数据类 | Datatypes
6.动态内存分配 | Dynamic Memory Allocation
7.外键约束 | Foreign Key Constraints
8.全文索引 | Full-Text Search
9.损坏方式 | How To Corrupt
10.JSON
11.语言 | Language
12.局限性 | Limits
13.锁定和并发 | Locking and Concurrency
14.其他 | Miscellaneous
15.PRAGMA Statements
16.查询计划程序 | Query Planner
17.R*Tree Module
18.RBU Extension
19.语法图 | Syntax Diagrams
20.Tcl Interface
21.虚拟表机制 | Virtual Table Mechanism
22.预写日志 | Write-Ahead Logging
23.SQL 教程
24.SQL 简介
25.SQL 语法
26.SQL DELETE 语句
27.SQL UPDATE 语句
28.SQL NOT NULL 约束
29.SQL 约束
30.SQL CREATE TABLE 语句
31.SQL CREATE DATABASE 语句
32.SQL INSERT INTO SELECT 语句
33.SQL SELECT INTO 语句
34.SQL CREATE VIEW、REPLACE VIEW、 DROP VIEW 语句
35.SQL AUTO INCREMENT 字段
36.SQL ALTER TABLE 语句
37.SQL 撤销索引、表以及数据库
38.SQL CREATE INDEX 语句
39.SQL DEFAULT 约束
40.SQL CHECK 约束
41.SQL FOREIGN KEY 约束
42.SQL PRIMARY KEY 约束
43.SQL UNIQUE 约束
44.SQL 通用数据类型
45.SQL ISNULL()、NVL()、IFNULL() 和 COALESCE() 函数
46.SQL NULL 值 – IS NULL 和 IS NOT NULL
47.SQL Server 和 MySQL 中的 Date 函数
48.SQL MS Access、MySQL 和 SQL Server 数据类型
49.SQL 函数
50.SQL 总结
51.SQL 主机
52.SQL 快速参考
53.SQL ROUND() 函数
54.SQL Server GETDATE() 函数
55.MySQL DATE_FORMAT() 函数
56.MySQL DATEDIFF() 函数
57.MySQL DATE_SUB() 函数
58.MySQL DATE_ADD() 函数
59.MySQL EXTRACT() 函数
60.MySQL DATE() 函数
61.MySQL CURTIME() 函数
62.MySQL CURDATE() 函数
63.MySQL NOW() 函数
64.SQL Server CONVERT() 函数
65.SQL Server DATEDIFF() 函数
66.SQL Server DATEADD() 函数
67.SQL Server DATEPART() 函数
68.SQLite 命令
69.SQLite 安装
70.SQLite 简介
71.SQLite 运算符
72.SQLite Select 语句
73.SQLite 删除表
74.SQLite 创建表
75.SQLite Insert 语句
76.SQLite 分离数据库
77.SQLite 附加数据库
78.SQLite 创建数据库
79.SQLite 数据类型
80.SQLite 语法
81.SQLite Order By
82.SQLite Limit 子句
83.SQLite Glob 子句
84.SQLite Like 子句
85.SQLite Delete 语句
86.SQLite Update 语句
87.SQLite AND/OR 运算符
88.SQLite Where 子句
89.SQLite 表达式
90.SQLite Distinct 关键字
91.SQLite Having 子句
92.SQLite Group By
93.SQLite Join
94.SQLite 约束
95.SQLite PRAGMA
96.SQLite 事务
97.SQLite 视图
98.SQLite Truncate Table
99.SQLite Alter 命令
100.SQLite Indexed By