数据库概念 (.db)
数据的集散地,有效地存储和管理数据。App如果有大量的数据需要进行本地存储就可以考虑使用数据库技术,它不仅能够有效的存储和管理数据,更重要的是提供了方便的检索数据的手段。简单的说,数据库是实现数据持久化的重要方案,其他的方案包括:plist文件、archieve归档、NSUserDefaults、普通文件等。
数据库类型
Oracle:甲骨文数据库—>当今牛逼关系型数据库
DB2:IBM公司的产品,数据仓库和数据挖掘功能非常强大
SQLServer:微软的产品,适合微软自己的Windows服务器环境
MySQL:开源的数据库产品,中小型站点的数据库服务器首选
关系型数据库
1.用二维表组织数据(行:一条记录;列:一条字段)
主键�:能够唯一标识一条记录的字段(比如库中已有的学号,再录相同的不能录);添加这个primary key表示它是主键
外键:其他表的主键(外来的主键);例如两张表人与身份证例子
pragma foreign_key=on
2.结构化查询语言(SQL)
SQL分4部分:
DDL:数据定义语言create(创建;可以加前缀命名—>如创建学生表: create Table TBstudent)/drop(删除)/alter(修改)
DML:操作insert(添加)/delete(删除)/update(更新)
DQL:查询select (重点)
DCL:控制grant/revoke
1.关系代数
2.集合论
3.实体关系图(ER图)
实体间关系:
一对一:人与身份证
一对多:部门和员工
多对一:读者与图书
4.事务--->ACID
即:Atomic;Consistency;Isolation;Duration
要么全成功,要么全失败;要么全做,要么全不做。(以银行转账为例)
SQLite-->属于嵌入式数据库系统(重点)
(理论上:整个数据库最多可装4T;一个字段可装4g)
SQLite:嵌入式关系型数据库;特点:轻量级、跨平台
1.是一种基于C语言开发的轻型数据库
2.在iOS中需要用C语言进行对数据库的操作、访问(无法用oc;因为libsqlite3框架基于c语言编写)
3.SQLite采用动态数据类型
4.要使用SQLite很简单,如果在Mac OSX上使用可以考虑到SQLite官方网站下载命令行工具,也可以使用类似于SQLiteManager、Navicat for SQLite等工具。
-启动SQLite:在终端键入sqlite3,提示符变成sqlite>
-常用命令:
.help --- 显示帮助信息
.quit/.exit --- 退出
.open --- 打开指定的数据库文件
.save --- 将内存中的数据库保存到指定的文件
.databases --- 显示数据库的信息
.schema ?TABLE? --- 显示表结构
.tables ?PATTERN? --- 显示所有的表
.mode MODE --- 设置输出模式
.stats ON|OFF --- 开启或关闭统计信息
.dump ?TABLE?--- 以SQL文本格式转存数据库
下面以学生表为例讲解相关基本知识
schema TbStudent查看学生表内容
tables列出所有表
header on 显示表头
—插入数据:
insert into TbStudent values(1001,'王大锤','男','重庆万州','1990-1-6');
insert into TbStudent (stuid,stuname) values(1002,'李林’);//部分项
—查询所有行所有列
select * from TbStudent;
—删除数据(要加条件,否则删除全部;下面同这)
delete from TbStudent where stuid=1004;
—更新数据
update TbStudent set stuaddr='四川绵阳',stubirth='1993.12.3' where stuid=1002;
(其中1002的没有加地址和出生)
--投影操作
select stuname,stusex from TbStudent;
--投影时别名(as可省,别名用法)
select stuname as 姓名 , stusex as 性别 from Tbstudent;
--数据筛选(可加关系:and or)
select *from TbStudent where stusex='女';
select *from TbStudent where stusex='女' and stuaddr='南京';
select *from TbStudent where stusex='女' or stubirth='1998-1-6';
select *from TbStudent where stubirth between '1985-1-1' and '1990-12-12';
select *from TbStudent where stubirth<'1990-12-1';
--模糊查询
select *from TbStudent where stuname like '王%';匹配任意多个字符
select *from TbStudent where stuname like'%王%';只要名字中有王字
select *from TbStudent where stuname like'王_';匹配精确一个字符
select *from TbStudent where stuname like'王__';
--排序(默认是升序的asc(可省);降序desc)[同时用筛选和排序,先筛后排]
select *from TbStudent order by stubirth;
select *from TbStudent order by stubirth desc;
select *from TbStudent order by stusex, stubirth desc;//先排性别后排出生
--统计数
select count(stusex) 总人数 from TbStudent;
--分组
select stusex,count(stusex)from TbStudent group by stusex;//男女各多少人
select stuaddr 家庭住址,count(stuaddr)as 总人数 from TbStudent group by stuaddr order by 总人数;
--聚合函数、分组函数
count
max
min
avg:平均数
sum
-----子查询(把一个查询的结果作为另一个查询的一部分来使用)
select stuname, stubirth from TbStudent where stubirth=(select min (stubirth) from TbStudent);//年龄最大的名字
select min(stubirth) from TbStudent;//选择出年龄最大
—分页查询(limit a,b—>a是第几条,b是从这条开始依次查b个)
select * from tbemp order by sal desc limit 10,5;//第10到14
-------连接查询(一次查询多张表)-----
--->内连接
--->外连接 ---> 左外连接(SQLite只支持左;即不管是否满足连接,都写出来,不满足的地方补空)、右外连接、全外连接
//以TbDept表和TbEmp表为例:
(注意:连接两张表时如果没有连接条件将产生笛卡尔积)
写法1:=
select empno,name,job,dname,dloc from TbEmp, Tbdept where TbEmp.dno =TbDept.deptno;
***
select empno,name,job,dname,dloc from TbEmp as t1, Tbdept as t2 where t1.dno =t2.deptno;
写法2:… inner jion … on
select empno, name, job, dname, dloc from TbEmp, inner join
TbDept on dno = deptno;
***
select empno, name, job, dname, dloc from TbEmp as t1 inner join TbDept as t2 on t1.dno = t2.deptno;
***查询薪水超过其所在部门平均薪水的员工的姓名、部门编号和工资
SELECT ename,deptno,sal from TbEmp as t1 inner join TbDept as t2 on sal>(SELECT avg(sal)from TbEmp where t1.dno=t2.deptno );
***查询部门中薪水最高的人姓名、工资和所在部门名称
SELECT ename,sal,dname from TbEmp as t1 inner join TbDept as t2 on sal=(SELECT max(sal) from TbEmp where t1.dno=t2.deptno);
***注意学会创建临时表
写在前面的是左表;写在后面的右表
-数据库数据:若只读取不对其操作则保存在Nsbundle
若对它要维护,修改则放在沙箱中(数据要长久放在doucument);创建数据库放沙箱的doucument文件
补充:简单认识core Data(苹果原生处理数据库的)
Core Data (ORM:可以将关系模型和对象模型互转)--->非常难用;可选用第三方库 --->ObjectRecord和
MagicalRecord
各类应用开发中只要牵扯到数据库操作通常都会用到一个概念“对象关系映射(ORM)iOS中ORM框架首选Core Data,这是官方推荐的,不需要借助第三方框架。无论是哪种平台、哪种技术,ORM框架的作用都是相同的,那就是将关系数据库中的表(准确的说是实体)转换为程序中的对象,其本质还是对数据库的操作(例如Core Data中如果存储类型配置为SQLite则本质还是操作的SQLite数据库)。使用Core Data进行数据库存取并不需要手动创建数据库,这个过程完全由Core Data框架完成,开发人员面对的是模型,主要的工作就是把模型创建起来,具体数据库如何创建则不用管。
FMDB(数据库第三方库)
1.官方提供的对SQLite的操作都是比较底层的C函数,用起来相对比较麻烦。FMDB对这些底层的东西进行了面向对象的封装,是一个非常好用的第三方库,使用时需要添加苹果提供的依赖库libsqlite3.dylib。
FMDB的核心API:
FMDatabase --- 代表数据库
FMResultSet --- 代表操作查询结果的游标
FMDatabaseAdditions --- 对FMDatabase类扩展的Category
FMDatabasePool --- 数据库连接池支持类
FMDatabaseQueue --- 数据库多线程操作支持类
2.例子讲解
// 创建数据库
- (void) createDb {
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/test.db"];
NSLog(@"%@", path);
self.db = [[FMDatabase alloc] initWithPath:path];
if([self.db open]) {
[self createTable];
}
else {
NSLog(@"创建数据库失败!");
}
}
// 创建表
- (void) createTable {
NSString *sql = @"create table if not exists tb_user (username varchar(20) primary key, password varchar(20) not null, email varchar(50));";
if([self.db executeUpdate:sql]) {
[self insertData];
}
else {
NSLog(@"创建用户表失败!");
}
}
// 插入数据
- (void) insertData {
NSString *sql = @"insert into tb_user values (?,?,?);";
if([self.db executeUpdate:sql, @"jackfrued", @"123456", @"[email protected]"]) {
}
else {
NSLog(@"插入数据失败!");
}
}
// 显示表中的记录
- (void) showRecords {
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/test.db"];
self.db = [[FMDatabase alloc] initWithPath:path];
if([self.db open]) {
NSString *sql = @"select * from tb_user";
FMResultSet *rs = [self.db executeQuery:sql];
NSLog(@"%d", rs.next);
while([rs next]) {
NSLog(@"Username: %@", [rs stringForColumn:@"username"]);
NSLog(@"Password: %@", [rs stringForColumn:@"password"]);
NSLog(@"Email: %@", [rs stringForColumn:@"email"]);
}
[self clearData];
}
else {
NSLog(@"创建数据库失败!");
}
}
- (void) clearData {
NSString *sql = @"delete from tb_user";
if([self.db executeUpdate:sql]) {
NSLog(@"清理数据成功!!!");
}
}