(点击
上方蓝字
,快速关注我们)
来源:工匠若水
链接:blog.csdn.net/yanbober/article/details/45581751
本篇继续接上一篇,阅读上一篇《
Sqlite全面学习(2)
》
约束是在表的数据列上强制执行的规则。这些是用来限制可以插入到表中的数据类型。这确保了数据库中数据的准确性和可靠性。约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整个表。
以下是在SQLite中常用的约束:
默认情况下,列可以保存NULL值。如果您不想某列有NULL值,那么需要在该列上定义此约束,指定在该列上不允许NULL值。NULL与没有数据是不一样的,它代表着未知的数据。
示例语法:
CREATE
TABLE
AndroidTeam(
id
INT
PRIMARY KEY
NOT NULL
,
name
TEXT
NOT NULL
,
age
INT
NOT NULL
,
address
CHAR
(50),
money
REAL
);
DEFAULT约束
DEFAULT约束在INSERT INTO语句没有提供一个特定的值时,为列提供一个默认值。
示例语法:
CREATE
TABLE
AndroidTeam(
id
INT
PRIMARY KEY
NOT NULL
,
name
TEXT
NOT NULL
,
age
INT
NOT NULL
,
address
CHAR
(50),
money
REAL
DEFAULT
4500.0
);
UNIQUE约束
UNIQUE约束防止在一个特定的列存在两个记录具有相同的值。
示例语法:
CREATE
TABLE
AndroidTeam(
id
INT
PRIMARY KEY
NOT NULL
,
name
TEXT
NOT NULL
,
age
INT
NOT NULL
UNIQUE
,
address
CHAR
(50),
money
REAL
DEFAULT
4500.0
);
PRIMARY KEY约束
PRIMARY KEY约束唯一标识数据库表中的每个记录。在一个表中可以有多个UNIQUE列,但只能有一个主键。在设计数据库表时,主键是很重要的。主键是唯一的ID。我们使用主键来引用表中的行。可通过把主键设置为其他表的外键,来创建表之间的关系。主键是表中的一个字段,唯一标识数据库表中的各行/记录。主键必须包含唯一值。主键列不能有NULL值。一个表只能有一个主键,它可以由一个或多个字段组成。当多个字段作为主键,它们被称为复合键。如果一个表在任何字段上定义了一个主键,那么在这些字段上不能有两个记录具有相同的值。
示例语法:
CREATE
TABLE
AndroidTeam(
id
INT
PRIMARY KEY
NOT NULL
,
name
TEXT
NOT NULL
,
age
INT
NOT NULL
,
address
CHAR
(50),
money
REAL
);
CHECK约束
CHECK约束启用输入一条记录要检查值的条件。如果条件值为false,则记录违反了约束,且不能输入到表。
示例语法:
CREATE
TABLE
AndroidTeam(
id
INT
PRIMARY KEY
NOT NULL
,
name
TEXT
NOT NULL
,
age
INT
NOT NULL
,
address
CHAR
(50),
money
REAL
CHECK
(money
>
0)
);
SQLite支持ALTER TABLE的有限子集。在SQLite中,ALTER TABLE命令允许用户重命名表,或向现有表添加一个新的列。重命名列,删除一列,或从一个表中添加或删除约束都是不可能的。
SQLite的Joins子句用于结合两个或多个数据库中表的记录。JOIN是一种通过共同值来结合两个表中字段的手段。
SQL定义了三种主要类型的连接:
交叉连接(CROSS JOIN)把第一个表的每一行与第二个表的每一行进行匹配。如果两个输入表分别有 x 和 y 列,则结果表有 x+y 列。由于交叉连接(CROSS JOIN)有可能产生非常大的表,使用时必须谨慎,只在适当的时候使用它们。
语法:
SELECT ... FROM table1 CROSS JOIN table2 ...;
如下展示示例:
内连接(INNER JOIN)根据连接谓词结合两个表(table1和table2)的列值来创建一个新的结果表。查询会把table1中的每一行与table2中的每一行进行比较,找到所有满足连接谓词的行的匹配对。当满足连接谓词时,A和B行的每个匹配对的列值会合并成一个结果行。
内连接(INNER JOIN)是最常见的连接类型,是默认的连接类型。INNER 关键字是可选的。
语法:
SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression ...;
为了避免冗余,并保持较短的措辞,可以使用USING表达式声明内连接(INNER JOIN)条件。这个表达式指定一个或多个列的列表:
SELECT ... FROM table1 JOIN table2 USING ( column1 ,... ) ...;
自然连接(NATURAL JOIN)类似于JOIN…USING,只是它会自动测试存在两个表中的每一列的值之间相等值:
SELECT ... FROM table1 NATURAL JOIN table2...;
如下展示示例:
外连接(OUTER JOIN)是内连接(INNER JOIN)的扩展。虽然 SQL标准定义了三种类型的外连接:LEFT、RIGHT、FULL,但SQLite只支持左外连接(LEFT OUTER JOIN)。外连接(OUTER JOIN)声明条件的方法与内连接(INNER JOIN)是相同的,使用 ON、USING或NATURAL关键字来表达。最初的结果表以相同的方式进行计算。一旦主连接计算完成,外连接(OUTER JOIN)将从一个或两个表中任何未连接的行合并进来,外连接的列使用NULL值,将它们附加到结果表中。
左外连接(LEFT OUTER JOIN)的语法:
SELECT ... FROM table1 LEFT OUTER JOIN table2 ON conditional_expression ...;
为了避免冗余,并保持较短的措辞,可以使用USING表达式声明外连接(OUTER JOIN)条件。这个表达式指定一个或多个列的列表:
SELECT ... FROM table1 LEFT OUTER JOIN table2 USING ( column1 ,... ) ...;
如下展示示例:
SQLite的UNION子句/运算符用于合并两个或多个SELECT语句的结果,不返回任何重复的行。为了使用UNION,每个SELECT被选择的列数必须是相同的,相同数目的列表达式,相同的数据类型,并确保它们有相同的顺序,但它们不必具有相同的长度。
语法:
SELECT
column1
[,
column2
]
FROM
table1
[,
table2
]
[
WHERE
condition
]
UNION
SELECT
column1
[,
column2
]
FROM
table1
[,
table2
]
[
WHERE
condition
]
如下展示示例:
UNION ALL运算符用于结合两个SELECT语句的结果,包括重复行。适用于UNION的规则同样适用于UNION ALL运算符。
语法:
SELECT
column1
[,
column2
]
FROM
table1
[,
table2
]
[
WHERE
condition
]
UNION ALL
SELECT
column1
[,
column2
]
FROM
table1
[,
table2
]
[
WHERE
condition
];
这里给定的条件根据需要可以是任何表达式。
如下展示示例:
SQLite的NULL是用来表示一个缺失值的项。表中的一个NULL值是在字段中显示为空白的一个值。带有NULL值的字段是一个不带有值的字段。NULL值与零值或包含空格的字段是不同的,理解这点是非常重要的。
语法示例:
CREATE
TABLE
AndroidTeam
(
id
INT
PRIMARY KEY
NOT NULL
,
name
TEXT
NOT NULL
,
age
INT
NOT NULL
,
address
CHAR
(50),
money
REAL
);
这里NOT NULL表示列总是接受给定数据类型的显式值。这里有两个列我们没有使用NOT NULL,这意味着这两个列可能为NULL。带有NULL值的字段在记录创建的时候可以保留为空。NULL值在选择数据时会引起问题,因为当把一个未知的值与另一个值进行比较时,结果总是未知的,且不会包含在最后的结果中。
如下展示示例:
您可以暂时把表或列重命名为另一个名字,这被称为别名。使用表别名是指在一个特定的SQLite语句中重命名表。重命名是临时的改变,在数据库中实际的表的名称不会改变。列别名用来为某个特定的SQLite语句重命名表中的列。
表别名语法:
SELECT
column1,
column2...
FROM
table_name
AS
alias_name
WHERE
[
condition
];
列别名语法:
SELECT
column_name
AS
alias_name
FROM
table_name
WHERE
[
condition
];
如下实例语句:
SELECT a.id, a.name, a.age, b.position FROM teamTable AS a, monkeyTable AS b WHERE a.id = b.tid;
SELECT a.id AS aid, a.name AS aname, a.age, b.position FROM teamTable AS a, monkeyTable AS b WHERE a.id = b.tid;
SQLite的触发器是数据库的回调函数,它在自动执行/指定的数据库事件发生时调用。以下是关于SQLite的触发器的要点:
创建触发器(Trigger)语法:
CREATE
TRIGGER
trigger_name
[
BEFORE
|
AFTER
]
event_name
ON
table_name
BEGIN
-- Trigger logic goes here....
END
;
在这里,event_name 可以是在所提到的表 table_name上的INSERT、DELETE和UPDATE数据库操作。您可以在表名后选择指定FOR EACH ROW。
以下是在UPDATE操作上在表的一个或多个指定列上创建触发器(Trigger)的语法:
CREATE
TRIGGER
trigger_name
[
BEFORE
|
AFTER
]
UPDATE
OF
column_name
ON
table_name
BEGIN
-- Trigger logic goes here....
END
;
如下实例语句:
您可以从sqlite_master表中列出所有触发器,如下所示:
SELECT name FROM sqlite_master WHERE type = 'trigger';
上面的 SQLite 语句只会列出一个条目,如下:
name
----------
audit_log
如果您想要列出特定表上的触发器,则使用AND子句连接表名,如下所示:
SELECT name FROM sqlite_master WHERE type = 'trigger' AND tbl_name = 'teamTable';
上面的 SQLite 语句只会列出一个条目,如下:
name
----------
audit_log
删除触发器(TRIGGERS)
下面是DROP命令,可用于删除已有的触发器:
DROP TRIGGER trigger_name;
SQLite索引(Index)
索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。例如,如果您想在一本讨论某个话题的书中引用所有页面,您首先需要指向索引,索引按字母顺序列出了所有主题,然后指向一个或多个特定的页码。
索引有助于加快SELECT查询和WHERE子句,但它会减慢使用UPDATE和INSERT语句时的数据输入。索引可以创建或删除,但不会影响数据。使用CREATE INDEX语句创建索引,它允许命名索引,指定表及要索引的一列或多列,并指示索引是升序排列还是降序排列。索引也可以是唯一的,与UNIQUE约束类似,在列上或列组合上防止重复条目。
CREATE INDEX命令:
CREATE INDEX基本语法:
CREATE INDEX index_name ON table_name;
单列索引
单列索引是一个只基于表的一个列上创建的索引。基本语法:
CREATE INDEX index_name ON table_name (column_name);
唯一索引
使用唯一索引不仅是为了性能,同时也为了数据的完整性。唯一索引不允许任何重复的值插入到表中。基本语法:
CREATE UNIQUE INDEX index_name on table_name (column_name);
组合索引
组合索引是基于一个表的两个或多个列上创建的索引。基本语法:
CREATE INDEX index_name on table_name (column1, column2);
是否要创建一个单列索引还是组合索引,要考虑到您在作为查询过滤条件的WHERE子句中使用频繁的列。如果值使用到一个列,则选择使用单列索引。如果在作为过滤的WHERE子句中有两个或多个列经常使用,则选择使用组合索引。
隐式索引
隐式索引是在创建对象时,由数据库服务器自动创建的索引。索引自动创建为主键约束和唯一约束。
如下实例演示:
CREATE
INDEX
money_index
ON
teamTable
(money);
查看索引:
.indices
teamTable
结果:
salary_index
sqlite_autoindex_COMPANY_1
//创建表时创建的隐式索引
列出数据库范围的所有索引:
SELECT
*
FROM
sqlite_master
WHERE
type
=
'index'
;
DROP INDEX命令:
一个索引可以使用SQLite的DROP命令删除。当删除索引时应特别注意,因为性能可能会下降或提高。
基本语法:
DROP INDEX index_name;
什么情况下避免使用索引
索引的目的在于提高数据库的性能,但这里有几个情况需要避免使用索引。使用索引时,应重新考虑下列准则:
“INDEXED BY index-name”子句规定必须需要命名的索引来查找前面表中值。如果索引名index-name不存在或不能用于查询,然后SQLite语句的准备失败。”NOT INDEXED” 子句规定当访问前面的表(包括由UNIQUE和PRIMARY KEY约束创建的隐式索引)时,没有使用索引。然而,即使指定了 “NOT INDEXED”,INTEGER PRIMARY KEY 仍然可以被用于查找条目。
下面是INDEXED BY子句的语法,它可以与DELETE、UPDATE 或 SELECT 语句一起使用:
SELECT
|
DELETE
|
UPDATE
column1,
column2...
INDEXED
BY
(index_name)
table_name
WHERE
(
CONDITION
);
如下实例:
假设有表teamTable表,我们将创建一个索引,并用它进行INDEXED
BY
操作:
CREATE
INDEX
money_index
ON
teamTable(money);
现在使用INDEXED
BY
子句从表teamTable中选择数据:
SELECT
*
FROM
teamTable
INDEXED
BY
money_index
WHERE
money
>
5000;
SQLite Alter命令
SQLite的ALTER TABLE命令不通过执行一个完整的转储和数据的重载来修改已有的表。您可以使用ALTER TABLE语句重命名表,使用ALTER TABLE语句还可以在已有的表中添加额外的列。在SQLite中,除了重命名表和在已有的表中添加列,ALTER TABLE命令不支持其他操作。
用来重命名已有的表的ALTER TABLE语法:
ALTER TABLE database_name.table_name RENAME TO new_table_name;
用来在已有的表中添加一个新的列的ALTER TABLE语法:
ALTER TABLE database_name.table_name ADD COLUMN column_def...;
如下展示示例:
ALTER
TABLE
teamTable
RENAME
TO
androidTeamTable;