在学习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数据时,就会报约束错误。
扩展: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;
参考相关博文:
SQLite外键(Foreign Key)支持
详解MySQL中的外键约束问题