所以我在学校里使用MySQL,Oracle和SQL Server学习了很多SQL。所以现在我需要在Rasberry pi项目上使用SQLite。我不太了解的是数据类型。当你把你的字段设为int时,它只能保存整数吗?在SQLite中,它可以将整数保存在int数据类型中。所以我一直在阅读它以及SQLite如何在这些组中保存数据:
NULL。该值为NULL值。
INTEGER。该值是有符号整数,存储为1,2,3,4,6或8个字节,具体取决于值的大小。
REAL。该值是浮点值,存储为8字节IEEE浮点数。
TEXT。该值是一个文本字符串,使用数据库编码(UTF-8,UTF-16BE或UTF-16LE)存储。
BLOB。该值是一个数据块,完全按照输入的方式存储。
因此,只有在保存数据而不是输入时才会有所作为?我无法理解它..如何让我的INT列不接受整数?或者它不可能?
答案 0 :(得分:2)
SQL的SQLite方言是dynamically-typed language。就像Python可以让你创建一个混合类型的数组,如[None, 42, 3.14, 'Hello, world!', b'\x01\x23']
,SQLite将允许你在同一列中存储多种类型的值。
从概念上讲,SQLite有五个标量data types,称为“存储类”:
NULL
类型用于单例值NULL
,这是一个表示未知或不适用值的标记值。INTEGER
类型是64位有符号整数。关于“根据值的大小存储在1,2,3,4,6或8个字节中”的部分是文件格式的实现细节,而不是您作为程序员需要关注的内容。从C API和SQL语言的角度来看,它始终是8个字节。REAL
类型是64-bit个浮点数。TEXT
类型是字符串。BLOB
类型是一个八位字节序列。 SQL文字是X
- 十六进制数字的前缀字符串(例如,X'0123456789ABCDEF'
)。如果你是Python 3.x程序员,你可以想到:
NULL
= None
(类型为NoneType
)INTEGER
= int
(但限制为64位)REAL
= float
TEXT
= str
BLOB
= bytes
(这实际上是Python标准sqlite3
模块使用的类型映射。)
如果你是C#程序员,你可以想到:
NULL
= null
(但没有值类型和引用类型之间的任意区别)INTEGER
= long
REAL
= double
TEXT
= string
BLOB
= byte[]
SQLite允许您在任何列中存储任何数据类型的值。 (例外:如果一列被声明为INTEGER PRIMARY KEY
,并且其表是而不是声明为WITHOUT ROWID
,那么它实际上被约束为仅包含整数,因为它是一个别名行ID。)
上述“存储类”列表的独立,SQLite具有类型关联性的概念,它确定要存储的首选数据类型在一列中。列的亲和性由其声明的数据类型确定。
这些自动类型转换只会影响数字(INTEGER
和REAL
)和TEXT
值;永远不会有NULL
或BLOB
存储类的隐式转换。
因此,如果您声明一个具有整数关联性的列(例如,INT
或INTEGER
),但是在其中插入了一个文本字符串,那么SQLite会自动将该值转换为整数。但如果它不能,则将其保留为字符串。因此,字符串'42'
变为整数42
,但字符串'xyz'
保持原样。
真实关联列(REAL
,FLOAT
,DOUBLE
)类似,只是它们尝试将字符串转换为REAL
值而不是INTEGER
值。数字关联列(NUMERIC
,DECIMAL
)将字符串转换为数字,但很乐意在同一列中允许INTEGER
和REAL
值。
文字关联列(CHAR
,VARCHAR
,TEXT
,CLOB
)将进行相反的转换:所有数字(整数或实数)都转换为字符串。
Blob-affinity列(BLOB
或没有声明的数据类型)保留所有值。
答案 1 :(得分:0)
实际值决定了类型 与Excel类似。
您甚至不必为列定义类型,例如 -
create table t (c1,c2,c3);
https://www.sqlite.org/datatype3.html
- SQLite中的数据类型
醇>大多数SQL数据库引擎(除了以外的每个SQL数据库引擎) 据我们所知,SQLite使用静态,严格的类型。随着静态 输入时,值的数据类型由其容器确定 - 存储值的特定列。
SQLite使用更通用的动态类型系统。在SQLite中 值的数据类型与值本身相关联,而不是与其相关联 容器。 SQLite的动态类型系统是向后兼容的 与其他数据库引擎的更常见的静态类型系统 在静态类型数据库上工作的SQL语句的意义 应该在SQLite中以相同的方式工作。但是,动态输入 SQLite允许它做传统中不可能的事情 严格类型化的数据库。
drop table if exists t;
create table t (studentId int);
insert into t (studentId) values (1),(2),('Say what?'),(3),('Yep!');
select studentId from t;
sqlite> drop table if exists t; sqlite> create table t (studentId int); sqlite> insert into t (studentId) values (1),(2),('Say what?'),(3),('Yep!'); sqlite> select studentId from t; studentId ---------- 1 2 Say what? 3 Yep!
sqlite> .header on
sqlite> drop table t;
sqlite> create table t (studentId text);
sqlite> insert into t (studentId) values (1),(2),('Say what?'),(3),('Yep!');
sqlite> select studentId,studentId * 10 from t;
studentId studentId * 10
---------- --------------
1 10
2 20
Say what? 0
3 30
Yep! 0
答案 2 :(得分:0)
不,如果你声明一个INT列,那么在SQLite中说它只接受整数值是错误的。在SQLite中,您可以在任何列中存储任何数据类型。因此,您可以声明列AGE INTEGER并在该列中存储值为#TE;类型为TEXT的旧版本。
这与几乎所有其他关系数据库完全不同,后者要求值的类型与其存储的列的类型相匹配。