分享

庖丁解牛Android中的SQLite之Sqlite中的数据类型

 图书馆送餐人员 2016-04-09

大多数数据库管理系统使用的是静态类型系统,也就是说,数据库中每一个数据以及表中每一列都有它固定的数据类型。Sqlite使用了动态类型系统,那sqlite的数据类型系统有什么特性呢?如果感兴趣的话,继续往下阅读吧。

一、Sqlite中的数据-存储类型

存入sqlite中的数据都有一个存储类型,数据的存储类型有五种:

  • NULL:表示数据为null的存储类型。
  • INTEGER:表示整型数据类型
  • REAL:表示浮点数据类型
  • TEXT:表示字符串数据类型
  • BLOB:二进制数据类型

每当一个数据插入到sqlite中的表中时,它都会被赋予一个存储类型。可以将这个存储类型看做是数据的一个属性。那么问题来了,存储类型由什么决定呢?应该是(我的推断,不一定正确),数据库管理系统,也就是sqlite,根据数据本身的类型来决定其存储类型,比如我们向数据库中插入一个int型的数据,那么sqlite会赋予这个数据INTEGER的存储类别。
为什么我会这么推断呢?在google官方封装的java接口中,我们都是通过ContentValues这个类来插入数据的,在这个类中put方法有多个重载:

public void put(String key, String value)
public void put(String key, Byte value)
public void put(String key, Long value)
public void put(String key, Float value)
public void put(String key, Double value)
public void put(String key, Boolean value)
public void put(String key, byte[] value)

这里给了一丢丢提示,sqlite可能会根据传入的数据的不同类型,赋予其不同的存储类型。

三、Sqlite中的列的“数据类型”(类型近似 Type Affinity)

在sqlite中每个列也有一个“数据类型”,这也“数据类型”是:

  • TEXT
  • NUMERIC
  • INTEGER
  • REAL
  • BLOB

为什么我在数据类型上打了引号呢?因为对于列的“数据类型”,表示的是该列推荐存储的数据类型,如果存入的数据类型不是推荐的类型,那么会进行相应的转换。所以称列的“数据类型”为类型近似 (Type Affinity)
问题又来了:

  1. 列的类型近似如何确定?
  2. 不同“数据类型”(类型近似)的列可以存储哪些数据类型的数据?

先来看看第一个问题,列的类型近似如何确定?,根据官方文档,有以下几条规则:

  1. 如果在列的声明中(一般是建表sql)包含“INT”,那么这个列的类型近似就是 INTEGER
  2. 如果在列的声明中包含“CHAR”,“CLOB”,“TEXT”,那么这个列的类型近似就是 TEXT
  3. 如果在列的声明中包含"BLOB”或者没有指定类型,那么这个列的类型近似就是 BLOB
  4. 如果在列的声明中包含“REAL”,“FLOA”,“DOUB”,那么这个列的类型近似就是 REAL
  5. 如果前四条规则都不满足,列的类型近似就是 NUMERIC

注意:以上规则,不区分大小写。

以上规则也间接地告诉我们,虽然sqlite的列只支持五种“数据类型”,但是我们仍然可以使用sql标准中的类型来声明列的“数据类型”,sqlite会自动完成转换工作。当然,最好的办法就是在列的声明中,只使用sqlite支持的“数据类型”

再来看看第二个问题。不同“数据类型”(类型近似)的列可以存储哪些数据类型的数据?

在sqlie中,列的“数据类型”是列推荐存储的类型,也就是说,列不限制用户传入的数据的存储类型。但是列会对不是推荐类型的数据进行相应的转换。官方文档中,给出了详细的转换规则,但是,我觉得没有必要仔细了解或者记忆这些规则。因为,在实践中,我们应该向列中插入它本来就支持的数据类型,而不是让数据库系统自己来转换。具体地:

  • TEXT类型就只存String类型
  • INTEGER类型只存储 short, int ,long, long long类型
  • REAL类型只存储 float,double类型
  • BLOB类型只存储 byte,byte[]类型
  • 一般不使用NUMERIC

四、布尔型和时间类型

那么问题来了,sqlite不支持布尔型和时间类型,那我们如何存储呢?
首先,能不存就不存,sqlite本来就是给嵌入式系统用的,所以能简单就简单,别什么都往数据库里仍,sqlite只是个小朋友,能力有限。
如果,非要存的话,这里给出官方的推荐方案:

  1. 布尔型使用INTEGER代替,0代表false,1代表true。
  2. 时间类型有三种方案

    • TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS")
    • REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
    • INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

      根据业务需求,来选择吧,如果时间只是用来显示在UI上,选第一种,如果要对时间进行相应的计算,选第三种。第二种我也不知道是啥。

本文根据官方文档改写而成,梳理了一些逻辑顺序,结合Android,简单谈了谈自己的理解,如有不恰当的地方,随便喷。

第一部分就到此了,这是一个系列文章,后续文章将陆续更新:
1、Sqlite中的数据类型

2、sqlite中的sql

3、Android应用开发中的数据库设计

4、Android中的数据库开发(一)

5、Android中的数据库开发(二)

6、Sqlite的性能优化

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多