昨天我学习了创建表与建立索引,今天来学习一些语句规范等等。
首先,查询两个表的时候,结果会返回它们的笛卡尔积,来自第一个数据集的每一行都将 与来自第二个数据集的任何可能的行进行联接。 这样会得到庞大的结果集,完成操作需要很长时间,并且大量消耗系统资源。
于是,我们在两表查询的语句中设置一些适当的限制,来控制笛卡尔积,得到想要的明确的结果,让结果有意义。
为了避免产生歧义,在查询中要规定:表名.列字段。例如
WHERE counties.region_id = region.region_id
这就是添加join条件,控制笛卡尔积的结果,使得结果清晰明了。
SELECT c.county_id AS county_id,
c.county_name AS county_name,
c.car_plate_code AS car_plate_code,
r.region_id AS region_id,
r.region_name AS region_name
FROM counties AS c,
regions AS r
WHERE c.region_id = r.region_id;
其中AS是为了给列和表定义别名,为了让sql语句不繁琐,使join查询更加简洁和可读。
性能考量
执行涉及许多不同表的复杂查询可能会很慢且缓慢地运行。当此类表包含大量行时,最容易注意到这一点。 解释所有这些并不是一件容易的事:为了计算笛卡尔乘积,SQL引擎必须访问查询涉及的每个表很多次。 基本行为是每次执行全表扫描的行为:显然,多次扫描长表需要很长时间。 因此,优化查询的主要要点就是尽可能避免使用 全表扫描。 所有这些都得到完全支持,并且易于实现。 每当SQL计划者(SQL引擎的内部组件 )检测到适当的 INDEX 可用时,根本就不需要执行全表扫描,因为现在可以使用此索引立即访问每一行。这显然将是一个更快的过程。JOIN 子句中经常使用的任何列(或一组列)都是对应INDEX的良好候选者。 无论如何,创建索引意味着几个负面后果:
DB文件所需的存储分配将增加(有时会急剧增加)。
执行INSERT, UPDATE和/或 DELETE操作将需要更长的时间,因为必须相应地更新索引。
这显然增加了额外的开销。
因此(毫不奇怪),这是一个折衷的过程:您必须仔细评估何时 绝对需要INDEX,并尝试达到均衡的组合。
也就是说,在各种条件下和不同用户情况下,对比要求之间的折衷。
换句话说,没有绝对的规则:必须找到执行多个实际测试的最佳案例解决方案,直到获得满足要求的最佳解决方案。
另一种查询方式
SELECT lc.lc_id AS lc_id,
lc.lc_name AS lc_name,
lc.population AS population,
c.county_id AS county_id,
c.county_name AS county_name,
c.car_plate_code AS car_plate_code,
r.region_id AS region_id,
r.region_name AS region_name
FROM local_councils AS lc
JOIN counties AS c ON (
lc.county_id = c.county_id)
JOIN regions AS r ON (
c.region_id = r.region_id);
使用JOIN ... ON(...) 可以更清楚表达。
JOIN 条件现在可以直接在ON(...)术语内表达 。这样,查询语句的结构更好,可读性更高。只是语法的区别,两种查询在功能上完全没有区别 。
关于SQLite数据类型
SQLite没有数据类型,可以在每列上插入任何数据类型:声明数据类型的列仅具有装饰性作用,但既不检查也不执行完全没有 ,它是一种特殊的设计选择。 其他不同的DBMS都会应用强大的数据类型限定和强制执行,因此SQLite自己的行为可能很容易显得奇怪和令人困惑。
SQLite内部都支持以下数据类型:
NULL:完全没有值。
INTEGER:实际上是 64位整数,因此要支持非常大的值。
DOUBLE:浮点数,双精度。
TEXT:任何不受限制的任意长度的 UTF-8编码的文本字符串。
BLOB:任何不受限制的任意长度的通用 Binary Long Object。
请记住:每个单元格 (行/列的交集)都可以存储任意数据类型。
存在一个独特的例外:声明为INTEGER PRIMARY KEY的列 绝对需要整数值。
在创建完表之后,完全可以增加列,语句如下:
ALTER TABLE peoples2
ADD COLUMN cell_phone TEXT;
另外,sqlite不支持删除列以及重命名,只能删除表。
网友评论