数据库-SQLite3中的数据类型
------------------------------
安装 Sqlite3 和数据库查看⼯具:
sudo apt-get install sqlite3
sudo apt-get install sqlitebrowser
------------------------------
基础概念:
  数据表中,纵向的⼀整列叫“列”,横向的⼀整⾏叫“记录”,“记录”中每⼀格叫“字段”,字段的内容叫“数据”
------------------------------
SQL 创建数据表:
Create Table 表名称 { 列名称列数据类型, 列名称列数据类型, ... };
  ⾸先要知道,⼤多数的数据库引擎都使⽤“静态数据类型”(基本上除了 SQLite 之外的所有 SQL 数据库引擎都使⽤“静态数据类型”),使⽤静态类型,数据的类型就由它的“列”决定,与“列”类型不相符的数据是⽆法写⼊到该“列”中的。
  ⽽ SQLite 采⽤的是“动态数据类型”(可以理解为 SQLite 是“⽆类型限制”的),这意味着你可以保存任何类型的“数据”到任何“表”的任何“列”中(整形主键“列”除外),⽆论这“列”声明的数据类型是什么。对于 SQLite 来说,不指定“数据类型”是完全Create Table 表名称 { 列名称, 列名称, ... };
  尽管 SQLite 为我们提供了这种⽅便,但是考虑到数据库的平台可移植性,我们在实际的开发中还是应该声明“数据类型”,并且保证“存⼊的数据类型”和“声明的数据类型”是⼀致的。除⾮你有极为充分的理由,同时不再考虑数据库平台的移植问题,------------------------------
  虽然 SQLite 对“数据类型”没有强制要求,但 SQLite 定义了 5 种最基本的“存储类型”,它们决定了“数据”在数据库中的存在形式。每个存放在 SQLite 数据库中的值(或者由这个数据库引擎操作的值)都属于下⾯ 5 种“存储类型”中的⼀种:
1  NULL    ⽆值(什么也没有,不等同于“空字符串”或 0)
2  INTEGER 有符号整数(根据值的⼤⼩存储在 1、2、3、4、6、8 字节中)
3  REAL    浮点数(8 字节的 IEEE 浮点数字)
4  TEXT    字符串(使⽤数据库内部的编码⽅式存储,默认 UTF-8)
5  BLOB    字节流(原样存储)
  也就是说 SQLite 本质上只有 5 种类别的数据,在 SQLite 的数据库中,也只能存⼊这 5 种类别的数据。
  INTEGER “存储类型”包含 6 种不同长度的不同整形的“数据类型”,这只在磁盘上造成了差异。当 INTEGER 值被从磁盘中读⼊到内存中以后,它们均被转换成最⼀般的数据类型(8 字节有符号整形)。
  SQLite 的 TEXT 编码⽅式可以通过 SQL 语句 PRAGMA encoding 来查询和修改:
// 查询当前编码⽅式,默认 UTF-8
PRAGMA encoding;
// 设置当前编码⽅式,只有以下⼏种
PRAGMA encoding = "UTF-8";
PRAGMA encoding = "UTF-16";
PRAGMA encoding = "UTF-16le";
PRAGMA encoding = "UTF-16be";
------------------------------
  虽然 SQLite 对“数据类型”没有强制要求,但依然有⾃⼰的“数据类型”,SQLite 内定了 5 种最基本的“数据类型”,它们决定了“数据”在写⼊数据库时的“修正⽅式”。所有的⾮内定“数据类型”最终都会被视为相应的内定“数据类型”。下⾯列出了 5 种内定1、INTEGER
  当“⽂本类型”的数据被插⼊到此类字段中时,会被⾃动转换为 INTEGER 格式(前提是转换操作不会导致数据信息丢失以及完全可逆),之后再插⼊到⽬标字段中。如果转换失败,则 SQLite 仍会以 TEXT ⽅式存储该数据。
  对于 NULL 或 BLOB 类型的数据,SQLite 将不做任何转换,直接以 NULL 或 BLOB 的⽅式存储该数据。
  需要额外说明的是,对于浮点格式的“常量⽂本”,如 '30000.0',如果该值可以转换为 INTEGER 类型,同时⼜不会丢失数值信息,那么 SQLite 就会将其转换为 INTEGER 格式 3000 进⾏存储。
2、REAL
  规则等同于 INTEGER 数据类型,“⽂本类型”的数据会被转换为 REAL 格式。
3、NUMERIC
  规则等同于 INTEGER 数据类型,“⽂本类型”的数据会被转换为 INTEGER 或 REAL 格式,优先转换为 INTEGER 格式,如果不能转换为 INTEGER 格式,再尝试转换为 REAL 格式。
数据库基本数据类型有哪些
  在执⾏ CAST 表达式时与 INTEGER 有差别。
4、TEXT
  当“数值类型”的数据被插⼊到此类字段中时,会被⾃动转换为 TEXT 格式,之后再插⼊到⽬标字段中。
5、BLOB
  当“任何类型”的数据被插⼊到此类字段中时,将不做任何的转换,直接以该数据所属的数据类型进⾏存
储。
------------------------------
  虽然 SQLite 有⾃⼰内定的“数据类型”,但依然可以使⽤⾮内定的“数据类型”来定义“列”。事实上,SQLite 接受“任意字符串”作为“数据类型”使⽤,也就是说,你可以使⽤“ABC”、“HELLO”等作为“数据类型”来定义“列”,如果你觉得这样做有意义的话  最终,SQLite 会把⾮内定的“数据类型”归类为某⼀个内定的“数据类型”,并将其视为内定“数据类型”来使⽤。归类原则如下:
1、如果“数据类型”字符串中包含“INT”,那么这些“数据类型”被归类为 INTEGER 类型。
2、如果“数据类型”字符串中包含“CHAR”、“CLOB”或“TEXT”,那么这些“数据类型”被归类为 TEXT 类型。
3、如果“数据类型”字符串中包含“BLOB”,那么这些“数据类型”被归类为 BLOB 类型。
4、如果“数据类型”字符串中包含“REAL”、“FLOA”或“DOUB”,那么这些“数据类型”被归类为 REAL 类型。
5、其余的“数据类型”被归类为 NUMERIC 类型。
  这 5 条归类原则具有先后优先级,前⾯的规则优先于后⾯的规则,⽐如某“列”的“数据类型”声明为“CharInt”,既有第 2 条规则中的“Char”,⼜有第 1 条规则中的“Int”,那么根据先后顺序,应该优先遵循第 1 条规则,则“CharInt”会被视为 INTEGER   在 SQLite 中,类型 CHAR(255) 的长度信息 255 没有任何实际意义,仅仅是为了与其它数据库平台的声明保持⼀致性,CHAR(255) 最终会以 TEXT 格式存⼊数据库,没有长度限制。
----------
举例说明:
  ⽐如声明某“列”的“数据类型”是“CHAR(255)“,根据“类型归类原则”,该“列”被视为 TEXT 类型,如果存⼊的数据是数值 32,那么在存⼊之前,SQLite 会把 32 转换为字符串 '32' 再存⼊相应的字段中。
  如果声明的“数据类型”是“SMALLINT”,根据“类型归类原则”,该“列”被视为 INTEGER 类型,如果存⼊的数据是字符串 '-32.0',那么在存⼊之前,SQLite 会把 '-32.0' 转换为整数 -32 再存⼊相应的字段中。但是,如果存⼊的是 'A32' 或 '-32.5',则⽆  如果声明的“数据类型”是“ABC”,根据“类型归类原则”,该“列”被视为 NUMERIC 类型,如果存⼊的数据是字符串 '-32.0',那么在存⼊之前,SQLite 会把 '-32.0' 转换为整数 -32 再存⼊相应的字段中。如果存⼊的是 '-32.5',则 SQLite 会把 '-32.5' 转------------------------------
关于布尔值的存储:
  SQLite 没有单独的“布尔存储类型”,它使⽤ INTEGER 类型来存储布尔值,0 为 false,1 为 true。⼀般的做法是将布尔值转换为 0 或 1,然后再写⼊ SQLite 数据库中。
  下⾯的 Golang 代码会⾃动将 true 和 false 转换为 1 和 0:
sql.DB.Exec("insert into data values (?,?)", true,false)
  不能直接在 SQL 语句中使⽤ true 或 false,⽐如下⾯的代码将⽆法执⾏成功:
sql.DB.Exec("insert into data values (true,false)")
------------------------------
关于⽇期时间的存储:
  SQLite 没有提供专门的“⽇期时间存储类型”,如果要存储⽇期时间,必须先将⽇期时间转换成 SQLite 内定的“数据类型”,然后再写⼊数据库。
  SQLite 内置的⽇期和时间函数(date、time、datetime、julianday、strftime)能够将“⽇期时间字符串”
转换为 TEXT,REAL 或 INTEGER 形式存放,程序可以任意选择这⼏个“存储类型”去存储⽇期和时间:
  TEXT    作为 IS08601 字符串("YYYY-MM-DD HH:MM:SS.SSS")
  REAL    从格林威治时间 11 ⽉ 24 ⽇,4174 B.C 中午以来的天数
  INTEGER 从 1970-01-01 00:00:00 UTC 以来的秒数
------------------------------
关于⽐较表达式:
  在 SQLite3 中⽀持的“⽐较表达式”有:=、==、<、<=、>、>=、!=、<>、IN、NOT IN、BETWEEN、IS、IS NOT。
  数据的⽐较结果主要依赖于操作数的存储⽅式,其规则为:
1、存储⽅式为 NULL 的数值⼩于其它存储类型的值。
2、存储⽅式为 INTEGER 和 REAL 的数值⼩于 TEXT 或 BLOB 类型的值,如果同为INTEGER 或 REAL,则基于数值规则进⾏⽐较。
3、存储⽅式为 TEXT 的数值⼩于 BLOB 类型的值,如果同为 TEXT,则基于⽂本规则(ASCII 值)进⾏⽐较。
4、如果是两个 BLOB 类型的数值进⾏⽐较,其结果为 C 运⾏时函数 memcmp() 的结果。
  即:NULL < INTEGER、REAL < TEXT < BLOB
------------------------------
关于数学操作符:
  所有的“数学操作符”(+、-、*、/、%、<<、>>、&、、|)在执⾏数学运算前都会先将“操作数”转换为 NUMERIC 存储类型,即使在转换过程中可能会造成数据信息的丢失。此外,如果其中⼀个操作数为 NULL,那么它们的运算结果亦为 NULL。------------------------------
总结:
  在使⽤ Create Table 表名称 { 列名称列数据类型, 列名称列数据类型, ... }; 创建 SQLite 数据表时,“列数据类型”最好选⽤ INTEGER、REAL、NUMERIC、TEXT、BLOB 其中之⼀,因为 SQLite 本质上只⽀持这些“数据类型”。如果要兼容其它数  在向数据库中写⼊数据时,要保证“写⼊的数据类型”与“声明的数据类型”⼀致,这样创建出来的数据库⽂件才能兼容其它数据库平台。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。