SQLite列类型的灵活性/限制性如何?

时间:2017-08-07 23:55:12

标签: android-sqlite

最近,关于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

3.1.1. Affinity Name Examples

另一个论点是列表是一个示例列表,列类型更灵活,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列类型的输入和输出是什么?

1 个答案:

答案 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

在SQLite中使用非标准列类型的原因!

简而言之,没有原因,如首先所述,列类型的灵活性似乎主要是为了满足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。