摘要:前提是对应外键列没有指定限定词。在标准中,意味着不采取任何动作。拒绝对父表的删除或更新操作。扩展创建外键约束示例如果,我们用的是数据库创建的外键,也发生不能约束的问题,不过和不同的是,是因为只有引擎才可以约束。
iOS中的数据存储方式在学习Sqlite之前,先看一下IOS中的数据存储都有哪些方式?
Plist(NSArrayNSDictionary)
Preference(偏好设置NSUserDefaults)
NSCoding(NSKeyedArchiverNSkeyedUnarchiver)
SQLite3
Core Data
SQLite什么是SQLite?
SQLite是一款轻型的嵌入式数据库
它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了
它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快
常用关系型数据库
PC端:Oracle、MySQL、SQL Server、Access、DB2、Sybase
/*删表*/ 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数据库创建的外键,也发生不能约束的问题,不过和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中的外键约束问题
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/16325.html
摘要:前提是对应外键列没有指定限定词。在标准中,意味着不采取任何动作。拒绝对父表的删除或更新操作。扩展创建外键约束示例如果,我们用的是数据库创建的外键,也发生不能约束的问题,不过和不同的是,是因为只有引擎才可以约束。 在学习Sqlite之前,先看一下IOS中的数据存储都有哪些方式? iOS中的数据存储方式 Plist(NSArrayNSDictionary) Preference(偏好设置...
摘要:看图从打印的记录可以看出,定时器每隔两秒会调用未读消息数的方法,但是当我们滚动下拉时,定时器就会停止打印,定时器的线程在主线程,我们应该放在子线程让处理。 上一节完成了提醒数字的功能,但是还存在问题,就是当我们下拉或上拉首页内容时,底下的提醒数字不会改变,因为图片轮播器,主线程忙着处理滚动,没有时间算计时器的时间,所以,不会请求获取提醒数字的接口,导致这样的问题出现。 看图:从打印的记...
摘要:微博项目使用管理,将项目文件推送到以方便管理,研究说明按照以下的第一九步骤即可推送到远程仓库。先在本地初始化建立跟踪目录,然后推送到远程代码库即可。一创建一个本地代码库我们首先需要告诉这个文件夹是我们需要跟踪的项目。 微博项目使用github管理,将项目文件推送到github以方便管理,研究 说明:按照以下的第一、九步骤即可推送到远程仓库。先在本地初始化建立git跟踪目录,然后推送到远...
摘要:本节将实现从新浪的接口获取到用户的未读消息数,并显示在底部的上,通过定时器每隔几秒请求新浪的接口,然后将获得的各种消息数通过显示出来。 本节将实现从新浪的接口获取到用户的未读消息数,并显示在底部的Tabbar上,通过定时器每隔几秒请求新浪的接口,然后将获得的各种消息数通过badgeValue显示出来。 封装提醒未读数的请求参数和返回参数的数据模型 在Home(首页)/Model/use...
阅读 2125·2021-10-11 10:58
阅读 2852·2019-08-30 15:56
阅读 1074·2019-08-29 15:20
阅读 1412·2019-08-29 13:19
阅读 1310·2019-08-29 13:10
阅读 2066·2019-08-27 14:26
阅读 3247·2019-08-26 18:27
阅读 2916·2019-08-26 11:46