许多SQL数据库引擎(除SQLite之外的各种SQL数据库引擎)使用静态、严格的数据类型。对于静态类型,一个值的数据类型由它的容器,即存储这个值的列来决定。SQLite则使用更加通用的动态类型系统。在SQLite中,一个值的数据类型被关联到这个值本身,而不是它的容器。SQLite的动态类型系统向后兼容一般静态类型系统的数据库引擎。在某种意义上,工作在静态类型数据库上的SQL声明也同样能工作在SQLite上。但是SQLite动态类型还允许做一些在传统严格类型的数据库中不能做的事情。

一、存储类别及数据类型
    在SQLite数据库中存储(或被数据库引擎操作)的每个值,都属于下面存储类别之一:
    * NULL: 值为一个NULL空值。
    * INTEGER: 值被标识为整数,依据值的大小可以依次被存储为1,2,3,4,6或8个字节。
    * REAL: 所有值都是浮点数值,被存储为8字节的IEEE浮点数。
    * TEXT: 值为文本字符串,使用数据库编码存储,如UTF-8、UTF-16BE或UTF-16-LE。
    * BLOB: 值是数据的二进制对象,如何输入就如何存储,不改变格式。
    注意一个存储类别比一个数据类型更通用。例如INTEGER存储类别就包括6个不同长度的整型数据类型,这在磁盘上是不同的。不过只要INTEGER值从磁盘上读到内存中进行处理,它们会转换成最通用的数据类型(8字节的整型),因此在大多数情况下,对“存储类别”和“数据类型”并不做严格区分,这两个术语可交换使用。
    在SQLite3数据库中,除了INTEGER PRIMARY KEY这一列,任何列都可以存储任何类型的数据。SQL语句中的所有值,不管是嵌入到SQL语句文本中的字面值还是绑定到预先编译好的SQL语句中的参数值,都有一个隐式存储类别。在下述情况中,数据库引擎将在执行查询时,可以让存储的值在数值类型(INTEGER和REAL)和文本类型之间转换。
    (1)Boolean数据类型
    SQLite没有单独的布尔数据类型。相应的,布尔值被存储为整型0(false)和1(true)。
    (2)日期和时间数据类型
    SQLite没有单独的日期/时间数据类型。相应的,内建的日期和时间函数能够把日期和时间存储为文本、实数或整数值,以TEXT、REAL和INTEGER类型分别不同的格式表示该类型,如:
    * 文本值为ISO8601字符串("YYYY-MM-DD HH:MM:SS.SSS")。

TEXT: "YYYY-MM-DD HH:MM:SS.SSS"。

* 实数值为儒略日数,即从公元前4714年11月24日格林威治正午时刻开始的天数,按公历来算。

REAL: 以Julian日期格式存储。

* 整数值为Unix时间,即从1970-01-01 00:00:00 UTC开始的秒数。

INTEGER: 以Unix时间形式保存数据值,即从1970-- ::00到当前时间所流经的秒数。

应用程序可以选择其中的一种格式来存储日期和时间,也可以通过内建的日期和时间函数在这些格式之间转换。

二、列的亲和类型(类型亲缘性)
  为了最大化SQLite和其它数据库引擎之间的数据类型兼容性,SQLite提出了"类型亲缘性(Type Affinity)"的概念。我们可以这样理解"类型亲缘性",在表字段被声明之后,SQLite都会根据该字段声明时的类型为其选择一种亲缘类型,当数据插入时,该字段的数据将会优先采用亲缘类型作为该值的存储方式,除非亲缘类型不匹配或无法转换当前数据到该亲缘类型,这样SQLite才会考虑其它更适合该值的类型存储该值。SQLite目前的版本支持以下五种亲缘类型:

亲缘类型 描述  
TEXT         数值型数据在被插入之前,需要先被转换为文本格式,之后再插入到目标字段中。
NUMERIC                  当文本数据被插入到亲缘性为NUMERIC的字段中时,如果转换操作不会导致数据信息丢失以及完全可逆,那么SQLite就会将该文本数据转换为INTEGER或REAL类型的数据,如果转换失败,SQLite仍会以TEXT方式存储该数据。对于NULL或BLOB类型的新数据,SQLite将不做任何转换,直接以NULL或BLOB的方式存储该数据。需要额外说明的是,对于浮点格式的常量文本,如"30000.0",如果该值可以转换为INTEGER同时又不会丢失数值信息,那么SQLite就会将其转换为INTEGER的存储方式。
INTEGER 对于亲缘类型为INTEGER的字段,其规则等同于NUMERIC,唯一差别是在执行CAST表达式时。
REAL 其规则基本等同于NUMERIC,唯一的差别是不会将"30000.0"这样的文本数据转换为INTEGER存储方式。
NONE 不做任何的转换,直接以该数据所属的数据类型进行存储。  

在SQLite 3中,值被定义为何种类型只和值自身有关,与列无关,和变量也没有关系(被称作弱类型)。而其它的数据库引擎都受静态类型系统的限制,其值的类型是由其所属列的属性决定的,而与值本身无关。为了最大限度的增加SQLite数据库和其他数据库的兼容性,SQLite支持列的“亲和类型”概念。列的亲和类型是指为该列所存储的数据建议一个类型,要注意这个类型是建议而不是强迫。任何列依然是可以存储任何类型的数据的。只是针对某些列,如果有建议类型的话,数据库将优先按所建议的类型存储。这个被优先使用的数据类型称为“亲和类型”。
    SQLite 3的每个列均可以使用以下亲和类型中的一种:TEXT、NUMERIC、INTEGER、REAL、NONE。
    带有文本亲和类型的列可以使用NULL、TEXT或BLOB类型来存储所有数据。如果数值数据被插入到这样的列中,会在存储之前转换成文本类型。
    带有数值亲和类型的列可以使用所有五种类型来存储值。当文本数据被插入到数据值型的列中时,如果转换是无损的且可逆的,则文本会被转换成INTEGER或REAL(按优先顺序)。为了在TEXT和REAL之间转换,SQLite尝试无损且可逆地转换文本的开头15个有效十进制数字。如果不能成功转换的话,值则只能按文本类型存储了,而不会被转换成NULL类型或BLOB类型来存储。带有小数点或指数记法的字符串可能看起来像一个浮点字面值,但只要值能表示为一个整数,数值亲和类型将把它转换成一个整数。因此,字符串'3.0e+5'会被转换成整数300000,而不是浮点数300000.0。
    使用整数亲和类型的列,其行为与数值亲和类型的列一样。但也有些区别,比如没有小数部分的实数字面值被插入整数亲和类型的列时,它将被转换成整数并按整数类型存储。
    使用实数亲和类型的列,其行为与数值亲和类型的列一样。但有一个区别,就是整数会强制用浮点数来表示。(作为一个内部优化,无小数部分的小浮点数会当作整数写入磁盘,以占用更少的空间。当读出这个值时会自动转换回浮点数。这个优化在SQL级别完全不可见,并且只有通过检测数据库文件的原始比特位才能发现)。
    使用NONE亲和类型的列不会优先选择使用哪个类型,在数据被存储前也不会强迫转换它的类型,而是直接按它声明时的原始类型来存储。

(1)列亲和类型的确定(决定字段亲缘性的规则)

列的亲和类型由列的声明类型(在写SQL语句时指定)来确定,即字段的亲缘性是根据该字段在声明时被定义的类型来决定,根据以下规则顺序来判断:
    1)如果列的声明类型包含字符串"INT",则被定义为整数亲和类型。
    2)如果列的声明类型包含字符串"CHAR"、"CLOB"或"TEXT"中的某一个,则列具有文本亲和类型。注意VARCHAR类型包含字符串"CHAR",因此被定义为文本亲和类型。
    3)如果列的声明类型包含字符串"BLOB",或者没有为列声明数据类型,则列具有NONE亲和类型。
    4)如果列的声明类型包含字符串"REAL"、"FLOA"或"DOUB"中的某一个,则列具有REAL亲和类型。
    5)否则,列的亲和类型为NUMERIC。
    需要注意的是以下情况的列表顺序,即如果某一字段类型同时符合两种亲缘性,那么排在前面的规则将先产生作用。确定列亲和类型的规则顺序非常重要,声明类型为"CHARINT"的列匹配规则1和2,但按顺序优先使用规则1,因此列被定义为整数亲和类型。

(2)亲和类型名称实例

按照上面5条规则,下面例子显示传统SQL实现中的各种通用数据类型(CREATE TABLE语句或CAST表达式中的数据类型)怎样被转化成SQLite中的亲和类型。这里只是所有传统数据类型中的一部分,它们能够被SQLite接受。注意跟在类型名后面的括号中的数字参数在SQLite中被忽略。SQLite不在字符串、BLOB对象或数值上强加任何长度限制(除了大的全局SQLITE_MAX_LENGTH限制)。
    * INT, INTEGER, TINYINT, SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8: 定义为INTEGER亲和类型(按规则1)。
    * CHARACTER(20), VARCHAR(255), VARYING CHARACTER(255), NCHAR(255), NATIVE CHARACTER(70), NVARCHAR(100), TEXT, CLOB: 定义为TEXT亲和类型(按规则2)。
    * BLOB, 不声明类型: 定义为NONE亲和类型(按规则3)。
    * REAL, DOUBLE, DOUBLE PRECISION, FLOAT: 定义为REAL亲和类型(按规则4)。
    * NUMERIC, DECIMAL(10,5), BOOLEAN, DATE, DATETIME: 定义为NUMERIC亲和类型(按规则5)。
    注意声明类型"FLOATING POINT"将得到INTEGER亲和类型,而不是REAL亲和类型,因为"POINT"中有子串"INT"。声明类型"STRING"为NUMERIC亲和类型,而不是TEXT。

(3)列亲和类型转化实例

SQL示范:当值被插入到表中时,SQLite是怎样使用亲和类型来做类型转换。

CREATE TABLE t1(
    t  TEXT,     -- text affinity by rule 2
    nu NUMERIC,  -- numeric affinity by rule 5
    i  INTEGER,  -- integer affinity by rule 1
    r  REAL,     -- real affinity by rule 4
    no BLOB      -- no affinity by rule 3
);  

-- Values stored as TEXT, INTEGER, INTEGER, REAL, TEXT.
INSERT INTO t1 VALUES('500.0', '500.0', '500.0', '500.0', '500.0');
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
text|integer|integer|real|text  

-- Values stored as TEXT, INTEGER, INTEGER, REAL, REAL.
DELETE FROM t1;
INSERT INTO t1 VALUES(500.0, 500.0, 500.0, 500.0, 500.0);
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
text|integer|integer|real|real  

-- Values stored as TEXT, INTEGER, INTEGER, REAL, INTEGER.
DELETE FROM t1;
, , , , );
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
text|integer|integer|real|integer  

-- BLOBs are always stored as BLOBs regardless of column affinity.
DELETE FROM t1;
');
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
blob|blob|blob|blob|blob  

-- NULLs are also unaffected by affinity
DELETE FROM t1;
INSERT INTO t1 VALUES(NULL,NULL,NULL,NULL,NULL);
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
null|null|null|null|null  

  具体示例:

声明类型 亲缘类型 应用规则
INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INT2
INT8
INTEGER 1
CHARACTER(20)
VARCHAR(255)
VARYING CHARACTER(255)
NCHAR(55)
NATIVE CHARACTER(70)
NVARCHAR(100)
TEXT
CLOB
TEXT 2
BLOB NONE 3
REAL
DOUBLE
DOUBLE PRECISION
FLOAT
REAL 4
NUMERIC
DECIMAL(10,5)
BOOLEAN
DATE
DATETIME
NUMERIC 5

  注意:在SQLite中,类型VARCHAR(255)的长度信息255没有任何实际意义,仅仅是为了保证与其它数据库的声明一致性。

三、比较表达式
    SQLite 3有常用的SQL比较运算符集,包括"=", "==", "<", "<=", ">", ">=", "!=", "<>", "IN", "NOT IN", "BETWEEN", "IS"和"IS NOT"。

比较的结果取决于操作数的存储类型,即数据的比较结果主要依赖于操作数的存储方式,根据以下规则来判断:
    * NULL类型的值被认为小于任何(存储类型的)值(包括另外一个值也是NULL类型时)。
    * INTEGER或REAL类型的值小于任何TEXT或BLOB类型的值。当一个INTEGER或REAL与另一个INTEGER或REAL比较时,则按照实际数值来比较。
    * TEXT值小于BLOB值。当两个同为TEXT类型的文本值进行比较时,指定的比较序列(默认规则为使用memcmp())会被用来确定比较结果,基于文本规则(ASCII值)进行比较。
    * 当两个BLOB值比较时,由memcmp()确定比较结果,其结果为C运行时函数memcmp()的结果。

在开始比较前,SQLite尝试着把值在数值类型(整数和实数)和文本之间相互转换。是否进行转换取决于操作数的亲和类型。操作数亲和类型根据以下规则确定:
    * 若表达式只是列值的简单引用,则亲和类型与列的亲和类型一样。注意如果X和Y.Z是列名,则+X和+Y.Z是用来确定亲和类型的表达式。
    * "CAST(expr AS type)"形式的表达式,其亲和类型与声明类型为"type"的列相同。
    * 否则,表达式为NONE亲和类型。

“应用亲和类型”表示转换一个操作数为特定的存储类型,当且仅当转换是无损且可逆的。应用于比较运算符的操作数的亲和类型根据下面规则来确定:
    * 如果一个操作数是INTEGER, REAL或NUMERIC亲和类型,另一个操作数是TEXT或NONE亲和类型,则NUMERIC亲和类型被应用于另外一个操作数。
    * 如果一个操作数是TEXT亲和类型,另一个操作数是NONE亲和类型,则TEXT亲和类型被应用于另一个操作数。
    * 否则,没有亲和类型需要转换,两个操作数按照原有亲和类型进行比较。

表达式"a BETWEEN b AND c"被当作两个分开的二进制表达式"a >= b AND a <= c",即使两次比较中'a'应用了不同的亲和类型也是如此。表达式"x IN (SELECT y ...)"实际执行的是"x=y"。例如如果'b'是一个列值,'a'是一个表达式,那么在开始比较前,'b'的亲和性就被转换为'a'的亲和性了。"a IN(x,y,z,...)"形式的表达式等价于"a = +x OR a = +y OR a = +z OR ..."。也就是说,IN运算符右边的值(这里的"x"、"y"和"z")的类型被认为没有亲和性,即使它们是列值或CAST表达式。
     SQL示范:比较运算。

CREATE TABLE t1(
    a TEXT,      -- text affinity
    b NUMERIC,   -- numeric affinity
    c BLOB,      -- no affinity
    d            -- no affinity
);  

-- Values will be stored as TEXT, INTEGER, TEXT, and INTEGER respectively
);
SELECT typeof(a), typeof(b), typeof(c), typeof(d) FROM t1;
text|integer|text|integer  

-- Because column "a" has text affinity, numeric values on the
-- right-hand side of the comparisons are converted to text before
-- the comparison occurs.
,   a ,   a  FROM t1;  

-- Text affinity is applied to the right-hand operands but since
-- they are already TEXT this is a no-op; no conversions occur.
' FROM t1;  

-- Column "b" has numeric affinity and so numeric affinity is applied
-- to the operands on the right.  Since the operands are already numeric,
-- the application of affinity is a no-op; no conversions occur.  All
-- values are compared numerically.
,   b ,   b  FROM t1;  

-- Numeric affinity is applied to operands on the right, converting them
-- from text to integers.  Then a numeric comparison occurs.
' FROM t1;  

-- No affinity conversions occur.  Right-hand side values all have
-- storage class INTEGER which are always less than the TEXT values
-- on the left.
,   c ,   c  FROM t1;  

-- No affinity conversions occur.  Values are compared as TEXT.
' FROM t1;  

-- No affinity conversions occur.  Right-hand side values all have
-- storage class INTEGER which compare numerically with the INTEGER
-- values on the left.
,   d ,   d  FROM t1;  

-- No affinity conversions occur.  INTEGER values on the left are
-- always less than TEXT values on the right.
' FROM t1;
  

如果交换比较方向,例子中的所有结果还是一样的。例如表达式"a<40"交换成"40>a"。

四、运算符
    所有数学运算符(+, -, *, /, %, <<, >>, &和|)在执行计算前会把两边的操作数转换成NUMERIC存储类型,即使转换有损或不可逆也会进行。若运算符上有NULL操作数,则运算产生NULL结果。若操作数不是NULL,也不是任何数值,则转换成0或0.0。

五、排序、分组和复合式SELECT
    当查询结果被一个ORDER BY子句排序时,NULL类型的值排在最前面,然后是INTERGER和REAL值,按数值大小排序。接着是文本值,按指定的比较序列排序。最后是BLOB值,按memcmp()比较来排序。在排序时没有存储类型的转换。
    当用GROUP BY子句对值进行分组时,不同存储类型的值是分开来的,但对INTERGER和REAL值,如果它们数值上相等,则被认为是相等的。对GROUP BY子句的结果,不会应用任何亲和类型。
    复合式SELECT操作符,包括UNION、INTERSECT和EXCEPT在值之间执行隐式的比较,在比较时不使用亲和类型转换,只是按照它们原有类型进行比较。

六、比较序列
    当SQLite比较两个字符串时,它使用一个比较序列(即比较函数)来确定哪个字符串更大或者相等。SQLite有3个内建的比较函数:BINARY、NOCASE和RTRIM。
    * BINARY: 使用memcmp()来比较字符串,即进行二进制比较,不管什么文本编码。
    * NOCASE: 与BINARY相同,但在比较前26个大写的ASCII字母会被折叠成对应小写字母。注意只有ASCII字母才会做大小写折叠。由于UTF字符表比较庞大,因此SQLite并不尝试做全部UTF字符的大小写折叠。
    * RTRIM: 与BINARY相同,但是忽略掉尾部的空格。
    每个表的每列都有一个关联的比较函数。如果没有显式地自定义比较函数,则默认使用BINARY。列定义的COLLATE子句用来为列定义可选的比较函数。

要确定二进制比较运算符(=, <, >, <=, >=, !=, IS和IS NOT)使用哪个比较函数,可根据以下规则来判断:
    1)如果有一个操作数通过尾部的COLLATE声明符分配了显式的比较函数,则用这个显式的比较函数来做比较,并且在左边操作数上优先使用这个比较函数。
    2)如果有一个操作数是列,则在左边操作数上优先使用这个列的比较函数。注意这时带有"+"的列名仍然被认为是一个列名。
    3)否则,使用默认的BINARY比较函数来进行比较。
    如果不是操作数,而是操作数的某个子表达式通过尾部的COLLATE声明符分配了显式的比较函数,则这个操作数也被认为有一个显式的比较函数。因此,单个COLLATE声明符可用在一个比较表达式的任何地方,由它定义的比较函数用于字符串比较,无论这个比较表达式使用了表的哪个列。如果一个表达式中有多个带COLLATE声明的子表达式,则使用最左边的显式比较函数,无论COLLATE声明符嵌套得有多深,也无论表达式有多少嵌套的括号。
    表达式"x BETWEEN y and z"在逻辑上与"x >= y AND x <= z"等价,因此使用两个独立比较的比较函数。表达式"x IN (SELECT y ...)"在确定比较函数时与表达式"x = y"的方法相同。 "x IN (y, z, ...)"形式的表达式,其比较函数是x的比较函数。
    SELECT语句中的ORDER BY子句也可以使用COLLATE声明符来分配一个比较函数,这个比较函数将被用来进行排序。否则,如果ORDER BY子句排序的表达式是一个列,则使用列的比较函数来确定排序顺序。如果表达式不是一个列且没有COLLATE子句,则使用BINARY比较函数。
    SQL示范:用于确定文本比较结果的比较函数,这可用在各种各样的SQL语句中(注意文本比较并不是必需的,如果是数值、BLOB或NULL值,则无需比较函数)。

CREATE TABLE t1(
    x INTEGER PRIMARY KEY,
    a,                 /* collating sequence BINARY */
    b COLLATE BINARY,  /* collating sequence BINARY */
    c COLLATE RTRIM,   /* collating sequence RTRIM  */
    d COLLATE NOCASE   /* collating sequence NOCASE */
);
                   /* x   a     b     c       d */
,'abc','abc', 'abc  ','abc');
,'abc','abc', 'abc',  'ABC');
,'abc','abc', 'abc ', 'Abc');
,'abc','abc ','ABC',  'abc');  

/* Text comparison a=b is performed using the BINARY collating sequence. */
SELECT x FROM t1 WHERE a = b ORDER BY x;
--result 1 2 3  

/* Text comparison a=b is performed using the RTRIM collating sequence. */
SELECT x FROM t1 WHERE a = b COLLATE RTRIM ORDER BY x;
--result 1 2 3 4  

/* Text comparison d=a is performed using the NOCASE collating sequence. */
SELECT x FROM t1 WHERE d = a ORDER BY x;
--result 1 2 3 4  

/* Text comparison a=d is performed using the BINARY collating sequence. */
SELECT x FROM t1 WHERE a = d ORDER BY x;
--result 1 4  

/* Text comparison 'abc'=c is performed using the RTRIM collating sequence. */
SELECT x FROM t1 WHERE 'abc' = c ORDER BY x;
--result 1 2 3  

/* Text comparison c='abc' is performed using the RTRIM collating sequence. */
SELECT x FROM t1 WHERE c = 'abc' ORDER BY x;
--result 1 2 3  

/* Grouping is performed using the NOCASE collating sequence (Values
** 'abc', 'ABC', and 'Abc' are placed in the same group). */
;
--result 4  

/* Grouping is performed using the BINARY collating sequence.  'abc' and
** 'ABC' and 'Abc' form different groups */
;
--result 1 1 2  

/* Sorting or column c is performed using the RTRIM collating sequence. */
SELECT x FROM t1 ORDER BY c, x;
--result 4 1 2 3  

/* Sorting of (c||'') is performed using the BINARY collating sequence. */
SELECT x FROM t1 ORDER BY (c||''), x;
--result 4 2 3 1  

/* Sorting of column c is performed using the NOCASE collating sequence. */
SELECT x FROM t1 ORDER BY c COLLATE NOCASE, x;
--result 2 4 3 1 

SQLite剖析之数据类型的更多相关文章

  1. SQLite剖析之功能特性

    SQLite是遵守ACID的轻型数据库引擎,它包含在一个相对较小的C库中.它是D.RichardHipp创建的公有领域项目.不像常见的客户端/服务器结构范例,SQLite引擎不是一个与程序通信的独立进 ...

  2. SQLite使用(二)&&数据类型

    1.概述 我们熟知的数据库引擎大部分采用静态数据类型,即列定义的类型定义了值的存储,并且值要严格满足列的定义,同一列所有值的存储方式都相同,比如定义了一个列类型为整型 int,不能在该列上输入'abc ...

  3. SQLite剖析之设计与概念

    1.API 由两部分组成: 核心API(core API)和扩展API(extension API). 核心API的函数实现基本的数据库操作:连接数据库.处理SQL.遍历结果集.它也包括一些实用函数, ...

  4. SQLite剖析之编程接口详解

    前言 使用过程根据函数大致分为如下几个过程: sqlite3_open() sqlite3_prepare() sqlite3_step() sqlite3_column() sqlite3_fina ...

  5. SQLite剖析之C/C++接口

    前言 SQLite3是SQLite一个全新的版本,它虽然是在SQLite2的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和API.SQLite3是为了满足以下的需求而开发的:支持UTF ...

  6. SQLite剖析之内核研究

    先从全局的角度把握SQLite内核各个模块的设计和功能.SQLite采用了层次化.模块化的设计,而这些使得它的可扩展性和可移植性非常强.而且SQLite的架构与通用DBMS的结构差别不是很大,所以它对 ...

  7. android sqlite支持的数据类型

    Sqlite3支持的数据类型 :NULL.INTEGER.REAL.TEXT.BLOB 但实际上,sqlite3也接受如下的数据类型:    smallint 16 位元的整数.    interge ...

  8. SQLite剖析之存储模型

    前言 SQLite作为嵌入式数据库,通常针对的应用的数据量相对于DBMS的数据量小.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树的形式来组织这 ...

  9. SQLite剖析之事务处理技术

    前言 事务处理是DBMS中最关键的技术,对SQLite也一样,它涉及到并发控制,以及故障恢复等等.在数据库中使用事务可以保证数据的统一和完整性,同时也可以提高效率.假设需要在一张表内一次插入20个人的 ...

随机推荐

  1. js去掉字符串的空格

    //去左空格; function ltrim(s){ return s.replace(/(^s*)/g, ""); } //去右空格; function rtrim(s){ re ...

  2. 那些过目不忘的H5页面

    原文链接:http://isux.tencent.com/great-mobile-h5-pages.html 从引爆朋友圈的H5小游戏<围住神经猫>,到颠覆传统广告的大众点评H5专题页& ...

  3. ArcGIS 10.5新功能预览

    ArcGIS for Server产品线被重命名为ArcGIS Enterprise. 带来更多丰富的时空GIS功能. 分析地理大数据 捕捉和分析实时传感器数据 快速地理影像分析 ArcGIS Ent ...

  4. IOS开发基础知识--碎片16

    1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断对象类型 -(BOO ...

  5. UIWebView保存网页中的图片(转载)

    现在H5混合原生开发的方式越来越流行,也就要用到UIWebView控件.在开发过程中,我们可能会遇到一个需求,要求我们保存网页上的图片,当用户点击图片的时候,就可以让用户选择是否下载图片. 在系统自带 ...

  6. 整型信号量和PV操作(计算机操作系统)

    在整型信号量机制中,信号量被定义为一个整形变量.除初始化外,仅能通过两个标准的原子操作Wait(S)和Signal(S)来访问.其通常分别被称为P.V操作. 描述如下: P操作:S=S-1:如果S小于 ...

  7. 使用SQL Server 扩展事件来创建死锁的时间跟踪

    我们通过SQL Server 2012图形界面来部署一个扩展事件跟踪会话.然后可以生成SQL脚本,在2008或2008 R2版本下运行类似的跟踪. 步骤1: 通过“Object Explorer”连接 ...

  8. MyEclipse编码设置及字体设置等

    原文: http://wenku.baidu.com/link?url=GTo5q8E1iVRYIYa-AiDP6_PJ4sQk7j1SPTr-CthVBw9hTGLPgR4TOeq9o8Sg0yEJ ...

  9. apache+mysql+php的环境配置

    一 配置前的准备 1 先设置环境变量(win7的) win10 二 配置apache 我用EditPlus打开httpd.conf LoadModule php5_module  "c:/w ...

  10. MySQL 复制表

    MySQL 复制表 如果我们需要完全的复制MySQL的数据表,包括表的结构,索引,默认值等. 如果仅仅使用CREATE TABLE ... SELECT 命令,是无法实现的. 本文将为大家介绍如何完整 ...