文章允许转载,请注明来源:http://www.jb51.cc/article/p-fbpktjwo-ee.html
sqlite作为一款轻量级数据库,常用于移动端的开发。今天开发的时候遇到一个问题,在解析一个其他应用的数据库时,数据库的表结构里字段数据定义为INTEGER,但是使用Cursor的getInt方法,获取到的数据跟数据库中的数值不一致。
通常理解下,int和INTEGER应该是同一种数据类型,也有很多数据库确实是这么处理的。但是后来通过验证发现,在sqlite中,int和INTEGER是有很大的区别。
sqlite中,INTEGER被认为是一个存储类
INTEGER 值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。
所以INTEGER是可以存储long long类型的。另外sqlite中还有一个亲和类型(Affinity)的概念,任何列仍然可以存储任何类型的数据,当数据插入时,该字段的数据将会优先采用亲和类型作为该值的存储方式。
In order to maximize compatibility between sqlite and other database engines,and so that the example above will work on sqlite as it does on other sql database engines,sqlite supports the concept of “type affinity” on columns. The type affinity of a column is the recommended type for data stored in that column. The important idea here is that the type is recommended,not required. Any column can still store any type of data. It is just that some columns,given the choice,will prefer to use one storage class over another. The preferred storage class for a column is called its “affinity”.
为了最大化sqlite和其它数据库引擎之间的数据类型兼容性,sqlite提出了”类型亲缘性(Type Affinity)”的概念。我们可以这样理解”类型亲缘性 “,在表字段被声明之后,sqlite都会根据该字段声明时的类型为其选择一种亲缘类型,当数据插入时,该字段的数据将会优先采用亲缘类型作为该值的存储方式,除非亲缘类型不匹配或无法转换当前数据到该亲缘类型,这样sqlite才会考虑其它更适合该值的类型存储该值。
INTEGER是五种亲和类型的一种。int的亲和类型就是INTEGER,因此,sqlite里面,部分int类型的字段,存储的数据可能是long long类型的。
所以获取数据不一致的原因就是INTEGER类型存储的是long long类型的数据,如果用getInt方式来取值,就会进行类型的强制转换。把取值时调用的getInt换成了getLong,问题就解决了。
参考:
What is the difference between SQLite integer data types like int,integer,bigint,etc.?
SQLite学习手册(数据类型)
Datatypes In SQLite Version 3