在学习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、SybaseDML操作
/*删表*/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表示条件语句
查询结果:参考相关博文: