目录
一、数据库
数据库的基本概念
![](https://i-blog.csdnimg.cn/blog_migrate/ac9186636df8a0f5083347d0620bb0d2.png)
常用的数据库
大型数据库
Oracle公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作系统平台。目前Oracle关系数据库产品的市场占有率名列前茅。
IBM 的DB2是第一个具备网上功能的多媒体关系数据库管理系统,支持包Linux在内的一系列平台。
中型数据库
Server是微软开发的数据库产品,主要支持windows平台。
小型数据库
mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,2008年被Sun公司收购,开放源码。现在Sun又被Oracle收购了
数据库种类大全及区别_seniorShen的博客-CSDN博客_数据库分类
我接触过的第一款就是免费开源的MySQL,在JavaWeb开发中常用
后面学习大数据接触到了第一个NoSQL它叫Hbase ,这些非关系型数据库常用于大数据处理中。
基于嵌入式的数据库
基于嵌入式Linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB
Firebird是关系型数据库,功能强大,支持存储过程、SQL兼容等
SQLite关系型数据库,体积小,支持ACID事务
Berkeley DB中并没有数据库服务器的概念,它的程序库直接链接到应用程序中
eXtremeDB是内存数据库,运行效率高
二、SQLite
SQLite基础
SQLite的源代码是C,其源代码完全开放。SQLite第一个Alpha版本诞生于2000年5月。 他是一个轻量级的嵌入式数据库。
SQLite有以下特性:
零配置一无需安装和管理配置;
储存在单一磁盘文件中的一个完整的数据库;
数据库文件可以在不同字节顺序的机器间自由共享;
支持数据库大小至2TB;
足够小,全部源码大致3万行c代码,250KB;
比目前流行的大多数数据库对数据的操作要快;
SQLite安装
准备好安装包
这时候dpkg的弊端就出现了,老师给的安装包太老了,相关依赖都木有,所以还是apt安装吧
先更新下软件包sudo apt update
报错了
先执行
sudo pkill -KILL appstreamcli
在执行
wget -P /tmp https://launchpad.net/ubuntu/+archive/primary/+files/appstream_0.9.4-1ubuntu1_amd64.deb https://launchpad.net/ubuntu/+archive/primary/+files/libappstream3_0.9.4-1ubuntu1_amd64.deb
最后执行
sudo dpkg -i /tmp/appstream_0.9.4-1ubuntu1_amd64.deb /tmp/libappstream3_0.9.4-1ubuntu1_amd64.deb
运行完了再来更新
我真是yue了,算了先不管它
直接 sudo apt install sqlite3
吐了呀
按照这个解决一下第一步 sudo apt --fix-broken install
太好了没报错
我在更新
爱了爱了
成功好像在招手
查看版本
安装可视化工具
sudo apt-get install sqlitebrowser
sqlitebrowser 数据库名查看数据库
数据库命令:
1)系统命令 , 都以'.'开头
.help 帮助
.exit 退出
.quit 退出sql命令行
.table 查看表
.schema 查看表的结构
英文文档
.archive ... Manage SQL archives: ".archive --help" for details
.auth ON|OFF Show authorizer callbacks
.backup ?DB? FILE Backup DB (default "main") to FILE
.bail on|off Stop after hitting an error. Default OFF
.binary on|off Turn binary output on or off. Default OFF
.cd DIRECTORY Change the working directory to DIRECTORY
.changes on|off Show number of rows changed by SQL
.check GLOB Fail if output since .testcase does not match
.clone NEWDB Clone data into NEWDB from the existing database
.databases List names and files of attached databases
.dbinfo ?DB? Show status information about the database
.dump ?TABLE? ... Dump the database in an SQL text format
If TABLE specified, only dump tables matching
LIKE pattern TABLE.
.echo on|off Turn command echo on or off
.eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN
.excel Display the output of next command in a spreadsheet
.exit Exit this program
.expert EXPERIMENTAL. Suggest indexes for specified queries
.fullschema ?--indent? Show schema and the content of sqlite_stat tables
.headers on|off Turn display of headers on or off
.help Show this message
.import FILE TABLE Import data from FILE into TABLE
.imposter INDEX TABLE Create imposter table TABLE on index INDEX
.indexes ?TABLE? Show names of all indexes
If TABLE specified, only show indexes for tables
matching LIKE pattern TABLE.
.limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT
.lint OPTIONS Report potential schema issues. Options:
fkey-indexes Find missing foreign key indexes
.load FILE ?ENTRY? Load an extension library
.log FILE|off Turn logging on or off. FILE can be stderr/stdout
.mode MODE ?TABLE? Set output mode where MODE is one of:
ascii Columns/rows delimited by 0x1F and 0x1E
csv Comma-separated values
column Left-aligned columns. (See .width)
html HTML <table> code
insert SQL insert statements for TABLE
line One value per line
list Values delimited by "|"
quote Escape answers as for SQL
tabs Tab-separated values
tcl TCL list elements
.nullvalue STRING Use STRING in place of NULL values
.once (-e|-x|FILE) Output for the next SQL command only to FILE
or invoke system text editor (-e) or spreadsheet (-x)
on the output.
.open ?OPTIONS? ?FILE? Close existing database and reopen FILE
The --new option starts with an empty file
.output ?FILE? Send output to FILE or stdout
.print STRING... Print literal STRING
.prompt MAIN CONTINUE Replace the standard prompts
.quit Exit this program
.read FILENAME Execute SQL in FILENAME
.restore ?DB? FILE Restore content of DB (default "main") from FILE
.save FILE Write in-memory database into FILE
.scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off
.schema ?PATTERN? Show the CREATE statements matching PATTERN
Add --indent for pretty-printing
.selftest ?--init? Run tests defined in the SELFTEST table
.separator COL ?ROW? Change the column separator and optionally the row
separator for both the output mode and .import
.session CMD ... Create or control sessions
.sha3sum ?OPTIONS...? Compute a SHA3 hash of database content
.shell CMD ARGS... Run CMD ARGS... in a system shell
.show Show the current values for various settings
.stats ?on|off? Show stats or turn stats on or off
.system CMD ARGS... Run CMD ARGS... in a system shell
.tables ?TABLE? List names of tables
If TABLE specified, only list tables matching
LIKE pattern TABLE.
.testcase NAME Begin redirecting output to 'testcase-out.txt'
.timeout MS Try opening locked tables for MS milliseconds
.timer on|off Turn SQL timer on or off
.trace FILE|off Output each SQL statement as it is run
.vfsinfo ?AUX? Information about the top-level VFS
.vfslist List all available VFSes
.vfsname ?AUX? Print the name of the VFS stack
.width NUM1 NUM2 ... Set column widths for "column" mode
Negative values right-justify
2)sql语句, 都以‘;’结尾
1-- 创建一张表
create table stuinfo(id integer, name text, age integer, score float);
2-- 插入一条记录
insert into stuinfo values(1001, 'zhangsan', 18, 80);
insert into stuinfo (id, name, score) values(1002, 'lisi', 90);
3-- 查看数据库记录
select * from stuinfo;
select * from stuinfo where score = 80;
select * from stuinfo where score = 80 and name= 'zhangsan';
select * from stuinfo where score = 80 or name='wangwu';
select name,score from stuinfo; 查询指定的字段
select * from stuinfo where score >= 85 and score < 90;
4-- 删除一条记录
delete from stuinfo where id=1003 and name='zhangsan';
插入的时候把wangyu插到得分里了,不对怎么删王五了重来
SQLite不会检查数据类型
5-- 更新一条记录
update stuinfo set age=20 where id=1003;
update stuinfo set age=30, score = 82 where id=1003;
6-- 删除一张表
drop table stuinfo;
7-- 增加一列
alter table stuinfo add column sex char;
8-- 删除一列(不支持直接删除,创建新表删除旧表将新表名改成旧表)
create table stu as select id, name, score from stuinfo;
drop table stuinfo;
alter table stu rename to stuinfo;
9、数据库设置主键和自增:
create table info(id integer primary key autoincrement, name vchar);
三、sqlite3 数据库 C语言 API
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
功能:打开数据库
参数:filename 数据库名称
ppdb 数据库句柄
返回值:成功为0 SQLITE_OK ,出错 错误码
int sqlite3_close(sqlite3* db);
功能:关闭数据库
参数:
返回值:成功为0 SQLITE_OK ,出错 错误码
const char *sqlite3_errmsg(sqlite3*db);
功能:得到错误信息的描述
int sqlite3_exec(
sqlite3* db, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void* arg,int,char**,char**), /* Callback function */
void * arg, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
功能:执行一条sql语句
参数:
db 数据库句柄
sql sql语句
callback 回调函数,只有在查询时,才传参
arg 为回调函数传递参数
errmsg 错误消息
返回值:成功 SQLITE_OK
查询回调函数:
int (*callback)(void* arg,int ncolumns ,char** f_value,char** f_name), /* Callback function */
功能:查询语句执行之后,会回调此函数
参数:arg 接收sqlite3_exec 传递来的参数
ncolumns 列数
f_value 列的值得地址
f_name 列的名称
返回值:0,
int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
int *pnRow, /* Number of result rows written here */
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
void sqlite3_free_table(char **result);
查询
四、基于数据库的学生管理系统
编译一下结果不认识sqlite3库
看了一下外国友人的解释我应该安一个这个
sudo apt-get install libsqlite3-dev
又出问题了主机和虚拟机间复制黏贴失效了
ubantu 与 主机 之间无法复制粘贴_51CTO博客_ubuntu与windows之间不能复制粘贴
sudo apt-get install open-vm-tools-desktop
好了,把代码粘过来
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#define DATABASE "student.db"
#define N 128
int do_insert(sqlite3 *db)
{
int id;
char name[32] = {};
char sex;
int score;
char sql[N] = {};
char *errmsg;
printf("Input id:");
scanf("%d", &id);
printf("Input name:");
scanf("%s", name);
getchar();
printf("Input sex:");
scanf("%c", &sex);
printf("Input score:");
scanf("%d", &score);
sprintf(sql, "insert into stu values(%d, '%s', '%c', %d)", id, name, sex, score);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("Insert done.\n");
}
return 0;
}
int do_delete(sqlite3 *db)
{
int id;
char sql[N] = {};
char *errmsg;
printf("Input id:");
scanf("%d", &id);
sprintf(sql, "delete from stu where id = %d", id);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("Delete done.\n");
}
return 0;
}
int do_update(sqlite3 *db)
{
int id;
char sql[N] = {};
char name[32] = "zhangsan";
char *errmsg;
printf("Input id:");
scanf("%d", &id);
sprintf(sql, "update stu set name='%s' where id=%d", name,id);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("update done.\n");
}
return 0;
}
int callback(void *arg, int f_num, char ** f_value, char ** f_name)
{
int i = 0;
for(i = 0; i < f_num; i++)
{
// printf("%-8s %s", f_value[i], f_name[i]);
printf("%-8s", f_value[i]);
}
printf("++++++++++++++++++++++");
putchar(10);
return 0;
}
int do_query(sqlite3 *db)
{
char *errmsg;
char sql[N] = "select count(*) from stu where name='zhangsan';";
if(sqlite3_exec(db, sql, callback,NULL , &errmsg) != SQLITE_OK)
{
printf("%s", errmsg);
}
else
{
printf("select done.\n");
}
}
int do_query1(sqlite3 *db)
{
char *errmsg;
char ** resultp;
int nrow;
int ncolumn;
if(sqlite3_get_table(db, "select * from stu", &resultp, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
return -1;
}
else
{
printf("query done.\n");
}
int i = 0;
int j = 0;
int index = ncolumn;
for(j = 0; j < ncolumn; j++)
{
printf("%-10s ", resultp[j]);
}
putchar(10);
for(i = 0; i < nrow; i++)
{
for(j = 0; j < ncolumn; j++)
{
printf("%-10s ", resultp[index++]);
}
putchar(10);
}
return 0;
}
int main(int argc, const char *argv[])
{
sqlite3 *db;
char *errmsg;//errmsg是一个二级指针,定义一个一级指针取地址。
int n;
if(sqlite3_open(DATABASE, &db) != SQLITE_OK)
{
printf("%s\n", sqlite3_errmsg(db));
return -1;
}
else
{
printf("open DATABASE success.\n");
}
if(sqlite3_exec(db, "create table if not exists stu(id int, name char , sex char , score int);",NULL, NULL, &errmsg) != SQLITE_OK)//分号可加可不加
{
printf("%s\n", errmsg);
}
else
{
printf("Create or open table success.\n");
}
while(1)
{
printf("********************************************\n");
printf("1: insert 2:query 3:delete 4:update 5:quit\n");
printf("********************************************\n");
printf("Please select:");
scanf("%d", &n);
switch(n)
{
case 1:
do_insert(db);
break;
case 2:
do_query(db);
// do_query1(db);
break;
case 3:
do_delete(db);
break;
case 4:
do_update(db);
break;
case 5:
printf("main exit.\n");
sqlite3_close(db);
exit(0);
break;
default :
printf("Invalid data n.\n");
}
}
return 0;
}
五、一个小作业
写了好久,代码不是很完善但是基本功能都实现了,并预留了接口等什么时候不忙了进行二次开发。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <time.h>
#define DATABASE "fruit.db"
#define N 128
int do_insert(sqlite3 *db)
{
int id;
char name[32] = {};
float price;
int number;
char sql[N] = {};
char *errmsg;
printf("Input id:");
scanf("%d", &id);
puts("");
printf("Input name:");
scanf("%s", name);
getchar();
puts("");
printf("Input price:");
scanf("%f", &price);
puts("");
printf("Input number:");
scanf("%d", &number);
puts("");
sprintf(sql, "insert into fruit values(%d, '%s', %f, %d)", id, name, price, number);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("stock done.\n");
}
return 0;
}
int do_delete(sqlite3 *db)
{
int id;
char sql[N] = {};
char *errmsg;
char a;
char name[32] = {};
printf("Are you sure you don`t want this fruit!(Y/N)\n");
scanf("%c",&a);
if (a == 'Y' || a == 'y'){
printf("Input fruit:");
scanf("%s", name);
getchar();
puts("");
sprintf(sql, "delete from fruit where name = '%s'", name);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("Delete done.\n");
}
}
return 0;
}
int do_update(sqlite3 *db)
{
int id;
char sql[N] = {};
char name[32] = {};
char *errmsg;
float price;
printf("Input fruit:");
scanf("%s", name);
getchar();
puts("");
printf("Input price");
scanf("%f", &price);
puts("");
sprintf(sql, "update fruit set price=%f where name = '%s'", price,name);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("update done.\n");
}
return 0;
}
int callback(void *arg, int f_num, char ** f_value, char ** f_name)
{
int i = 0;
for(i = 0; i < f_num; i++)
{
// printf("%-8s %s", f_value[i], f_name[i]);
printf("%-8s", f_value[i]);
}
printf("\n++++++++++++++++++++++++++++++++");
putchar(10);
return 0;
}
int do_query(sqlite3 *db)
{
printf("++++++++++++++++++++++++++++++++\n");
char *errmsg;
//char sql[N] = "select count(*) from fruit where name='zhangsan';";
char sql[N] = "select * from fruit;";
if(sqlite3_exec(db, sql, callback,NULL , &errmsg) != SQLITE_OK)
{
printf("%s", errmsg);
}
else
{
printf("select done.\n");
}
}
int do_query1(sqlite3 *db)
{
char *errmsg;
char ** resultp;
int nrow;
int ncolumn;
if(sqlite3_get_table(db, "select * from fruit", &resultp, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
return -1;
}
else
{
printf("query done.\n");
}
int i = 0;
int j = 0;
int index = ncolumn;
for(j = 0; j < ncolumn; j++)
{
printf("%-10s ", resultp[j]);
}
putchar(10);
for(i = 0; i < nrow; i++)
{
for(j = 0; j < ncolumn; j++)
{
printf("%-10s ", resultp[index++]);
}
putchar(10);
}
return 0;
}
#if 0 //FIXME//cuowu
static int callback1(void *data,int argc,char **argv,char **azColName)
{
int i;
fprintf(stderr,"%s:",(const char *)data);
for(i=0;i<argc;i++)
{
printf("%s = %s\n",azColName[i],argv[i] ? argv[i]:"NULL");
}
printf("\n");
return 0;
}
//查询主函数
int select_db(sqlite3 *db,char *tbname)
{
Stu s1 = {};
char sql[100] = {'\0'};
sprintf(sql,"select * from %s",tbname);
printf("%s\n",sql);
char *errmsg = NULL;
if(sqlite3_exec(db,sql,callback,NULL,&errmsg)!=SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
printf("select ok\n");
return 0;
}
#endif
int do_sell(sqlite3 *db)
{
int id;
char sql[N] = {};
char sql2[N] = {};
char name[32] = {};
char *errmsg;
float price;
int number;
time_t times;
struct tm* ge;
times = time(NULL);
char buf[32];
sprintf(buf,"%4d-%2d-%2d %2d:%2d:%2d",ge->tm_year+1900,ge->tm_mon+1,ge->tm_mday,ge->tm_hour,ge->tm_min,ge->tm_sec);
printf("Input fruit:");
scanf("%s", name);
getchar();
puts("");
printf("Input number");
scanf("%d", &number);
puts("");
sprintf(sql2, "insert into sell values(%d, '%s', %f, %d, '%s')", id, name, price, number, buf);
if(sqlite3_exec(db, sql2, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("stock done.\n");
}
#if 1
char *errmsg1;
char ** resultp;
int nrow;
int ncolumn;
char sql1[N] = {};
sprintf(sql,"select number from fruit where name = '%s';",name);
if(sqlite3_get_table(db, sql1, &resultp, &nrow, &ncolumn, &errmsg1) != SQLITE_OK)
{
printf("%s\n", errmsg1);
return -1;
}
else
{
number = (int)resultp - number;
printf("query done.\n");
}
#endif
sprintf(sql, "update fruit set number='%d' where name='%s'", number, name);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("sell done.\n");
}
return 0;
}
void help()
{
printf("1:stock,Input id,name,price,number\n");
printf("2:Inquire the price and allowance of all fruits\n");
printf("3:Delete fruit that is sold out and never comes in again\n");
//XXX
}
int do_stock_list(db)
{
//TODO
return 0;
}
int do_sell_list(db)
{
//TODO
return 0;
}
int main(int argc, const char *argv[])
{
sqlite3 *db;
char *errmsg;//errmsg是一个二级指针,定义一个一级指针取地址。
int n;
if(sqlite3_open(DATABASE, &db) != SQLITE_OK)//打开数据库
{
printf("%s\n", sqlite3_errmsg(db));
return -1;
}
else
{
printf("open DATABASE success.\n");
}
if(sqlite3_exec(db, "create table if not exists fruit(id int, name char , price float , number int);",NULL, NULL, &errmsg) != SQLITE_OK)//分号可加可不加 商品价格数量表
{
printf("%s\n", errmsg);
}
else
{
printf("Create or open table success.\n");
}
if(sqlite3_exec(db, "create table if not exists sell(id int, name char , price float ,number int, time char);",NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("%s\n", errmsg);
}
else
{
printf("Create or open table success.\n");
}
while(1)
{
printf("*******************************************************************************\n");
printf("1:stock 2:price 3:delete 4:update 5:quit 6:sell 7:stock_list 8:sell_list 9:help\n");
printf("*******************************************************************************\n");
printf("Please select:");
scanf("%d", &n);
switch(n)
{
case 1:
do_insert(db);
break;
case 2:
do_query(db);
// do_query1(db);
break;
case 3:
do_delete(db);
break;
case 4:
do_update(db);
break;
case 5:
printf("main exit.\n");
sqlite3_close(db);
exit(0);
break;
case 6:
do_sell(db);
break;
//XXX//mianqiangnenggongzuo
case 7:
do_stock_list(db);
break;
case 8:
do_sell_list(db);
break;
case 9:
help();
break;
default :
printf("Input error\n");
}
}
return 0;
}