这篇文章主要是围绕 SQLite,记录总结 SQL 的一些用法。
至于 iOS 中其余的几种存储方式例如 .plist 等,以及数据库的概念,SQL 的概念等,先不做介绍。


SQL 的特点

  1. 不区分大小写。
  2. 每条语句必须以分号 ; 结尾。
  3. 不可以使用关键字来命名表、字段。(关键字见下一小节)

SQL 中的关键字

selectinsertupdatedeletefromcreatewheredescorderbygrouptablealterviewindex etc.

  • 注意,为了保持良好的数据库编程习惯,我们在编写 SQL 语句的时候,应当采用关键字大写的形式。

SQL 语句的种类

DDL 数据定义语句

数据定义语句 DDL 的全称是 Data Definition Language

其包含 createdrop 等操作。create创建表 (create table) 。drop 则是 删除表drop table)。

DML 数据操作语句

数据操作语句 DML 的全称是 Data Manipulation Language

包括 insertupdatedelete 等操作。

第一次接触的时候,只看这些关键词的话可以会误解 delete 为删除表的操作。实则不然,DML 全部都是对 数据 的操作,DDL 才是对于表的操作。

所以这里 insert 为在表中 添加 (插入)数据,update修改 表中的数据,delete删除 表中的数据。

DQL 数据查询语句

数据查询语句 DQL 的全称是 Data Query Language。用于查询并获得表中的数据。

关键字 selectDQL (也是所有 SQL )用的最多的操作。

其他的 DQL 常用的关键字有 whereorder bygroup byhaving 等。


SQL基础操作

以下内容就是重点要记录的部分了。为了更加清晰的划分各个模块,以下内容将使用分割线来对各个模块进行划分。

创表

CREATE TABLE 表名 (字段名1 字段类型1, 字段名2 字段类型2, ...);

上面个这条语句是最基本的创表语句,create 关键字 和 table 关键字连用,用于创建一张表,用 () 英文括号将多个 字段名字段类型 括起来。

一般的,我们不使用上面那条语句,为了更加的安全,我们使用 下面这种写法进行表的创建

CREATE TABLE IF NOT EXISTS 表名 (字段名1 字段类型1, 字段名2 字段类型2, ...);

IF NOT EXISTS 用于判断所要创建的 表是否存在,如果不存在的话才会创建。

举个例子的话创建一张表的实际语句是这样的:

CREATE TABLE IF NOT EXISTS t_student (id integer, name text, age inetger, score real);
  • tip: 又一则良好的 SQL 编码习惯——在创建表时,表名前加上 t_ 来表明这是一张表,同理,创建视图时使用 v_ 来表明视图。

然而,当我们使用例如 Navicat Premium 等软件,在 GUI 中创建表,然后使用 DDL 查看该表的创表语法时,我们会看到如下的语句:

CREATE TABLE "t_shop" (
  "name" text,
  "price" real,
  "left_count" integer
);

表名和字段名都加了引号。我稍微查了一下,好像 oracle 是需要加引号的,好像和大小写有关。不过在 SQLite 中不加引号即可。毕竟 Navicat Premium 中集成了多种数据库,不是仅有 SQLite

字段类型

SQLite 将数据划分为以下几种存储类型:

名称 含义
integer 整型值
real 浮点值
text 文本字符串
blob 二进制数据(比如文件)

然而呢,实际上 SQLite无类型 的。就算我们将一个字段声明为 integer,还能可以存储类如 字符串之类的数据(注意,这里 主键除外)。

这也就意味着我们在建表的时候实际上是可以不声明类型的,只声明名称即可。但是为了保持良好的编程习惯,可可读性等等,我们还是应该声明类型的


删表

删表的时候使用关键字 drop,和创表时一样,分为普通的写法和我们平时会用到的写法。这里就直接给出后者了:

DROP TABLE IF EXISTS 表名;

举个例子:

DROP TABLE IF EXISTS t_student;

插入数据

INSERT INTO 表名 (字段1, 字段2, ...) values (字段1的值, 字段2的值, ...);

提炼一下上述语法,即 insert into ... values ...。感觉还是很好理解的:插入到... 它的值是 ...

举例来说:

INSERT INTO t_student (name, age) VALUE ('mj', 10);
  • 注意:
    1. 在存储 字符串 时,我们应当使用 单引号 将其括起来。
    2. 在插入数据时,并不一定要每个字段都有值,即表名后面的那个括号,不必包含表中的所有字段。

更新数据

UPDATE 表名 SET 字段1 = 字段1的值, 字段2 = 字段2的值, ...;

上面便是更新数据的语法格式,但是如果仅仅是套用这个格式的话,例如下面这条语句:

UPDATE t_student SET name = 'jack', age = 20;

这条语句将会将整张表的所有数据,name 字段的值都改为 jackage 字段的值都改为20。

所以在使用的时候我们还要结合下一大节的条件语句进行使用。


删除数据

DELETE FROM 表名;

删除数据的一般语法也很简单,但是和更新数据一样。执行了上面的操作之后,整张表的所有数据都会被删除。所以也要结合条件语句进行使用。


条件语句

创表删表 时,我们曾经使用过 if 这个关键词,可以理解为如果。但是这个 if 并不是条件判断语句的用词。

在条件判断语句中,我们使用 where 关键字,可以翻译为 当....时,初次接触时我很好奇,如果不使用 if 的话,为什么不用 when 呢?感觉这里可能更是为了突出 在某行记录 的这个概念吧。

条件语句的格式也很好记忆,即在需要条件判断的语句后面,跟上由 where 开头的条件判断语句即可。

格式 含义
WHERE 字段 = 某个值 字段的值是否等于某个值
WHERE 字段 != 某个值 字段的值是否不等于某个值
WHERE 字段 > 某个值 字段的值是否大于某个值
WHERE 字段 < 某个值 字段的值是否小于某个值
WHERE 字段1 = 某个值 AND 字段2 > 某个值 关键字 AND 用于连接两个判断条件
WHERE 字段1 = 某个值 OR 字段2 > 某个值 关键字 OR 用于连接两个判断条件

举例:

-- 将 t_student 表中年龄大于10并且姓名不等于jack的记录,年龄都改为5。
UPDATE t_student SET age = 5 WHERE age > 10 AND name != 'jack';

-- 删除 t_student 表中年龄小于等于 10 或者 年龄大于 30 的记录。
DELETE FROM t_student WHERE age < 10 OR age > 30;

-- 将 t_student 表中名字等于 jack 的记录,score 字段的值都改为 age 字段的值。
UPDATE t_student SET score = age WHERE name = 'jack';
  • 特别注意:在 SQLite 中,等于 这个概念使用的是 单独的等号。和 Obj-C 以及其他大部分编程语言都不相同。

查询数据

查询操作使用关键字 select。格式为:

SELECT 字段1, 字段2, ... FROM 表名;

如果我们想要查询整张表的数据,可以使用 * 号来代替字段名,即

SELECT * FROM 表名;

举个例子:

SELECT name, age FROM t_student;
SELECT * FROM t_student WHERE age > 10;

别名

在进行查询操作时,我们可以为 字段 起一个 别名,从而我们我们查看或者进行某些操作。不过需要注意的是,别名 顾名思义,只是另外一个称呼,并不会修改字段本身的名称。

别名 使用关键字 as,不过该关键字是可以省略的,而且,这个别名可以使用 中文。其格式如下:

-- 最基本的写法为:
SELECT 字段1 AS 别名1, 字段2 AS 别名2, ... FROM 表名 AS 表别名;

-- 当隐藏 AS 时
SELECT 字段1 别名1, 字段2 别名2, ... FROM 表名 表别名;

同时,如果我们为表起了一个 别名,那么我们在查询时就可以这么定义需要查询的字段:

SELECT 表别名.字段1 别名1, 表别名.字段2 别名2, ... FROM 表名 表别名;

即用 表别名 后接 . 再接字段名的格式,用 表别名 来引用表中的字段。这样做的好处是,在使用如 Navicat Premium 时,可以提示该表有哪些字段,以防字段太多我们记不清楚。而且当多表联查时出现了字段名重名的问题的话,表别名 也是一个很好的解决办法。

举个例子:

SELECT s.name 姓名, s.age 年龄 FROM t_student s;

计算记录的数量

SQL 中有这么一个函数 count() ,其作用为记录某个字段的数量。格式为:

SELECT COUNT(字段名) FROM 表名;

不过一般来说,我们直接使用 * 号来代替字段名。即:

SELECT COUNT(*) FROM 表名;

举个例子:

SELECT COUNT(*) FROM t_student WHERE score >= 60;

查询结果排序

我们可以使用关键字 order by 对查询结果进行排序,其格式为:

SELECT 字段名 FROM 表名 ORDER BY 字段名 排序规则;

其默认是按照 asc ,即升序排列。我们可以显示的修改排序规则,改为 desc, 即降序排列。如果省略排序规则的话,则是默认的升序排列。

举个例子:

-- 省略排序规则。(按照升序排列
SELECT * FROM t_student ORDER BY age;

-- 降序排列
SELECT * FROM t_student ORDER BY age DESC;

同时我们还可以指定按照多个字段进行排序,例如下面这条语句:

SELECT * FROM t_student ORDER BY age ASC, height DESC;

这条语句会将查询结果按照字段 age 升序排列,年龄相等的话就会按照字段 height 降序排列。


未完待续 ...