数据库基本概念
1. 数据(Data)
能够输入计算机并能被计算机程序识别和处理的信息集合。
2. 数据库 (Database)
数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合。
注:数据库管理系统(DataBase Management System)------DBMS
数据库管理系统( DBMS )
DBMS是数据库系统中对数据进行统一管理和控制的软件系统。
(1) 数据库定义功能。(Data Definition)
(2) 数据库操纵功能。 (Data Manipulation)
(3) 数据库运行控制功能。 (Data Control)
(4) 数据通信功能。 (Data Communication)
(5) 支持存取海量数据。 (Mass Data)
文件管理阶段:
优点:
(ⅰ)数据可长期保存
(ⅱ)能存储大量数据
缺点:
(ⅰ)数据冗余度(redundancy)大,
数据一致性(consistency)、
完整性(integrity)难以维持。
(ⅱ)数据与程序缺乏高度独立性。
数据库系统阶段
(ⅰ)数据组织结构化。
(ⅱ)数据冗余度比较小,易扩充。
(ⅲ)具有较高的数据与程序之间的独立性。
(ⅳ)统一的数据控制。
常用的数据库
大型数据库
Oracle公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作系统平台。目前Oracle关系数据库产品的市场占有率名列前茅。
IBM 的DB2是第一个具备网上功能的多媒体关系数据库管理系统, 支持包括Linux在内的一系列平台。
中型数据库
Server是微软开发的数据库产品,主要支持windows平台
小型数据库
mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,2008年被Sun公司收购。开放源码
基于嵌入式linux的数据库
基于嵌入式linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB。
Firebird是关系型数据库,功能强大,支持存储过程、SQL兼容等。
SQLite关系型数据库,体积小,支持ACID事务。
Berkeley DB中并没有数据库服务器的概念,它的程序库直接链接到应用程序中。
eXtremeDB是内存数据库,运行效率高。
SQLite3
SQLite的源代码是C,其源代码完全开放。SQLite第一个Alpha版本诞生于2000年5月。 他是一个轻量级的嵌入式数据库。
SQLite有以下特性:
零配置一无需安装和管理配置;
储存在单一磁盘文件中的一个完整的数据库;
数据库文件可以在不同字节顺序的机器间自由共享;
支持数据库大小至2TB;
足够小,全部源码大致3万行c代码,250KB;
比目前流行的大多数数据库对数据的操作要快;
使用注意事项
需要在线下载或者安装离线包
在编译时需要链接相应的库 -lsqlite3
SQLite数据库采用了模块化设计,由8个独立的模块构成,这些独立模块又构成了三个主要的子系统,模块将复杂的查询过程分解为细小的工作进行处理:
安装方式
在线安装:
sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev
离线安装:
1> 先把安装包移动到家目录中
sqlite-autoconf-3240000.tar.gz
2> 执行解压命令
sudo tar -xvf sqlite-autoconf-3240000.tar.gz
3> 切换到解压出来的目录
cd sqlite-autoconf-3240000/
4> 执行以下命令:环境配置的可执行文件,完善当前环境配置的修改
sudo ./configure
5> 执行以下命令
sudo make
6> 执行以下命令
sudo make install
7> 测试是否正常安装
farsight@Ubuntu18:~/sqlite-autoconf-3240000$ cd ~
farsight@Ubuntu18:~$ ls
Downloads shared test.c
a.out mnt sqlite-autoconf-3240000 Videos
app Music sqlite-autoconf-3240000.tar.gz
Desktop Pictures Templates
Documents Public test
farsight@Ubuntu18:~$ sqlite3 info.db
SQLite version 3.24.0 2018-06-04 19:24:41
Enter ".help" for usage hints.
sqlite> .quit
/**
退出方式:
1> 三次CTRL+C
2> .quit加回车键
**/
备注:info.db
实际上就是一张表:
SQLite数据库的使用方式
1. sqlite3命令
.databases 列出数据库文件名
.tables ?PATTERN? 列出?PATTERN?匹配的表名
.import FILE TABLE 将文件中的数据导入的文件中
.dump ?TABLE? 生成形成数据库表的SQL脚本
.output FILENAME 将输出导入到指定的文件中
.output stdout 将输出打印到屏幕
.mode MODE ?TABLE? 设置数据输出模式(csv,html,tcl…
.nullvalue STRING 用指定的串代替输出的NULL串
.read FILENAME 执行指定文件中的SQL语句
.schema ?TABLE? 打印创建数据库表的SQL语句
.separator STRING 用指定的字符串代替字段分隔符
.show 打印所有SQLite环境变量的设置
.quit 退出命令行接口
.head on 打印数据时,展示出表头
.head off 打印数据时,不展示出表头
2. sqlite3语句
(…> 表示输入的内容还未结束,需补上;)
手工创建
使用sqlite3工具,通过手工输入SQL命令行完成数据库创建.
用户在Linux的命令行界面中输入sqlite3可启动sqlite3工具
代码创建
在代码中常动态创建数据库
在程序运行过程中,当需要进行数据库操作时,应用程序会首先尝试打开数据库,此时如果数据库并不存在,程序则会自动建立数据库,然后再打开数据库
在终端下运行sqlite3 <*.db>,出现如下提示符:
SQLite version 3.7.2
Enter “.help” for instructions
Enter SQL statements terminated with a “;”
sqlite>
#<*.db> 是要打开的数据库文件。若该文件不存在,则自动创建。
2.1> 针对于表
2.1.1创建
//a.普通创建
原型:create table 表名 (列名 列名类型,列名 列名类型,......);//与C语言定义相反
例子:create table info (ID int,name char[20],pwd char[20]);
//b.避免重复创建
原型:create table if not exists 表名 (列名 列名类型,列名 列名类型,......);
例子:create table if not exists info (IIDD int,name char[20],pwd char[20]);
2.1.2删除
原型:drop table 表名 ;
例子:drop table info;
2.1.3修改(只能增加项,不能减少)
原型:alter table 表名 add column 列名 列名类型;
例子:alter table info add column salary char[20];
alter table 原表名 rename to 新表名;
alter table test rename to info;
2.1.4查看表
.table 查看所有表
.table 表名 查看指定的表
.schema 表名 查看表的格式
2.1.5在表中删除字段
Sqlite中不允许删除字段,可以通过下面步骤达到同样的效果
sqlite> create table stu as select no, name, score from student
sqlite> drop table student
sqlite> alter table stu rename to student
/**增删改查**/
2.2> 针对于数据
2.2.1增加数据
原型:insert into 表名 values (value1, value2,…);//每一列的数值用逗号隔开
例子:insert into info values (1, "Tomas","123456","$500000");
insert into info values (2, "Alen","666666","$60000");
2.2.2查询数据
//控制查看数据的表头显示与否
.header on
//a.查看该表中所有数据
原型:select * from 表名;
例子:select * from info;
//b.查看该表中符合条件的数据
原型:select * from 表名 where 条件;(多条件之间用and(与)或者or(或)连接)
例子:select * from info where ID == 1;//单条件
select * from info where ID == 1 or pwd == "666666";//多条件
select * from info where ID == 1 and pwd == "888888";//多条件
2.2.3删除数据
原型:delete from 表名 where 条件;
例子:delete from info where pwd == "888888";
2.2.4修改数据
原型:update 表名 set 列名 = 数值,列名 = 数值 ...... where 条件;
例子:update info set name = "laoguo",pwd = "9999" where ID == 2;
3.SQLite3的API函数
(
程序中需要包含相应的头文件 #include <sqlite3.h>
编译时需要链接相应的库 -lsqlite3
)
3.1>打开数据库
int sqlite3_open(char *path,sqlite3 **db);
/**********************************************************************
@brief: 打开sqlite数据库
@path: 数据库文件路径(如果文件不存在则创建,文件存在则打开。)
@db: 指向sqlite句柄的指针
@retval: 成功:返回SQLITE_OK(0)
失败:返回错误码(非零值)
**********************************************************************/
3.2>执行SQLite3语句
int sqlite3_exec(sqlite3 *db, const char *sql, sqlite3_callback callback, void * arg, char **errmsg);
/**********************************************************************
@brief: 执行SQL操作
@db: 数据库句柄
@sql: SQL语句
@callback: 回调函数的函数指针
@arg: 给回调函数传的参数
@errmsg: 错误信息指针的地址
@retval: 成功:返回SQLITE_OK(0)
失败:返回错误码(非零值)
**********************************************************************/
typedef int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);
/**********************************************************************
@brief: 如果使用select语句查表的数据,会调用到该回调函数
@para: 给回调函数传过来的参数
@f_num: 回调函数中查询的表中的列的数量
@f_value: 表中的具体的数据
@f_name: 表中的具体的表头(列名)
@retval: 成功:返回SQLITE_OK(0)
失败:返回错误码(非零值)
/**
使用回调函数时,要在最后加上return 0; ,否则回调函数只会调用一次
**/
/**********************************************************************/
例如:int LoadMyInfo(void * para, int n_column, char ** column_value, char ** column_name)
para是在 sqlite3_exec 里传入的 void * 参数,通过para参数,可以传入带有控制功能的数据
n_column是这一条记录有多少个字段 (即这条记录有多少列)
char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组,每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以\0结尾)
char ** column_name 跟 column_value是对应的,表示这个字段的字段名称
说明:回调函数必须定义为上面这个函数的类型。
3.3>关闭数据库
int sqlite3_close(sqlite3 *db);
/**********************************************************************
@brief: 关闭sqlite数据库
@db: 数据库句柄
@retval: 成功:返回SQLITE_OK(0)
失败:返回错误码(非零值)
**********************************************************************/
3.4>获得错误信息
const char *sqlite3_errmg(sqlite3 *db);
/**********************************************************************
@brief: 关闭sqlite数据库
@db: 数据库句柄
@retval: 返回错误信息
**********************************************************************/
完整操作sqlite3数据表的代码
#include <sqlite3.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int i;
int CheckMsg(void *para,int n_column,char **column_value,char **column_name)
{
//printf("para:%s\n",(char *)para);
static int flag = 0;//利用static在修饰局部变量时只会初始化一次的特点,控制打印表头的次数为1次
if(!flag)
{
for(i = 0;i < n_column;i++)
printf("%s|",column_name[i]);//column_name[0] = ID,column_name[1] = name,column_name[2] = pwd;
printf("\n");
flag = 1;
}
for(i = 0;i < n_column;i++)
printf("%s|",column_value[i]);
printf("\n");
return 0;
}
int main(void)
{
sqlite3 *db;//制作句柄用于后续操作
char *errmsg;
//打开数据库文件
int ret = sqlite3_open("info.db", &db);
if(ret != SQLITE_OK)
{
perror("sqlite3 open");
exit(1);
}
//执行sql语句,创建一张表
char sql[256] = "create table if not exists info (ID int,name char[20],pwd char[20]);";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3 exec");
printf("errmsg:%s\n",errmsg);
exit(1);
}
//执行sql语句,将数据写入到表中
bzero(sql,sizeof(sql));
strcpy(sql,"insert into info values (1, \"Tomas\",\"123456\");");
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3 exec");
printf("errmsg:%s\n",errmsg);
exit(1);
}
bzero(sql,sizeof(sql));
strcpy(sql,"insert into info values (2, 'Alen', '666666');");
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3 exec");
printf("errmsg:%s\n",errmsg);
exit(1);
}
//查询数据,需要用到回调函数
bzero(sql,sizeof(sql));
strcpy(sql,"select * from info;");
ret = sqlite3_exec(db, sql, CheckMsg, "数据库查询,启动!", &errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3 exec");
printf("errmsg:%s\n",errmsg);
exit(1);
}
//关闭数据库
if(sqlite3_close(db) != SQLITE_OK)
{
fprintf(stderr,"error : %s\n", sqlite3_errmsg(db));
fprintf(stderr,"error : %s\n", errmsg);
exit(-1);
}
return 0;
}
综上。希望该内容能对你有帮助,感谢!
以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。
我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!