最近,关于SQLite中列类型的灵活性存在争议。因此,问题 SQLite列类型有多灵活?
一个论点是类型仅限于主要的五个,即TEXT,NUMERIC,INTEGER,REAL和BLOB,以及官方文档中的命名列类型,即: -
INT, TINYINT, SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8, CHARACTER(20), VARCHAR(255), VARYING CHARACTER(255), NCHAR(55), NATIVE CHARACTER(70), NVARCHAR(100), CLOB,
no datatype specified (BLOB)
, DOUBLE, DOUBLE PRECISION, FLOAT, DECIMAL(10,5), BOOLEAN, DATE & DATETIME
。
另一个论点是列表是一个示例列表,列类型更灵活,5条规则(如下所示)几乎普遍适用。
3.1。柱亲和力的测定
列的亲和力由声明的类型决定 列,按照以下规则显示顺序:
1)如果声明的类型包含字符串“INT”,则会为其指定INTEGER亲和力。
2)如果声明的列类型包含任何字符串“CHAR”,“CLOB”或“TEXT”,则该列具有TEXT亲和性。注意 VARCHAR类型包含字符串“CHAR”,因此被分配 TEXT亲和力。
3)如果列的声明类型包含字符串“BLOB”,或者未指定类型,则列具有关联BLOB。
4)如果列的声明类型包含任何字符串“REAL”,“FLOA”或“DOUB”,则该列具有REAL亲和力。
5)否则,亲和力为NUMERIC。
请注意,确定列关联性的规则的顺序是 重要。声明类型为“CHARINT”的列将与两者匹配 规则1和2,但第一个规则优先,因此列 亲和力将是INTEGER。
3.1. Determination Of Column Affinity
那么SQLite列类型的输入和输出是什么?
答案 0 :(得分:1)
SQLite列类型是灵活的(动态的),主要是,它似乎迎合了其他数据库管理系统使用的刚性列类型的采用/改编。
注意!这个Asnwer不推荐使用奇怪而精彩的色谱柱类型。
1)您实际上可以使用几乎任何名称作为列类型,但有一些限制。
2)列类型是列定义中的第二个值,例如CREATE TABLE table (columnname columntype .....,....)
,虽然可能会有意或无意地忽略注意见 5a)
3)第一个限制是mycolumn
INTEGER PRIMARY KEY
或mycolumn
INTEGER PRIMARY KEY AUTOINCREMENT
是一种特殊的列类型。该列是 rowid
的别名,它是一个唯一的数字标识符( AUTOINCREMENT
强制规定 rowid 必须更大比最后一次使用的表的rowid,例如,如果一行使用id(9223372036854775807),那么任何后续添加行的尝试都将导致SQLITE FULL错误。)。 SQLite Autoincrement
4)其他限制是列类型不得混淆SQLite解析器。例如,PRIMARY,TABLE,INDEX的列类型将导致SQLite异常(语法错误(代码1)),例如当使用列类型的INDEX时: -
android.database.sqlite.SQLiteException: near "INDEX": syntax error (code 1):
发生。
5)列类型不是必需的,例如CREATE TABLE mytable (...,PRIMARY_COL,....
,在这种情况下, PRAGMA TABLE_INFO(tablename)
将不显示任何类型,例如(第3行)。
08-08 07:56:23.391 13097-13097/? D/TBL_INFO: Col=cid Value=8
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=name Value=PRIMARY_COL
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=type Value=
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=notnull Value=1
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=dflt_value Value=null
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=pk Value=0
5a)在某些情况下,SQLite Parser会跳到有效的KEYWORDS,例如CREATE TABLE mytable (mycolumn NOT NULL,...
导致NOT NULL
用于表示NOT NULL
列,类型被视为无类型(上面的table_info是实际上来自这样的用法)。
6)类型不限于单个字,例如 VARYING CHARACTER(255)
或 THE BIG BAD WOLF
可以指定为类型,可以从此table_info提取中看到: -
08-08 08:23:26.423 4799-4799/? D/ TBLINFO: Col=type Value=THE BIG BAD WOLF
简而言之,没有原因,如首先所述,列类型的灵活性似乎主要是为了满足SQL从其他数据库管理系统的轻松调整。
列类型本身影响不大,因为数据将根据SQLite确定的要使用的存储类进行存储。除 rowid (请参阅上面的 3)外,任何列都可以保存任何类型的值。
除了作为Blob存储的数据之外,必须使用cursor.getBlob
检索该数据,并且cursor.getBlob不能用于未存储为BLOB的数据(getBlob不会因数据存储为TEXT而失败),您可以使用任何cursor.get????
方法检索数据(所有这些都不一定有用)。
以下是一些例子: -
对于添加了数据long myINT = 556677888;
的列(通过ContentValues,例如cv1.put(columnanme,myINT)
);
然后: -
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: Column=INTEGER_COL<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS INT >>556677888<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS LONG >>556677888<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS STRING >>556677888<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS DOUBLE >>5.56677888E8<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS FLOAT >>5.566779E8<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS SHORT >>15104<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: Unable to handle with getBlob.
getShort不会返回存储的值,getBlob无法获取存储的值。
对于Double myREAL = 213456789.4528791134567890109643534276;
: -
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: Column=REAL_COL<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: VALUE AS INT >>213456789<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: VALUE AS LONG >>213456789<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: VALUE AS STRING >>2.13457e+08<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: VALUE AS DOUBLE >>2.134567894528791E8<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: VALUE AS FLOAT >>2.1345678E8<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: VALUE AS SHORT >>6037<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: Unable to handle with getBlob.
String myTEXT = "The Lazy Quick Brown Fox Jumped Over the Fence or something like that.";
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: Column=TEXT_COL<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS INT >>0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS LONG >>0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS STRING >>The Lazy Quick Brown Fox Jumped Over the Fence or something like that.<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS DOUBLE >>0.0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS FLOAT >>0.0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS SHORT >>0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: VALUE AS BLOB >>[B@2f9e811e<<
根据my_char_is_not_a_char_but_an_int
,这是一个非常荒谬的示例,列类型为PRAGMA TABLE_INFO
: -
08-08 09:19:03.657 13575-13575/mjt.soqanda D/TBL_INFO: Col=cid Value=7
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ TBLINFO: Col=name Value=my_char_is_not_a_char_but_an_int_COL
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ TBLINFO: Col=type Value=my_char_is_not_a_char_but_an_int
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ TBLINFO: Col=notnull Value=0
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ TBLINFO: Col=dflt_value Value=null
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ TBLINFO: Col=pk Value=0
结果(按上述'Double'存储)为: -
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: Column=my_char_is_not_a_char_but_an_int_COL<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: VALUE AS INT >>213456789<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: VALUE AS LONG >>213456789<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: VALUE AS STRING >>2.13457e+08<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: VALUE AS DOUBLE >>2.134567894528791E8<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: VALUE AS FLOAT >>2.1345678E8<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: VALUE AS SHORT >>6037<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: Unable to handle with getBlob.
以上内容基于以下内容: - Datatypes In SQLite Version 3 SQLite Autoincrement PRAGMA Statements
代码在运行API22的GenyMotion仿真设备上测试/运行,编译时的最小版本为14,目标为26。