iOS-数据库-SQL语句

在上篇文章iOS-数据持久化存储中,我们学习了iOS中存储数据的一些方式,但是上篇文章中的方式都有一个共同的问题,那就是都无法存储大批量的数据,否则会有性能问题,大批量数据通常使用数据库来进行存储。

一. 数据库简介

  1. 什么是数据库

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库

  1. 数据库的分类

可以分为2大种类:
关系型数据库(主流)和对象型数据库(直接把内存中的对象塞入到数据库,对比关系型数据库而言性能不能很好,效率不高)

  1. 常用关系型数据库有哪些

PC端:Oracle、MySQL、SQL Server、Access、DB2、Sybase
嵌入式\移动客户端:SQLite

  1. 什么是SQLite

SQLite是一款轻型的嵌入式数据库,安卓和iOS开发使用的都是SQLite数据库
3是版本号,是SQLite的第三个版本。
Core Data是对SQLite的封装,因为iOS中使用的SQLite是纯C语言的。

  1. SQLite优点

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

二. 使用Navicat创建表

Navicat是一款著名的数据库管理软件,支持大部分主流数据库(包括SQLite), 在学习sql语句之前, 我们先使用Navicat来创建数据库和表

  1. 打开Navicat创建连接
    创建连接.png
  2. 填写连接名和数据库名
    信息.png

点击保存后桌面会出现一个1106.db文件

  1. 打开连接
    打开连接.png
  2. 打开数据库
    打开数据库.png
  3. 新建表
    新建表.png
  4. 添加字段并保存, 表名最好以t_开头, 表明这是个table表
    保存.png

三. SQL简介

如果要在程序运行过程中操作数据库中的数据,那得先学会使用SQL语句

  1. 什么是SQL

SQL(structured query language):结构化查询语言
SQL是一种对关系型数据库中的数据进行定义和操作的语言
SQL语言简洁,语法简单,好学好用

  1. 什么是SQL语句

使用SQL语言编写出来的句子\代码,就是SQL语句
在程序运行过程中,要想操作(增删改查,CRUD)数据库中的数据,必须使用SQL语句

  1. SQL语句的特点

不区分大小写(比如数据库认为user和UsEr是一样的)
每条语句都必须以分号 ; 结尾

  1. SQL中的常用关键字有

select、insert、update、delete、from、create、where、desc、order、by、group、table、alter、view、index等等
数据库中不可以使用关键字来命名表、字段

  1. SQL语句的分类

① 数据定义语句(DDL:Data Definition Language)
包括create和drop等操作
在数据库中创建新表或删除表(create table或 drop table)

② 数据操作语句(DML:Data Manipulation Language)
包括insert、update、delete等操作
上面的3种操作分别用于添加、修改、删除表中的数据

③ 数据查询语句(DQL:Data Query Language)
可以用于查询获得表中的数据
关键字select是DQL(也是所有SQL)用得最多的操作
其他DQL常用的关键字有where,order by,group by和having

四. SQL的基本操作

1. 创建表

在上面我们手动创建了表,现在我们使用sql语句再创建一个表

create table 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;
create table if not exists 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;

示例:

create table t_student (id integer, name text, age integer, score real) ;

字段类型:
SQLite将数据划分为以下几种存储类型:
integer : 整型值
real : 浮点值
text : 文本字符串
blob : 二进制数据(比如文件,或者是字典archived后的data)

注意:实际上SQLite是无类型的,就算声明为integer类型,还是能存储字符串文本(主键除外)

建表时声明啥类型或者不声明类型都可以,也就意味着创表语句可以这么写:

create table t_student(name, age);

提示:为了保持良好的编程规范、方便程序员之间的交流,编写建表语句的时候最好加上每个字段的具体类型

在Navicat中实际操作:

  1. 点击查询 -> 新建查询
  2. 输入如下sql语句:
    create table t_student2 (id integer, name text, age integer, score real) ;

结果如下:
表.png

2. 删除表

格式:

drop table 表名 ;
drop table if exists 表名 ;

示例:
drop table t_student ;

运行后刷新, 结果如下:
删除表.png

3. 给表添加字段 alter

alter table t_student add column grade char default '1';

上面的语句是给表添加一个年级字段, 并且设置默认值1

4. 插入数据(insert)

格式:

insert into 表名 (字段1, 字段2, …) values (字段1的值, 字段2的值, …) ;

示例:
insert into t_student (name, age) values ('xu', 10) ;

注意: 数据库中的字符串内容应该用引号 ' ' 括住

结果:
结果.png

5. 更新数据(update)

格式

update 表名 set 字段1 = 字段1的值, 字段2 = 字段2的值, … ;

示例:
update t_student set name = 'jack', age = 20 ;

注意:
上面的示例会将t_student表中所有记录的name都改为jack,age都改为20, 如果想更新某一个,可以在最后加条件 where id = '5'

刷新表后, 结果如下:
结果.png

如果数据的值不确定,则使用问好代替:

[db executeUpdate: @"UPDATE info_change_userinfo SET storage_time = ? ,user_id = ? ,head_icon_url = ? WHERE bank_id = ?",time,user_id,head_icon_url,bank_Id];

6. 删除数据(delete)

格式:

delete from 表名 ;
delete from t_student where id = '3'

示例:
delete from t_student ;

注意: 上面的示例会将t_student表中所有记录都删掉

7. 条件语句

如果只想更新或者删除某些固定的记录,那就必须在DML语句后加上一些条件

条件语句的常见格式:
where 字段 = 某个值 ; // 不能用两个 =
where 字段 is 某个值 ; // is 相当于 =
where 字段 != 某个值 ;
where 字段 is not 某个值 ; // is not 相当于 !=
where 字段 > 某个值 ;
where 字段1 = 某个值 and 字段2 > 某个值 ; // and相当于C语言中的 &&
where 字段1 = 某个值 or 字段2 = 某个值 ; // or 相当于C语言中的 ||

示例:
将t_student表中年龄大于10并且姓名不等于jack的记录,年龄都改为 5

update t_student set age = 5 where age > 10 and name != 'jack' ;

结果:
结果.png

删除t_student表中年龄小于等于10或者年龄大于30的记录

delete from t_student where age <= 10 or age > 30 ;

猜猜下面语句的作用:
update t_student set score = age where name = 'jack' ;
将t_student表中名字等于jack的记录,score字段的值 都改为 age字段的值

8. 查询语句 (DQL)

格式

select 字段1, 字段2, … from 表名 ;
select * from 表名; // 查询所有的字段

示例:
select name, age from t_student ;
select * from t_student ;
select * from t_student where age > 10 ; // 条件查询

查询结果:
查询

9. 起别名

格式(字段和表都可以起别名)

select 字段1 别名 , 字段2 别名 , … from 表名 别名 ;
select 字段1 别名, 字段2 as 别名, … from 表名 as 别名 ;
select 别名.字段1, 别名.字段2, … from 表名 别名 ;

示例:
select name myname, age myage from t_student ;
给name起个叫做myname的别名,给age起个叫做myage的别名

结果:
结果.png

select s.name, s.age from t_student s ;
给t_student表起个别名叫做s,利用s来引用表中的字段

10. 计算记录的数量

格式

select count (字段) from 表名 ;
select count ( * ) from 表名 ;

示例
select count (age) from t_student ; //有age的记录有多少个
select count ( * ) from t_student where score >= 60; //分数大于等于60有多少个

11. 排序

查询出来的结果可以用order by进行排序

select * from t_student order by 字段 ;

默认是按照升序排序(由小到大),也可以变为降序(由大到小)
select * from t_student order by age desc ; //降序
select * from t_student order by age asc ; // 升序(默认)

也可以用多个字段进行排序
select * from t_student order by age asc, height desc ;
先按照年龄排序(升序),年龄相等就按照身高排序(降序)

12. 控制查询数量 limit

使用limit可以精确地控制查询结果的数量,比如每次只查询10条数据

格式

select * from 表名 limit 数值1, 数值2 ;

示例
select * from t_student limit 4, 8 ;
可以理解为:跳过最前面4条语句,然后取8条记录

limit常用来做分页查询,比如每页固定显示5条数据,那么应该这样取数据:
第1页:limit 0, 5
第2页:limit 5, 5
第3页:limit 10, 5

第n页:limit 5*(n-1), 5

select * from t_student limit 7 ; 这条语句的作用相当于select * from t_student limit 0, 7 ; 表示取最前面的7条记录

13. 模糊匹配

select *from t_student where name like '%xy%'; // 匹配符 %

查找name中有xy的

五. 约束

1. 简单约束

建表时可以给特定的字段设置一些约束条件,常见的约束有

not null :规定字段的值不能为null
unique :规定字段的值必须唯一
default :指定字段的默认值

(建议:尽量给字段设定严格的约束,以保证数据的规范性)

示例:

create table t_student (id integer, name text not null unique, age integer not null default 1) ;

name字段不能为null,并且唯一
age字段不能为null,并且默认为1

2. 主键约束

① 简单说明
如果t_student表中就name和age两个字段,而且有些记录的name和age字段的值都一样时,那么就没法区分这些数据,造成数据库的记录不唯一,这样就不方便管理数据

良好的数据库编程规范应该要保证每条记录的唯一性,为此,增加了主键约束, 也就是说,每张表都必须有一个主键,用来标识记录的唯一性

② 什么是主键
主键(Primary Key,简称PK)用来唯一地标识某一条记录
例如t_student可以增加一个id字段作为主键,相当于人的身份证
主键可以是一个字段或多个字段

为什么主键可以是多个字段?因为主键的目的是唯一地标识某一条记录,如果一个字段会有可能重复,那就用两个字段呗,如下:

//建立消息列表
NSString *sql5 = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS message_records(messageID TEXT NOT NULL,accountNO TEXT NOT NULL,messageInfo TEXT NOT NULL,timestamp Double,PRIMARY KEY(messageID,accountNO))"];

这里是创建消息列表,同一条id的消息也可能是不同用户的,所以我们使用消息的id和账户的id共同作为主键,来唯一地标识一条消息。

③ 主键的设计原则
主键应当是对用户没有意义的
永远也不要更新主键
主键不应包含动态变化的数据
主键应当由计算机自动生成

④ 主键的声明
在创表的时候用primary key声明一个主键

create table t_student (id integer primary key, name text, age integer) ;

integer类型的id作为t_student表的主键

关于主键字段
只要声明为primary key,就说明是一个主键字段
主键字段默认就包含了not null 和 unique 两个约束

说明:如果想要让主键自动增长(必须是integer类型),应该增加autoincrement

create table t_student (id integer primary key autoincrement, name text, age integer) ;

3. 外键约束

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

新建一个外键

create table t_student (id integer primary key autoincrement, name text, age integer, class_id integer, constraint fk_student_class foreign key (class_id) references t_class (id));

t_student表中有一个叫做fk_t_student_class_id_t_class_id的外键
这个外键的作用是用t_student表中的class_id字段引用t_class表的id字段

4. 表连接查询

表连接查询:需要联合多张表才能查到想要的数据

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

示例 : 查询0316iOS班的所有学生

select s.name,s.age from t_student s, t_class c where s.class_id = c.id and c.name = ‘0316iOS’;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270