在学习Sqlite之前,先看一下IOS中的数据存储都有哪些方式?

iOS中的数据存储方式

  • Plist(NSArrayNSDictionary)

  • Preference(偏好设置NSUserDefaults)

  • NSCoding(NSKeyedArchiverNSkeyedUnarchiver)

  • SQLite3

  • Core Data

SQLite

什么是SQLite?
SQLite是一款轻型的嵌入式数据库
它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了
它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快

常用关系型数据库
PC端:Oracle、MySQL、SQL Server、Access、DB2、Sybase

DML操作


/*删表*/
DROP table IF EXISTS student_tbl;

/* 创建表 */
CREATE table if not EXISTS student_tbl  (id integer primary key autoincrement, name text, age integer, score real);

/* 插入 */
INSERT INTO student_tbl (id, name, age, score) VALUES (1, 'Jack', 25, 80);

外键

利用外键约束可以用来建立表与表之间的联系
外键的一般情况是:一张表的某个字段,引用着另一张表的主键字段

外键约束条件有以下几种:
  · CASCADE : 从父表删除或更新行时自动删除或更新子表中匹配的行。
  · SET NULL : 从父表删除或更新行时自动设置子表对应的外键列值为NULL。前提是对应外键列没有指定NOT NULL限定词。
  · NO ACTION : 在ANSI SQL-92标准中,NO ACTION意味着不采取任何动作。
  · RESTRICT : 拒绝对父表的删除或更新操作。

外键约束

  • 建立表与表之间联系

  • 可以约束数据之间的规范

  • 让数据库自己通过外键来保证数据的完整性和一致性

如有有两个表,一个为班级表class_tbl,一个为学生详情表student_tbl,某一个学生属于某一个班级,这时如果不建立班级外键,则学生表可以随意写一个班级ID,即使在班级表中没有该class_id,而如果建立外键之后,则对学生表中的班级ID有一个规范,学生表中的班级ID只能是班级表中的班级class_id,如果删除班级表中的某一个班级ID,则会出现错误,因为学生表有用班级表的ID,有相互依赖,不能删除,所以,这就是外键的好处。

新建一个外键:

create table student_tbl (id integer primary key autoincrement, name text, age integer, class_id integer,
 constraint fk_student_tbl_class_id_class_tbl_id foreign key (class_id) references class_tbl(id)); 

student_tbl表中有一个叫做fk_student_tbl_class_id_class_tbl_id的外键
这个外键的作用是用student_tbl表中的class_id字段引用class_tbl表的id字段.

完整sql代码:

/* 创建班级表 */
CREATE table if not EXISTS class_tbl  (id integer PRIMARY KEY AUTOINCREMENT, name text);

/* 插入 */
INSERT INTO class_tbl (name) VALUES ('三年1班');
INSERT INTO class_tbl (name) VALUES ('三年2班');
INSERT INTO class_tbl (name) VALUES ('三年3班');
INSERT INTO class_tbl (name) VALUES ('三年4班');
INSERT INTO class_tbl (name) VALUES ('三年5班');


/* 创建学生表-外键 */
create table student_tbl (id integer primary key autoincrement, name text, age integer, class_id integer,
 constraint fk_student_tbl_class_id_class_tbl_id foreign key (class_id) references class_tbl(id));

constraint:约束

查看外键

插入学生数据
咦,添加一个不存在的class_id外键,居然可以成功,外键约束怎么不管用呀?什么原因呢???!!!
图片描述

因为:Sqlite外键默认是关闭的,所以每次进入数据库时,都需要打开外键PRAGMA foreign_keys = ON。

/* 开启外键 */
PRAGMA foreign_keys = ON;

/*插入数据 --- 外键class_id不存在class_tbl表,会报错*/
INSERT INTO student_tbl (id, name, age, class_id) VALUES (1, 'Jack', 25, 99);

这时,打开外键后,当我们插入一个在class_tbl表中不存在的class_id=99数据时,就会报约束错误。
图片描述

当改为class_id=1时,就会插入成功。
图片描述

扩展:mysql 创建外键约束示例

如果,我们用的是Mysql数据库创建的外键,也发生不能约束的问题,不过和sqlite不同的是,Mysql是因为只有innodb引擎才可以约束。

mysql 创建外键约束示例,注意student_tbl表为ENGINE=InnoDB引擎

CREATE TABLE `student_tbl` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `class_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_student_tbl_class_id_tbl_id` (`class_id`),
  CONSTRAINT `fk_student_tbl_class_id_tbl_id` FOREIGN KEY (`class_id`) REFERENCES `class_tbl` (`class_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

表连接查询

什么是表连接查询?
表连接查询也叫多表查询
需要联合多张表才能查到想要的数据

表连接的类型
内连接:inner join 或者 join (显示的是左右表都有完整字段值的记录)
左外连接:left outer join (保证左表数据的完整性)

示例
如果,我要查询“三年2班”的学生,但是我不知道“三年2班”的班级ID,这时需要怎么查询呢?可以通过联合查询法,不需要先查出班级ID,然后再到student_tbl表中根据class_id查询“三年2班”的学生。

/* 表联合查询 */
SELECT * FROM class_tbl c, student_tbl s WHERE c.id = s.class_id AND c.name='三年2班';

查询结果:
图片描述

内连接 INNER JOIN
查出学生及班级名:

/* 表联合查询 - INNER JOIN*/
SELECT s.name sname, c.name cname FROM student_tbl s  INNER JOIN class_tbl c;

如果不加约束条件,会出现这样的笛卡尔结果:
图片描述

添加约束条件:

/* 表联合查询 - INNER JOIN*/
SELECT s.name sname, c.name cname FROM student_tbl s  INNER JOIN class_tbl c ON s.class_id = c.id;

此处的ON=WHERE表示条件语句
查询结果:
图片描述

参考相关博文:
SQLite外键(Foreign Key)支持
详解MySQL中的外键约束问题


Corwien
6.3k 声望1.6k 粉丝

为者常成,行者常至。