嵌入式数据库
数据库综述(文件保存优先选择,因为有格式)
1、什么是数据库?
数据库(DataBase,简记为DB)就是一个有结构的、集成的、可共享的统一管理的数据集合。它不仅包括数据本身,而且包括相关数据之间的联系。数据库技术主要研究如何存储、使用和管理数据;
- 有结构——数据是按一定的模型组织起来的
- 数据模型可用数据结构来描述。
- 数据模型决定数据的组织方式、操作方法。
- 理解数据库的前提是理解数据模型。
- 现在的数据库多数是以关系模型来组织数据的。
- 可以简单地把关系模型的数据结构-关系理解成为一张二维表。
- 集成的——数据库中集中存放着企业各种各样的数据。
- 集中存放的好处是:一个数据只需一个备份,重复存储少,即消除了数据的冗余。 没有数据冗余,也就能保证数据的一致。
- 可共享的——数据库中的数据可以被不同的用户使用
- 也就是说,每一个用户可以按自己的要求访问相同的数据库。
- 统一管理的——指的是数据库由DBMS统一管理
2、数据库是如何存储数据的?
-
DBMS:数据库管理系统(软件)
-
定义
- DBMS ,即DataBase Management System 是用来管理数据库的一种商品化软件。所有访问数据库的请求都由DBMS来成的。DBMS提供了操作数据库的许多命令(语言),即SQL语言
-
DBMS访问方式
- SQL语句
- SQL语句
-
数据库管理的层次结构
- 根据处理对象的不同,数据库管理系统的层次结构由高级到低级依次为应用层、语言翻译处理层、数据存取层、数据存储层、操作系统。
![]()
-
分类
- 分类①
- NOSQL(Mongodb、Redis)
- SQL(oracle、sql server、mysql)
- 分类②
- 小型数据库:sqlite3
- 中型数据库(十万等级):mysql
- 大型数据库(百万数据集):oracle、sql server
- 分类③
- 架构网络(主从、分布):mysql
- 本地:sqlite3
- 单用户数据库系统
单用户数据库系统是一种早期的最简单的数据库系统。在这种系统中,整个数据库系统(包括应用程序、DBMS、数据)都装在一台计算机上,由一个用户独占,不同机器之间不能共享数据。
- 单用户数据库系统
- 分类①
-
常见关系型数据库管理系统
- Oracle是1983年推出的世界上第一个开放式商品化关系型数据库管理系统。它采用标准的SQL结构化查询语言,支持多种数据类型,提供面向对象存储的数据支持,具有第四代语言开发工具,支持Unix、Windows NT、OS/2、Novell等多种平台。除此之外,它还具有很好的并行处理功能。Oracle产品主要由Oracle服务器产品、Oracle开发工具、Oracle应用软件组成,也有基于微机的数据库产品。主要满足对银行、金融、保险等企业、事业开发大型数据库的需求。
- SQL即结构化查询语言(Structured Query Language,简称为SQL)。SQL Server最早出现在1988年,当时只能在OS/2操作系统上运行。2000年12月微软发布了SQL Server 2000,该软件可以运行于Windows NT/2000/XP等多种操作系统之上,是支持客户机/服务器结构的数据库管理系统,它可以帮助各种规模的企业管理数据。随着用户群的不断增大,SQL Server在易用性、可靠性、可收缩性、支持数据仓库、系统集成等方面日趋完美。特别是SQL Server的数据库搜索引擎,可以在绝大多数的操作系统之上运行,并针对海量数据的查询进行了优化。目前SQL Server已经成为应用最广泛的数据库产品之一。
- DB2是基于SQL的关系型数据库产品。20世纪80年代初期DB2的重点放在大型的主机平台上。到90年代初,DB2发展到中型机、小型机以及微机平台。DB2适用于各种硬件与软件平台。各种平台上的DB2有共同的应用程序接口,运行在一种平台上的程序可以很容易地移植到其他平台。DB2的用户主要分布在金融、商业、铁路、航空、医院、旅游等各个领域,以金融系统的应用最为突出。
- Access是在Windows操作系统下工作的关系型数据库管理系统。它采用了Windows程序设计理念,以Windows特有的技术设计查询、用户界面、报表等数据对象,内嵌了VBA(全称为Visual Basic Application)程序设计语言,具有集成的开发环境。Access提供图形化的查询工具和屏幕、报表生成器,用户建立复杂的报表、界面无需编程和了解SQL语言,它会自动生成SQL代码。Access被集成到Office中,具有Office系列软件的一般特点,如菜单、工具栏等。与其他数据库管理系统软件相比,更加简单易学,一个普通的计算机用户,没有程序语言基础,仍然可以快速地掌握和使用它。最重要的一点是,Access的功能比较强大,足以应付一般的数据管理及处理需要,适用于中小型企业数据管理的需求。当然,在数据定义、数据安全可靠、数据有效控制等方面,它比前面几种数据库产品要逊色不少。
-
3、数据管理技术的发展过程
- 人工管理阶段(40年代中--50年代中)
![]()
- 特点: 数据不保存;应用程序管理数据;数据不共享;数据不具有独立性
- 文件系统阶段(50年代末--60年代中)
![]()
- 特点: 数据长期保存;文件管理数据;共享性差;独立性差
- 数据库系统阶段(60年代末--现在)
![]()
- 特点: 数据结构化;数据的共享性高,冗余度低,易扩充;数据独立性高;数据由DBMS统一管理和控制 嵌入式数据库综述
- 区别于文件系统的特点是: 面向应用;记录之间没有联系;最小存取单位是数据记录
4、数据模型
-
层次数据模型
![]()
- 定义
- 层次模型按树型结构组织数据,它是以记录类型为结点,以结点间联系为边的有序树,数据结构为有序树或森林。
- 优点
- 优点: 数据结构很类似于金字塔,不同层次之间的关联性直接而且简单。
- 缺点
- 由于数据纵向发展,横向关系难以建立,数据可能会重复出现,造成管理维护的不便。
-
网状数据模型
![]()
- 定义
- 网状模型用网状结构表示实体及其之间的联系,网中结点之间的联系不受层次限制,可以任意发生联系。
- 优点
- 避免了数据的重复性,具有良好的性能,存取效率高。
- 缺点
- 关联性比较复杂,尤其是当数据库变得越来越大时,关联性的维护会非常麻烦。
-
关系数据模型
- 定义
- 用关系(二维表格形式结构)来表示实体类型以及实体间联系的模型称为关系模型。关系数据模型是由IBM公司的E.F.Codd于1970年首次提出,以关系数据模型为基础的数据库管理系统,称为关系数据库系统(RDBMS),目前广泛使用。
![]()
- 定义
-
面向对象数据库模型
- 定义
- 使用面向对象技术(Object-Oriented,简称OO)来表示信息世界的实体类型及实体之间联系的模型称为对象模型。
![]()
- 定义
5、数据库系统的三级模式结构
-
(1)数据库系统的三级模式结构是指数据库系统是由外模式、模式和内模式三级组成。
-
![]()
-
外模式
- 外模式也称子模式或用户模式,它是数据库用户(包括应用程序员和最终用户)看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。外模式一般是模式的子集。一个模式可以有多个外模式。一个应用程序只能使用一个外模式。外模式是保证数据库安全性的一个有力措施。
-
模式
- 模式也称为逻辑模式或概念模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公用数据视图。一个数据库只有一个模式。模式是数据项值的框架。数据库系统模式通常还包含有访问控制、保密定义、完整性检查等方面的内容。
-
内模式
- 内模式也称为存储模式,是数据库在物理存储器上具体实现的描述,是数据在数据库内部的表示方法,也是数据物理结构和存储方式的描述。一个数据库只有一个内模式
-
-
(2)二级映像功能与数据独立性
- 数据库系统在三级模式之间提供了两层映像:外模式/模式映像和模式/内模式映像。正是这两层映像保证了数据库系统的数据能够具有较高的逻辑独立性和物理独立性。
- 数据独立性
- 数据的逻辑独立性
- 模式描述的是数据的全局逻辑结构,外模式描述的是数据的局部逻辑结构。对应于同一个模式可以有任意多个外模式。对于每一个外模式,数据库系统都有一个外模式/模式映像,它定义了该外模式与模式之间的对应关系。当模式改变时(例如,增加新的数据类型、新的数据项、新的关系等),由数据库管理员对各个外模式/模式的映像作相应改变,可以使外模式保持不变,从而应用程序不必修改,保证了数据的逻辑独立性
- 数据的物理独立性
- 数据库中只有一个模式,也只有一个内模式,所以模式/内模式映像是惟一的,它定义了数据全局逻辑结构与存储结构之间的对应关系。当数据库的存储结构改变时(例如,采用了更先进的存储技术),由数据库管理员对模式/内模式映像作相应改变,可以使模式保持不变,从而保证了数据的物理独立性。
- 数据的逻辑独立性
(3)数据库系统结构
从数据库管理系统的角度,数据库系统通常采用三级模式结构,这是数据库管理系统内部的系统结构。从数据库最终用户的角度看,数据库结构分为集中式、分布式、客户/服务器和并行结构等
- 本地小型数据库
- Main Frame大型数据库
- 分布式数据库
- 客户机/服务器数据库
(4)关系术语与定义
- 关系(Relation):一个关系就是一张二维表,每一个关系有一个关系名,可以存储为一个文件。其定义可以描述为 的子集叫做域 , ,…, 上的关系,表示为 ,R表示关系的名称,n表示关系的目或度(Degree)。
- 元组:表中的行称为元组,一行就是一个元组,对应存储文件中的一个记录。
- 属性:关系中的一列称为一个属性。一个属性必须有唯一的属性名,一个关系可以有若干个属性值。
- 域(Domain):属性的取值范围,是一组具有相同数据类型的值的集合。
- 关系的候选键与主键
- 表中某一列(或若干列的最小组合)的值能惟一标识一个行,称该列或列组为候选键。如Students表的学号列,就是一个候选键。
- 对于一个表,可能有多个候选键 。
- 候选键取决于应用范围,如给定条件,没有重复的学生姓名,则姓名是学生基本情况表的一个候选键。
- 如果一个表有多个候选键,数据库设计者通常选择其中一个候选键作为区分行的惟一性标识符,称为主键(primary key,PK)。如果一个表只有一个候选键,那么这个候选键就作为主键。例如,在学生基本情况表中,把学号作为该表的主键。
- 因为主键是候选键之一,而根据候选键的定义,候选键列上的各个值都惟一,因此主键列上的各个值也都惟一
- 外键(Foreign Key,FK)
- 若一个表R1中的一个列或列组对应另一个表R2的主键,那么该列或列组称为表R1的外键。
- 外键可以由一个或多个列组成,可以有重复值
![]()
(5)储存数据类型
- 空
- 这个值为空值
- 整数
- 值被标识为整数,依据值的大小可以依次被存储1,2,3,4,5,6,7,8.
- 实数
- 所有值都是浮动的数值,被存储为8字节的IEEE浮动标记序号.
- 文本
- 值为文本字符串,使用数据库编码存储(TUTF-8, UTF-16BE or UTF-16-LE).
- BLOB
- 值是BLOB数据,如何输入就如何存储,不改变格式.
- bit整型
- bit 数据类型是整型,其值只能是0、1或空值。这种数据类型用于存储只有两种可能值的数据,如Yes 或No、True 或Fa lse 、On 或Off
- int整型
- int 数据类型可以存储从- 231(-2147483648)到231 (2147483 647)之间的整数。存储到数据库的几乎所有数值型的数据都可以用这种数据类型。这种数据类型在数据库里占用4个字节
- smallint整型
- smallint 数据类型可以存储从- 215(-32768)到215(32767)之间的整数。这种数据类型对存储一些常限定在特定范围内的数值型数据非常有用。这种数据类型在数据库里占用2 字节空间
- tinyint整型
- tinyint 数据类型能存储从0到255 之间的整数。它在你只打算存储有限数目的数值时很有用。 这种数据类型在数据库中占用1 个字节
- numeric精确数值型
- numeric数据类型与decimal 型相同
- decimal精确数值型
- decimal 数据类型能用来存储从-1038-1到1038-1的固定精度和范围的数值型数据。使用这种数据类型时,必须指定范围和精度。 范围是小数点左右所能存储的数字的总位数。精度是小数点右边存储的数字的位数
- money货币型
- money 数据类型用来表示钱和货币值。这种数据类型能存储从-9220亿到9220 亿之间的数据,精确到货币单位的万分之一
- smallmoney货币型
- smallmoney 数据类型用来表示钱和货币值。这种数据类型能存储从-214748.3648 到214748.3647 之间的数据,精确到货币单位的万分之一
- float近似数值型
- float 数据类型是一种近似数值类型,供浮点数使用。说浮点数是近似的,是因为在其范围内不是所有的数都能精确表示。浮点数可以是从-1.79E+308到1.79E+308 之间的任意数
- real近似数值型
- real 数据类型像浮点数一样,是近似数值类型。它可以表示数值在-3.40E+38到3.40E+38之间的浮点数
- datetime日期时间型
- datetime数据类型用来表示日期和时间。这种数据类型存储从1753年1月1日到9999年12月3 1日间所有的日期和时间数据, 精确到三百分之一秒或3.33毫秒
- Smalldatetime日期时间型
- smalldatetime 数据类型用来表示从1900年1月1日到2079年6月6日间的日期和时间,精确到一分钟
- cursor特殊数据型
- cursor 数据类型是一种特殊的数据类型,它包含一个对游标的引用。这种数据类型用在存储过程中,而且创建表时不能用
- timestamp特殊数据型
- timestamp 数据类型是一种特殊的数据类型,用来创建一个数据库范围内的唯一数码。 一个表中只能有一个timestamp列。每次插入或修改一行时,timestamp列的值都会改变。尽管它的名字中有“time”, 但timestamp列不是人们可识别的日期。在一个数据库里,timestamp值是唯一的
- Uniqueidentifier特殊数据型
- Uniqueidentifier数据类型用来存储一个全局唯一标识符,即GUID。GUID确实是全局唯一的。这个数几乎没有机会在另一个系统中被重建。可以使用NEWID 函数或转换一个字符串为唯一标识符来初始化具有唯一标识符的列
- char 字符型
- char数据类型用来存储指定长度的定长非统一编码型的数据。当定义一列为此类型时,你必须指定列长。当你总能知道要存储的数据的长度时,此数据类型很有用。例如,当你按邮政编码加4个字符格式来存储数据时,你知道总要用到10个字符。此数据类型的列宽最大为8000 个字符
- varchar 字符型
- varchar数据类型,同char类型一样,用来存储非统一编码型字符数据。与char 型不一样,此数据类型为变长。当定义一列为该数据类型时,你要指定该列的最大长度。 它与char数据类型最大的区别是,存储的长度不是列长,而是数据的长度
- text 字符型
- text 数据类型用来存储大量的非统一编码型字符数据。这种数据类型最多可以有231-1或20亿个字符
- nchar 统一编码字符型
- nchar 数据类型用来存储定长统一编码字符型数据。统一编码用双字节结构来存储每个字符,而不是用单字节(普通文本中的情况)。它允许大量的扩展字符。此数据类型能存储4000种字符,使用的字节空间上增加了一倍
- nvarchar 统一编码字符型
- nvarchar 数据类型用作变长的统一编码字符型数据。此数据类型能存储4000种字符,使用的字节空间增加了一倍
- ntext 统一编码字符型
- ntext 数据类型用来存储大量的统一编码字符型数据。这种数据类型能存储230 -1或将近10亿个字符,且使用的字节空间增加了一倍
- binary 二进制数据类型
- binary数据类型用来存储可达8000 字节长的定长的二进制数据。当输入表的内容接近相同的长度时,你应该使用这种数据类型
- varbinary 二进制数据类型
- varbinary 数据类型用来存储可达8000 字节长的变长的二进制数据。当输入表的内容大小可变时,你应该使用这种数据类型
- image 二进制数据类型
- image 数据类型用来存储变长的二进制数据,最大可达231-1或大约20亿字节
- BLOB 二进制大对象
- 是一个可以存储二进制文件的容器。典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)
6、SQL语法
-
(1)定义
-
(2)功能
-
数据定义(DDL):用户定义、删除和修改数据模式
- 命令动词:CREATE、DROP、ALTER
-
数据查询(DQL):用于查询数据
- 命令动词:SELECT
-
数据操纵(DML):用于增、删、改数据
- 命令动词:INSERT、UPDATE、DELETE
-
数据控制(DCL):用于控制数据访问权限
- 命令动词:GRANT、REVOKE、DENY
-
-
(3)语法
- SQL的语法很像自然语言。每个语句都是一个祈使句,以动词开头,表示所要做的动作。
![]()
-
(4)命令
- SQL由命令组成,每个命令以分号(;)结束。
- 如下面是3个独立的命令: SELECT id, name FROM foods; INSERT INTO foods VALUES (NULL, 'Whataburger');
-
(4)常量
- 也称为Literals,表示确切的值
- 分类
- 字符串常量——如:'Jerry' 'Newman' 'JujyFruit'
- 数据常量——有整数、十进制数和科学记数法表示的数,如:-1 ,3.142 6.0221415E23
- 二进制常量——如x'0000'的表示法,其中每个数据是一个16进制数。二进制值必须由两个两个的16进制数(8 bits)组成,如:x'01' X'0fff'x'0F0EFF'
-
(6)保留字和标识符
- 保留字由SQL保留用做特殊的用途,如SELECT UPDATE、INSERT、CREATE、DROP和BEGIN等。
- 标识符指明数据库里的具体对象,如表或索引。
- 保留字预定义,不能用做标识符。SQL不区分大小写,下面是相同的语句: SELECT * from foo; select * from foo;
-
(7)创建数据库
-
代码参考
- 新建数据库、输入数据、显示数据、适宜列宽、显示表头、删除行/列、更新数据,添加表头,填充表头内容、删除数据库
-
数据库文件格式
harry@harry-virtual-machine:~/2022$ sqlite3 test.db
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
新建数据库 mytable为数据库名 id,name为数据库列
sqlite> create table mytable(id,name);
输入数据库数据
sqlite> insert into mytable (id,name) values (2,'chen');
sqlite> insert into mytable (id,name) values (3,'zhang');
sqlite> insert into mytable (id,name) values (4,'lang');
sqlite> insert into mytable (id,name) values (1,'chen');
显示数据库内容
sqlite> select * from mytable;
2|chen
3|zhang
4|lang
1|chen
使数据库有适宜列宽
sqlite> .mode column
sqlite> select *from mytable;
2 chen
3 zhang
4 lang
1 chen
显示表头
sqlite> .head on
sqlite> select *from mytable;
id name
---------- ----------
2 chen
3 zhang
4 lang
1 chen
删除id=2的数据内容(删除行)
sqlite> delete from mytable where id=2;
sqlite> select *from mytable;
id name
---------- ----------
3 zhang
4 lang
1 chen
更新数据
sqlite> update mytable set name = 'liang' where name = 'lang';
sqlite> select *from mytable;
id name
---------- ----------
3 zhang
4 liang
1 chen
添加表头email
sqlite> alter table mytable add column email text not null default '';
sqlite> select *from mytable;
id name email
---------- ---------- ----------
3 zhang
4 liang
1 chen
表头email添加内容(all)
sqlite> update mytable set email = 'fafafaf@1163.com';
sqlite> select *from mytable;
id name email
---------- ---------- ----------------
3 zhang fafafaf@1163.com
4 liang fafafaf@1163.com
1 chen fafafaf@1163.com
删除列(email)//因为没有删除列的指令,新建数据库将其余列复制过去,然后删除原数据库
sqlite> create table newtable as select id,name from mytable;
sqlite> .tables
mytable newtable
sqlite> .table
mytable newtable
sqlite> select *from newtable;
id name
---------- ----------
3 zhang
4 liang
1 chen
删除数据库mytable
sqlite> drop table mytable;
sqlite> .tables
newtable
-
相关操作
-
创建表
- 在SQL中,创建和删除数据库对象的语句一般被称为数据定义语言(data definition language,DDL),操作这些对象中数据的语句称为数据操作语言(data manipulation language,DML)。创建表的语句属于DDL,用CREATE TABLE命令,如下定义:
- CREATE [TEMP] TABLE table_name (column_definitions [, constraints]);
- CREATE TABLE命令至少需要一个表名和一个字段名。命令中table_name表示表名,必须与其它所有的标识符不同。column_definitions表示一个用逗号分隔的字段列表。每个字段定义包括一个名称、一个域和一个逗号分隔的字段约束表。“域”一般情况下是一个类型,与编程语言中的数据类型同名,指明存储在该列的数据的类型。
- 在SQLite中有5种本地类型:INTEGER、REAL、TEXT、BLOB和NULL
- 示例程序
- create table episodes (id integer primary key, season int, name text ); create table foods(id integer primary key,type_id integer, name text ); create table food_types(id integer primary key, name text ); create table foods_episodes(food_id integer, episode_id integer );
-
改变表
- 用ALTER TABLE命令改变表的结构。SQLite版的ALTER TABLE命令既可以改变表名,也可以增加字段。
- 一般格式为: ALTER TABLE table { RENAME TO name | ADD COLUMN column_def }
-
查询
-
SELECT是SQL命令中最大最复杂的命令。SELECT的很多操作都来源于关系代数。
-
SQL查询语句的基本结构
- 简单查询
- 多表连接查询
- 合并多个结果集
- SELECT INTO
- 使用TOP限制结果集
- 子查询
-
select-基本结构(方括号表示可选)
- SELECT <目标列名序列> FROM <数据源> [WHERE <检索条件表达式>] [GROUP BY <分组依据列>] [HAVING <分组提取条件>] //必须和GRIOUP BY合用 [ORDER BY <排序依据列>] //默认顺序排列
- ORDER BY <列名> [<列名> … ] [ASC | DESC ]
- 按<列名>进行升序(ASC)或降序(DESC)排序
- SELECT <目标列名序列>(需要哪些列) FROM <表名序列> (从哪些表) WHERE <查询条件> (根据什么条件)
- SELECT <目标列名序列> FROM <数据源> [WHERE <检索条件表达式>] [GROUP BY <分组依据列>] [HAVING <分组提取条件>] //必须和GRIOUP BY合用 [ORDER BY <排序依据列>] //默认顺序排列
-
查询指定列
-
查询全部列
-
常用的查询条件
-
查询条件 谓词 比较(比较运算符)
- =(等于);
- 查询计算机系全体学生谁的Sdept为CS
- select Sname from Student where Sdept=’CS‘;
![]()
- >(大于);
- >=(大于等于);
- <=(小于等于);
- <(小于);
- 查询所有年龄在20岁以下的学生的姓名及年龄
- select Sname,Sage from Student where Sage<20;
![]()
- <>(不等于);!=(不等于)
- NOT + 上述运算符
确定范围
- BETWEEN…AND…(包括临界值);
- 查询年龄在20~23岁之间的学生的姓名、所在系和年龄
- select Sname, Sdept, Sage from Student where Sage between 20 and 23
- NOT BETWEEN …AND…(不包括临界值)
- 查询年龄不在20~23之间的学生姓名、所在系和年龄
- select Sname, Sdept, Sage from Student where Sage not between 20 and 23
- 作用:查找属性值在或不在指定范围内的元组
- 说明:BETWEEN后是范围的下限(低值) AND后是范围的上限(高值)
确定集合
- IN;
- 查询信息系(IS)、数学系(MA)和计算机系(CS)学生的姓名和性别。
- select Sname, Ssex from Student where Sdept in(‘IS’.‘CS’,‘MA’);
- NOT IN
- 查询既不是信息系、数学系,也不是计算机系学生的姓名和性别
- select Sname, Ssex from Student where Sdept not in(‘IS’.‘CS’,‘MA’);
- 作用:用来查找属性值属于指定集合的元组
字符匹配
- 一般形式为: 列名 [NOT ] LIKE 匹配串
- 作用:查找指定列名与匹配串常量匹配的元组。
- 匹配串类型:匹配串可以是字符串常量,也可以含有通配符。
- 通配符种类:
- %(百分号):匹配0个或多个字符。
- _(下划线):匹配一个字符。
- [ ]:匹配括号中的字符
- [∧ ]:不匹配括号中的字符
- LIKTE;
- 查询名字中第2个字为“海”字的学生的姓名和学号
- select Sname,Sno from student where Sname like '_海';
- 查询以a,b,c开始的产品名称
- select productName from products where name like‘[a-c]%’;
- 查询名字中第2个字为“海”字的学生的姓名和学号
- NOT LIKE
- 查询所有不姓“刘”的学生
- select Sname from student where Sname not like '刘%’;
空值
- 空值是未确定的值或其值尚不知道,所以不可以用等于或不等于来比较或衡量;
- 例如,学生选课,在开学初学生只有选课记录,没有修课成绩,这时成绩一项的值就是空值。 不能用=或<>,只能用IS NULL或IS NOT NULL
- IS NULL
- 查询无成绩的学生的学号和相应的课程号
- select Sno,Cno from student where Grade is null
- IS NOT NULL
多重条件(逻辑谓词)
- AND
- 查询计算机系年龄在20岁以下的学生姓名
- select Sname from student where Sdept='CS' and Sage<20;
- OR
排序
- 对查询结果进行排序的子句为:
- ORDER BY <列名> [<列名> … ] [ASC | DESC ]
- 说明:按<列名>进行升序(ASC)或降序(DESC)排序。
- 查询全体学生情况,查询结果按所在系的系号升序排列,同一系的学生按年龄降序排列
- select * from student order by Sdept,Sage desc
![]()
- =(等于);
-
-
-
-
插入insert
- 语法格式 INSERT [ INTO] table_name { [ ( column_list ) ] { VALUES ( { expression } [ ,...n] ) } }
- 语法注释
- [INTO]:一个可选的关键字,可以将它用在 INSERT 和目标表之间
- table_name:将要接收数据的表或 table 变量的名称。
- (column_list):要在其中插入数据的一列或多列的列表。必须用圆括号将column_list括起来,并且用逗号进行分隔。
- VALUES:引入要插入的数据值的列表。对于column_list(如果已指定)中或者表中的每个列,都必须有一个数据值。必须用圆括号将值列表括起来。如果 VALUES 列表中的值与表中列的顺序不相同,或者未包含表中所有列的值,那么必须使用column_list明确地指定存储每个传入值的列。
- 实例
- 在“Northwind”数据库的“Order Details”表里插入一条记录,其中“OrderID”字段的值为10248;“ProductID”字段的值为1;“UnitPrice”字段的值为10;“Quantity”字段的值为2;“Discount”字段的值为0.8 。
- 程序清单如下: insert [order details] (orderid,productid,unitprice,quantity,discount) values(10248,1,10,2,0.8)
- 在“学生”数据库中创建“教师”表(性别为有默认值列) 。在该表中录入数据。
- insert into teachers(teach_id,teach_name,tsex,tdegree) values('rj001', '李波',DEFAULT, '本科') insert into Student Values (95020, '陈冬', '男','IS', 18); insert Into SC (Sno, Cno,grade) Values(95020, 1,100);
- 在“Northwind”数据库的“Order Details”表里插入一条记录,其中“OrderID”字段的值为10248;“ProductID”字段的值为1;“UnitPrice”字段的值为10;“Quantity”字段的值为2;“Discount”字段的值为0.8 。
-
修改
- 语法格式
- Update <表名> Set <列名>=<表达式>[{, <列名>=<表达式>}] Set 列名 表达式 [{, 列名 表达式 }] [Where <条件>]
- 实例
- 将学生95001的年龄改为22岁
- Update Student Set Sage = 22 Where Sno=95001;
- 将所有学生的年龄增加1岁
- Update Student Set Sage=Sage+1;
- 将学生95001的年龄改为22岁
- 语法格式
-
删除
- 语法格式
- Delete From <表名>[Where <条件>]
- 实例
- 删除学号为95019的学生的记录
- Delete From Student Where Sno=95019
- 删除所有学生的选课记录
- Delete From SC
- 删除学号为95019的学生的记录
- 语法格式
-
(8)SQL提供的计算函数
- COUNT(*):统计表中元组个数
- COUNT(<列名>):统计本列非空列值个数
- SUM(<列名>):计算列值总和(必须是数值型列)
- AVG(<列名>):计算列值平均值(必须是数值型列)
- MAX(<列名>):求列值最大值
- MIN(<列名>):求列值最小值
-
(9)对查询结果分组
- 作用:可以控制计算的级别(对全表还是对一组)
- 目的:细化计算函数的作用对象
- 分组语句的一般形式:
-
[WHERE <条件> ]
-
[GROUP BY <分组条件>]
-
统计每门课程的选课人数,列出课程号和人数
-
select Cno,count(Sno)from SC group by Cno;
-
对查询结果按Cno的值分组,所有具有相同Cno值的元组为一组,然后再对每一组使用COUNT计算,求得每组的学生人数.
-
![]()
-
-
[HAVING <组自身条件>]
- HAVING用于对分组自身进行限制,它有点象WHERE子句,但它用于组而不是对单个记录。
- 查询选修了3门以上课程的学生学号和选课门数
- select Sno,count(*) from SC group by Sno hanving count(*) >3;
- 先用GROUP BY对Sno进行分组,然后再用统计函数COUNT分别对每一组进行统计
![]()
-
7、C API
-
(1)头文件#include <sqlite3.h>
-
(2)打开
- 函数原型:int sqlite3_open(const char* fileName, sqlite3** ppDB);
- 函数功能:打开一个数据库;若该数据库文件不存在,则自动创建。打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行。
- 输入参数:fileName,待打开的数据库文件名称,包括路径,以’\0’结尾;
- 特别说明:SQLite 支持内存数据库,内存方式存储使用文件名“:memory:”
- 输出函数:指向打开或创建数据库的指针,ppDB,返回打开的数据库句柄;一个 数据库连接句柄被返回到这个参数。即是发生错误,唯一的异常是如果 sqlite不能分配内存来存放sqlite对象,ppDb会返回一个NULL值。——跟文件句柄FILE很相似。句柄在很多地方我们见到过,最常见的就是文件的句柄,我们要操作一个文件,我们就要取得一个文件的句柄。句柄是什么东西呢?其实很简单, 句柄是一个东西的描述,它被定义为一个结构体,这个结构会包含这个东西的具体信息,比图位置,大小,类型。我们有了这个描述信息就能去找到这个东西
- 返回值:执行成功返回SQLITE_OK,也就是0,否则返回其他值;
-
(3)关闭
-
函数原型:int sqlite3_close(sqlite3* pDB);
- 函数功能:关闭一个打开的数据库;
- 输入参数:pDB,打开的数据库句柄
- 输出函数:无
- 返回值:执行成功返回SQLITE_OK,否则返回其他值
-
-
(4)调试
- ①
-
函数原型:const char *sqlite3_errmsg(sqlite3* pDB);
- 函数功能:获取最近调用的API 接口返回的错误说明,这些错误信息UTF-8的编码返回,并且在下一次调用任何SQLite API 函数时被自动清除;
- 输入参数:pDB,打开的数据库句柄
- 输出函数:无
- 返回值:错误说明的字符串指针
-
- ②
-
函数原型:int sqlite3_errcode(sqlite3* pDB);
- 函数功能:获取最近调用的API 接口返回的错误代码;
- 输入参数:pDB,打开的数据库句柄
- 输出函数:无
- 返回值:错误代码
-
- ①
-
(5)执行
- ①
-
函数原型:int sqlite3_exec(sqlite3* pDB, const char *sql, sqlite_callback callback, void*para, char** errMsg);
- 函数功能:编译和执行零个或多个SQL 语句,查询的结果返回给回调函数callback
- 输入参数:
- pDB,数据库句柄;
- sql,待执行的SQL 语句字符串,以’\0’结尾;
- callback,回调函数,用来处理查询结果,如果不需要回调(比如做insert 或者delete 操作时),可以输入NULL;
- para,用户传入的参数,可以为NULL,该参数指针最终会被传给回调函数callback,供用户在回调函数中使用;
- sql参数不是select,第三个和第四个可以为NULL
- 输出函数:errMsg,返回错误信息,注意是指针的指针。
- 返回值:执行成功返回SQLITE_OK,否则返回其他值
-
- ②
-
函数原型:int sqlite3_get_table(sqlite3* pDB, const char *sql,char ***pResult, int * rowCount,int * columnCount, char** errMsg);
- 函数功能:执行SQL 语句,通过一维数组返回结果;一般用于数据记录查询
- 输入参数:pDB,打开的数据库句柄;sql,待执行的SQL 字符串,以’\0’结尾;
- 输出函数:
- rowCount,查询出多少条记录(即查出多少行);
- columnCount,查询出来的记录有多少个字段(多少列);
- errMsg,返回错误信息;
- pResult,查询结果,是由字符串组成的一维数组(不要以为是二维数组,更不要以为是三维数组)。它的内存布局是:第一行是字段名称,后面紧接着每个字段的值;
- 返回值:执行成功返回SQLITE_OK,否则返回其他值
- 用free_table释放
-
- ①
-
(6)回调函数
-
函数原型:typedef int (*sqlite_callback)函数名(void* para,int columnCount,char** columnValue,char** columnName);
- 函数功能:由用户处理查询的结果
- 输入参数:
- para,从sqlite3_exec()传入的参数指针;
- columnCount, 查询到的这一条记录有多少个字段(即这条记录有多少列);
- columnValue,查询出来的数据都保存在这里,它实际上是个1 维数组(不要以为是2 维数组),每一个元素都是一个char * 值,是一个字段内容(用字符串来表示,以‘\0’结尾);
- columnName,与columnValue 是对应的,表示这个字段的字段名称。
- 输出函数:无
- 返回值:执行成功返回SQLITE_OK或return 0,一定要加,否则返回其他值
- 回调函数的调用次数:有多少条符合的就调用多少次👆
-
-
(7)释放
-
函数原型:void sqlite3_free_table(char **result);
- 函数功能:释放查询结果占用的内存;
- 输入参数:result,通过函数sqlite3_get_table()查询到的记录结果
- 输出函数:无
- 返回值:无
-
编译:#gcc 文件名.c -o db -lsqlite3
#./db



















浙公网安备 33010602011771号