数据库的概念
数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。
数据库是存放数据的仓库。它的存储空间很大,可以存放百万条、千万条、上亿条数据。但是数据库并不是随意地将数据进行存放,是有一定的规则的,否则查询的效率会很低。当今世界是一个充满着数据的互联网世界,充斥着大量的数据。即这个互联网世界就是数据世界。数据的来源有很多,比如出行记录、消费记录、浏览的网页、发送的消息等等。
数据库分类
常见的关系型数据库有: MySQL、SQL Server、Oracle、SQLite。
小型数据库: MySQL:免费产品,内存存储引擎使用较少。
中型数据库: SQL Server:微软的商业化产品,是为了适应大数据等业务产品新添加的存储引擎,微软SQL语句兼容性好,商业化成熟度高。
大型数据库: Oracle :基于内存计算的关系数据库, 提供了响应时间极短且吞吐量极高的应用程序。
轻型数据库: SQLite:专为嵌入式设计的一款轻型的数据库,是遵守ACID的关系型数据库管理系统。
不管哪一个数据库,它的核心都是SQL语句:SQL (Structured Query Language:结构化查询语言) 是用于管理关系数据库管理系统(RDBMS)。 SQL 的范围包括数据插入、查询、更新和删除,数据库模式创建和修改,以及数据访问控制。所以,学习的重点应该放到如何利用SQL语句进行操作数据库。
SQLite的源代码是C,其源代码完全开放。它是一个轻量级的嵌入式数据库。
SQLite有以下特性:零配置一无需安装和管理配置; 储存在单一磁盘文件中的一个完整的数据库; 数据库文件可以在不同字节顺序的机器间自由共享; 支持数据库大小至2TB(1024G = 1TB);足够小,全部源码大致3万行c代码,250KB; 比目前流行的大多数数据库对数据的操作要快;
数据库和表
数据库是个文件,而表其实就是文件里存储数据的容器。可以把数据库理解为excel文件,而表就是excel中一张张数据表,一个数据库可以有多张数据库表。

数据库操作
创建数据库
数据库本质就是一个文件,通常以db作为后缀名。使用sqlite3 命令来创建,可以在打开sqlite命令提示符之前就创建,命令如下:
$ sqlite3 student.db
也可以打开后使用.open 命令来创建。
sqlite>.open student.db
以上两种方式,如果student.db 存在则直接会打开,不存在就创建它。
sqlite3数据库系统命令:
以 '.' 开头,常用的有:
.help 查看所有支持的命令
.quit 退出
.tables 查看有哪些表
.schema stu2 查看表结构
SQL语句
不管哪一个数据库,它的核心都是SQL语句,SQL语句可以理解为数据库标准,不管哪种数据库都要支持。
sqlite中SQL语句不需要以.开头,正常输入的内容都会被当成SQL语句解析。
SQL语句的关键字不区分大小写,但是通常约定俗成会以大写来书写关键字。
SQL语句在sqlite命令终端以分号结尾,如果未键入;敲回车,终端会继续等待键入。
举例:对学生成绩库进行增删改查
1》创建一个表
create table stu(id int,name char,score float);
create table stu1(id int primary key, name char, score float);
注:把id字段设置为主键(在表中唯一);只能存在一个id为某值的数
2》 删除一个表
drop table <table_name>;
table_name 要删除的表的名字
可以使用 .table 查看库中都有什么表 .schema stu2 table_name 查看表结构
3》 向表里面插入数据
//插入标准类型字段
insert into <table_name> values(value1, value2,…);
eg: insert into stu values(1,"张三",99.9);
//只插入部分字段 id name score
insert into stu(id,name) values(4,“xiaoming”)
4》 查找数据
查询表中所有记录:
select * from <table_name>;
(*表示查询所有的值)
按指定条件查询表中记录:
select * from <table_name> where <expression>;
举例: select * from stu where id=2;
//从表stu中查找id=2的所有数据
select * from stu where id=2 and name='lisi';
//从表stu中查找id=2且name=lisi的数据
select * from stu where id=1 or name='zhangsan';
//从表stu中查找id=1且name是zhangsan的数据
select score from stu where name='LiSi' or id=3;
//满足条件的某列
select name,score from stu where name='LiSi' or id=3;
//满足条件的某两列
select * from stu limit 5;
//只查询前n条记录
select * from stu order by id desc;
//按id从大到小进行排序
5》 修改(更新)数据
update <table_name> set <f1=value1>, <f2=value2>… where <expression>;
//将某个表中的expression数据修改为value1数据
update stu set id=10 where id=1;
//将id=1改为id=10;
6》 增加字段
alter table <table> add column <field> <type> default …;
alter table stu add column class int default 1;
//(表示添加了一列class,默认值为1)
7》 删除字段
(在数据库当中其实不支持直接删除一个字段(及一列),如果就想删除一列,那么需要三步骤)
1)create table student as select id,name,score from stu;
创建一个student表,从stu表当中复制id,name,score
2) drop table stu;
删除原有的stu表
3) alter table student rename to stu;
重命名
最后一列为1的被删除掉了。
8》删除一行
delete from stu where value
sqlite编程
头文件:#include <sqlite3.h>
编译:gcc sqlite1.c -lsqlite3
函数
1.sqlite_open 打开数据库函数
int sqlite3_open(char *path, sqlite3 **db);
功能:打开sqlite数据库,如果数据库不存在则创建它
path: 数据库文件路径
db: 指向sqlite数据库句柄的指针
返回值:成功返回SQLITE_OK,失败返回错误码(非零值)
// 1、创建或打开数据库sqlite3 *db; //db是 指向数据库句柄的指针// 失败返回非0值if (sqlite3_open("./student.db", &db) != 0){fprintf(stderr,"err:%s\n",sqlite3_errmsg(db));return -1;}printf("数据库创建成功!\n");
2.int sqlite3_close 关闭数据库函数
int sqlite3_close(sqlite3 *db);
功能:关闭sqlite数据库
返回值:成功返回SQLITE_OK,失败返回错误码返回错误信息
//关闭数据库sqlite3_close(db);return 0;
3.int sqlite3_exec 执行sql语句接口函数
int sqlite3_exec(sqlite3 *db, /* An open database */const char *sql, /* SQL to be evaluated */int (*callback)(void*,int,char**,char**), /* Callback function */void *arg, /* 1st argument to callback */char **errmsg /* Error msg written here */
);功能:执行SQL操作
参数:db:数据库句柄sql:要执行SQL语句callback:回调函数(满足一次条件,调用一次函数,用于查询)再调用查询sql语句的时候使用回调函数打印查询到的数据arg:传递给回调函数的参数errmsg:错误信息指针的地址
返回值:成功返回SQLITE_OK,失败返回错误码回调函数:
typedef int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);功能:select:每找到一条记录自动执行一次回调函数para:传递给回调函数的参数(由 sqlite3_exec() 的第四个参数传递而来)f_num:记录中包含的字段数目f_value:包含每个字段值的指针数组(列值)f_name:包含每个字段名称的指针数组(列名)
返回值:成功返回SQLITE_OK,失败返回-1,每次回调必须返回0后才能继续下次回调
//2.创建表if(sqlite3_exec(db,"create table stu(id int primary key,\name char,score float);",NULL,NULL,&errmsg)!= SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}//3.插入数据 stu 3 int n;//插入学生个数int id;char name[32];float score;char sql[128];printf("please input number:");scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d %s %f",&id,name,&score);sprintf(sql,"insert into stu values(%d,\"%s\",%f);",id,name,score);printf("sql:%s\n",sql);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!= SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}}//4.查询插入的数据if(sqlite3_exec(db,"select * from stu;",callback,"hello",&errmsg)!= SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}//callback回调函数int callback(void *arg,int f_num,char **f_value,char **f_name){printf("arg:%s\n",(char *)arg);for(int i=0;i<f_num;i++){printf("%s ",f_name[i]);}putchar(10);for(int i=0;i<f_num;i++){printf("%s ",f_value[i]);} putchar(10);return 0;}
4. sqlite3_get_table 不使用回调函数执行SQL语句(只用于查询)
int sqlite3_get_table(sqlite3 *db, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg);功能:执行SQL操作
db:数据库句柄
sql:SQL语句
resultp:用来指向sql执行结果的指针
nrow:满足条件的记录的数目(但是不包含字段名(表头 id name score))
ncolumn:每条记录包含的字段数目
errmsg:错误信息指针的地址返回值:成功返回SQLITE_OK,失败返回错误码
//sqlite3_get_table 专门用于查询 selectchar **sp=NULL;int nrow,lie;if(sqlite3_get_table(db,"select * from stu;",\&sp,&nrow,&lie,&errmsg) != SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}//打印查询到的信息int i,j,k=0;for(i=0;i<nrow+1;i++){for(j=0;j<lie;j++){printf("%s ",sp[k++]);}putchar(10);}
5.sqlite3_errmsg 返回sqlite3定义的错误信息
char *sqlite3_errmsg(sqlite3 *db);
char *errmsg=NULL;
if( )//容错判断
{fprintf(stderr,"err:%s\n",errmsg);return -1;
}
完整代码
#include <stdio.h>
#include <sqlite3.h>int callback(void *arg,int f_num,char **f_value,char **f_name)
{printf("arg:%s\n",(char *)arg);for(int i=0;i<f_num;i++){printf("%s ",f_name[i]);}putchar(10);for(int i=0;i<f_num;i++){printf("%s ",f_value[i]);}putchar(10);return 0;
}int main(int argc,const char *argv[])
{//1.创建或打开数据库sqlite3 *db;if(sqlite3_open("./student.db",&db) != SQLITE_OK){fprintf(stderr,"err:%s\n",sqlite3_errmsg(db));return -1;}printf("sqlite3_open ok.\n");char *errmsg=NULL;
#if 0//2.创建表if(sqlite3_exec(db,"create table stu(id int primary key,\name char,score float);",NULL,NULL,&errmsg)!= SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}//3.插入数据 stu 3 int n;//插入学生个数int id;char name[32];float score;char sql[128];printf("please input number:");scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d %s %f",&id,name,&score);sprintf(sql,"insert into stu values(%d,\"%s\",%f);",id,name,score);printf("sql:%s\n",sql);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!= SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}}//4.查询插入的数据if(sqlite3_exec(db,"select * from stu;",callback,"hello",&errmsg)!= SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}
#endif //sqlite3_get_table 专门用于查询 selectchar **sp=NULL;int nrow,lie;if(sqlite3_get_table(db,"select * from stu;",\&sp,&nrow,&lie,&errmsg) != SQLITE_OK){fprintf(stderr,"err:%s\n",errmsg);return -1;}int i,j,k=0;for(i=0;i<nrow+1;i++){for(j=0;j<lie;j++){printf("%s ",sp[k++]);}putchar(10);}sqlite3_close(db);return 0;
}
编译:
gcc sqlite.c -o sqlite -lsqlite3
