SQLite数据库从0到1

SQLite

SQLite基础知识

  1. SQLite数据库功能特性:ACID事务;支持数据库大小至2TB ;足够小,大致13万行C代码4MB左右;存储在单一磁盘文件中的完整数据库。独立,无额外依赖。源码完全开源。支持多种编程语言,如 C/C++、PHP、Java、Python 等。

  2. ACID:在 DBMS 写入或更新数据过程中,为保证事务正确可靠,具备原子性、一致性、隔离性、持久性 4 个特性 。

  3. 常用指令

    sqlite 复制代码
    databases 列出数据库的名称及所附属的文件信息
    quit 	  退出SQLite程序
    show	  显示各种属性
    open ?OPTION? ?FILE? 打开数据库
    tables ?TABLE? 查询数据库有哪些表
    limit 
    del studentdb.db 删除数据库
  4. SQLite数据库中的主表保存数据库表的关键数据信息,命名为sqlite_master。

    sqlite 复制代码
    sqlite> .schema sqlite_master
    CREATE TABLE sqlite_master (
      type text,
      name text,
      tbl_name text,
      rootpage integer,
      sql text
    );
  5. 创建SQ Lite数据库及创建表

    sqlite 复制代码
    sqlite> .databases
    main: "" r/w
    sqlite> .open studetndb.db
    --通过打开方式创建数据库,如果已经存在,直接打开,否则直接创建数据库
    sqlite> .databases
    main: E:\sqlite\studetndb.db r/w
    sqlite> .tables
    sqlite> create table tbl(stuno,stuname);
    sqlite> .tables
    tbl
    sqlite> insert into tbl values(101,'dell');
    sqlite> .tables
    tbl
    sqlite> select *from tbl;
    101|dell
    sqlite> insert into tbl values(102,'dxll');
    sqlite> select *from tbl;
    101|dell
    102|dxll

SQLite数据库:附加与分离

附加数据库

此操作:打开数据库和使用attach附加进来的数据库必须在同一目录

sqlite 复制代码
sqlite> .databases
main: "" r/w
sqlite> attach database 'db1.db' as 'db1test'
   ...> ;
--没有 db1test 就新建
sqlite> .databases
main: "" r/w
db1test: E:\sqlite\db1.db r/w
sqlite> attach database 'db1.db' as 'db1test2';
sqlite> .databases
main: "" r/w
db1test: E:\sqlite\db1.db r/w
db1test2: E:\sqlite\db1.db r/w

分离数据库

detach database 数据库名称

sqlite 复制代码
sqlite> detach database 'db1test';
sqlite> .databases
main: "" r/w
db1test2: E:\sqlite\db1.db r/w

SQLite数据类型

SQLite存储各类和数据类型

  1. 数据值:
    • NULL:表示该值为NULL值
    • INTEGER:整型值
    • REAL:浮点值
    • TEXT:文本字符串,存储使用的编码方式为UTF-8、UTF-16BE,UTF-16LE。
    • BLOB:存储Blob数据,该类型数据和输入数据完全相同
  2. 日期和时间数据类型:和布尔类型一样,SQLite也同样没有提供专门的日期时间存储类型,而是以TEXY、REAL和INTEGER类型分别表示不同的格式表示该类型。
    • TEXT ('YYYY-MM-DD HH:MM:SS')
    • REAL:从公元前4714年11月24日格林尼治时间的正午计算的天数。
    • INTEGER:从1970-01-01 00:00:00 UTC 算起的秒数
  3. 布尔类型:SQLite没有提供专门的布尔类型,存储为0 1整数

SQLite五种亲缘类型

最大化SQLite和其他数据库引擎之间额数据类型兼容性,SQLite提出类型亲缘性(type affinity)

  • TEXT:数值型数据在被插入之前,需要先被转换为文本格式,之后再插入到目标字段中。
  • NUMERIC :当文本数据被插入到亲缘性为 NUMERIC 的字段中时,如果转换操作不会导致数据信息丢失以及完全可逆,那么 SQLite 就会将该文本数据转换为 INTEGER 或 REAL 类型的数据,如果转换失败,SQLite 仍会以 TEXT 方式存储该数据。
  • INTEGER:对于亲缘类型为 INTEGER 的字段,其规则等同于 NUMERIC,唯一差别是在执行 CAST 表达式时。
  • REAL:其规则基本等同于 NUMERIC,唯一的差别是不会将 "30000.0" 这样的文本数据转换为 INTEGER 存储方式。
  • NONE:不做任何的转换,直接以该数据所属的数据类型进行存储。

INTEGER(假设类型字符串当中包含 INT,此字段亲缘类型为 INEGER)

  • INT、INTEGER(取值范围足够大,不用担心超限问题)
  • TINYINT:枚举类型
  • SMALLINT:用于小范围的统计数据
  • MEDIUMINT:用于比较大整数的计算
  • BIGINT:处理巨大整数才用到。

TEXT

  • VARCHAR 可变长度的字符串
  • TEXT:一个文本字符串
  • CLOB:大文本、大字段

REAL

  • REAL:浮点值,以 8 个字节指数形式存储
  • FLOAT:单精度
  • DOUBLE:双精度

NUMERIC

  • DECIMAL:小数值
  • NUMERIC:精确数字类型
  • DATE:日期类型
  • DATETIME:日期时间类型

SQLite 比较表达式:=、==、<、<=、>、>=、!=、IN、NOT IN、BETWEEN、IS、IS NOT。

SQLite 操作符: + - * / % << >> & and | 。

创建表&删除表

  1. create table 语法:

    sqlite 复制代码
    create table 鼠标名称(
    字段名称1 数据类型1 约束等条件,
    字段名称2 数据类型2 约束等条件,
    字段名称3 数据类型3 约束等条件,
    ...)
  2. SQLite常用约束条件

    sqlite 复制代码
    NOT NULL 约束:确保某列不能有 NULL 值。
    DEFAULT 约束:当某列没有指定值时,为该列提供默认值。
    UNIQUE 约束:确保某列中的所有值是不同的。
    PRIMARY Key 约束:唯一标识数据库表中的各行 / 记录。
    CHECK 约束:CHECK 约束确保某列中的所有值满足一定条件。
  3. Navicat:

    sqlite 复制代码
    --------创建数据表
    -- 学生表
    create table student(
    sno INT primary key not null, --学号
    sname text not null,--姓名
    ssex text not null,--性别
    sdept text --所在系、学员
    );
    -- 课程表
    create table course(
    cno int PRIMARY KEY not NULL, --课程编号
    cname text not null, --课程名称
    ccredit int --课程学分
    );
    
    --学生选课表
    create table sc(
    sno int PRIMARY KEY NOT NULL, --学号
    cno int NOT NULL, --课程编号
    score int --考试分数
    );
    select *FROM sqlite_master;
    ----------删除数据表
    drop table sc;

insert into 语句

sqlite 复制代码
INSERT INTO TABLE_NAME[(cloumn1,cloumn2,cloumn3,...cloumnN)] VALUES (value1,value2,value3...,valueN);
INSERT INTO TABLE_NAME VALUES (value1, value2,value3 ..., valueN) ; --不指定列名按顺序即可
sqlite 复制代码
--查询输出student数据表
select *from student;

--向student数据表插入一条记录
insert into student(sno,sname,ssex,sage,sdept)
values(101,'张华','男',21,'计算机系');
insert into student(sno,sname,ssex,sage,sdept)
values(102,'张ss','女',22,'外语系');

--未指定数据表中的字段
insert into student values(103,'刘ss','女',23,'生物系');

select & update & delete

select用法

sqlite 复制代码
-- 查询student表中所有记录
SELECT * FROM "student"

-- 只查询student表中的:学号、姓名
SELECT Sno as '学号', Sname as '姓名' FROM Student

-- SQLite 算术运算符
select 10 + 20; 
select 10 - 20;
select 10 * 20;
select 10 / 20;
select 10 % 20;

--查询表结构信息
PRAGMA table_info(course);

-- SQLite比较运算符
SELECT * FROM student WHERE sage = 19;
SELECT * FROM student WHERE sage > 19;

-- SQLite 逻辑运算符
SELECT *FROM student WHERE sage >= 19 and sage <= 21
SELECT *FROM student WHERE sname LIKE '张%'  --模糊匹配
SELECT *FROM student WHERE sage in(19,21); --19 和 21
SELECT *FROM student WHERE sage not in(19,21); -- 非 19 和 21

SELECT *FROM student WHERE sage BETWEEN 20 and 24; -- 非 19 和 21

-- SQLite表达式
SELECT *FROM student WHERE ssex='女' and sage = 22;

update & delete

sqlite 复制代码
-- SQLite UPDATE 语句操作
UPDATE student 
SET sage = 32
where sno = 1004 --将学号为1004的年龄改为32


-- SQLite delete 删除语句
DELETE FROM student WHERE sno = 1004; --用主键作为条件,防止删除多个

联合查询

sqlite 复制代码
select student.sno,student.sage,student.ssex,student.sname,student.sdept,sc.cno,sc.score
from student,sc
WHERE(student.sno=sc.sno);
1001	21	男	张华	计算机系	101	98
1003	23	女	刘ss	物理系	105	99
1008	22	女	叶知夏	生物系	106	89
1006	19	男	陈嘉佑	生物系	104	88

distinct & orderby & groupby

  1. dinstinct 专用于消除重复记录

    sqlite 复制代码
    -- 通过distinct关键字,消除重复这个字段
    select DISTINCT sname from staff;
  2. order by 专用于对一个或多个字段按升序或者降序排列数据

    sqlite 复制代码
    -- ASC | DESC  从小到大(默认) | 从大到小 order by
    SELECT *FROM staff ORDER BY ssalary ASC;
    SELECT *FROM staff ORDER BY ssalary DESC;
  3. group by 子句专用于配合相同数据进行分组

    sqlite 复制代码
    -- 相同数据进行分组
    select sid, sname,sage,sdepartment,spost, ssalary, sum(ssalary) from staff group by sname ORDER by sname;
  4. having子句专用于指定条件 来过滤将数据,having子句由group by子句创建的分组在设置条件

    sqlite 复制代码
    -- 过滤数据
    select *FROM staff GROUP by sname HAVING COUNT(sname)<2  --姓名只出现一次的
    select *FROM staff GROUP by sname HAVING COUNT(sname)=2  --姓名只出现一次的
    -- 1	andy	29	开发部	工程师	15000

SQLite触发器

SQLite触发器是数据库的一个回调函数,在指定的数据库事件发生时,自动执行或调用。比如insert、update、delete时等触发。

sqlite 复制代码
select * FROM staff;

select * FROM staff_log;

--创建staff员工表对应日志表
create table staff_log(
Staff_ID INT NOT NULL,
Staff_Date TEXT NOT NULL
);

-- 创建触发器 staff数据表--->监控此表插入记录事件
CREATE TRIGGER staff_logtrigger after INSERT  -- 对 staff 执行插入操作后
ON staff
BEGIN
	insert into staff_log(Staff_ID,Staff_Date) VALUES(new.SID,datetime('now'));
END

--- test data

insert into staff values(15,'yuuny',38,'财务部','会计',16000);
-- 15	2025-02-27 06:12:49
insert into staff values(16,'say',32,'财务部','出纳',17000);
16	2025-02-27 06:14:58

-- 查询刚创建的触发器:staff_logtrigger
SELECT name from sqlite_master
where type='trigger';

-- 删除触发器
DROP TRIGGER staff_logtrigger;

SQLite索引

索引index是一种特殊查找表,数据库搜索引擎用来加速数据检索功能

sqlite 复制代码
CREATE INDEX 索引名称 ON 数据表名称;
  • 搜索码:表示的是记录各种字符段的一个集合,它可以是一个或者多个字符段的任意序列组合,并不是唯一的一个标识记录。
  • 数据目录项: 为索引的相关元素,在建立索引的过程中,数据目录项一般具有各种不同的选择方式
  • 记录ID:每一个/段索引在存储内容中唯一的一个标识符。
  1. 单列索引(基于表的一个列上创建索引)
  2. 唯一索引(唯一索引不允许任何重复的值插入到数据表当中:create unique index)
  3. 组合索引(基于表的两个或多个列创建索引)
  4. 隐式索引(在创建数据表的时候,由数据库服务器自动创建索引)
sqlite 复制代码
--查询数据表:staff
SELECT * FROM staff;

-- 创建索引
CREATE INDEX staff_ssalary_index on staff(SSalary);

-- 查找索引
SELECT * FROM sqlite_master WHERE type='index'

-- 通过索引查询数据
SELECT *FROM staff indexed by staff_ssalary_index WHERE ssalary >= 10000


SELECT *FROM staff WHERE ssalary >= 10000
--删除索引
drop index staff_ssalary_index;

优缺点

  • 优点

    • ​ 通过建立索引 可以极大地提高在数据库中获取所需数据信息的速度 ,同时还能够提高服务器处理相关搜索请求的效率

    • ​ 索引本质上是一种数据结构,它会存储表中特定列的值以及这些值对应的行在磁盘上的物理地址(或逻辑指针)。当表中的数据发生变化时,**数据库不仅要更新表中的数据,还要更新与之相关的所有索引。**降低插入、更新和删除操作的性能

  • 避免使用

    • 数据表比较小不要使用索引
    • 索引不应该出现在频繁操作的列当中
    • 索引应该使用在由大量的NULL值列上
    • 又频繁大笔批量数据实现更新、增加、删除操作的。

SQLite 视图

视图则为一张虚拟表,它内容数据由查询决定。视图并不在数据

库中存储的数据值形式存储,记录和字段由自由视图的查询所引用的

表,并且在引用视图时动态生成。

​ 视图是存储在数据库中查询 SQL 语句:安全原因、可以使复杂

的查询易于理解和使用。可以在视图上创建一个触发器。

优势:视点集中简化操作定制数据安全性问题。

SQLite 事务

​ **数据库事务( transaction)**是访问并可能操作各种数据项的

一个数据库操作序列,这些操作要么全部执行,要么全部不执行,

是一个不可分割的工作单位。事务由事务开始与事务结束之间执

行的全部数据库操作组成。

2、事务属性

​ **原子性(Atomicity):**事务中的全部操作在数据库中是不可

分割的,要么全部完成,要么全部不执行。

​ **一致性(Consistency):**几个并行执行的事务,其执行结果

必须与按某一顺序串行执行的结果相一致。

​ **隔离性(Isolation):**事务的执行不受其他事务的干扰,事务

执行的中间结果对其他事务必须是透明的。

​ **持久性(Durability):**对于任意已提交事务,系统必须保证

该事务对数据库的改变不被丢失,即使数据库出现故障。

3、事务控制命令

  • begin transaction:事务处理
  • commit:提交事务
  • rollback:回滚事务

通过事务方式对数据库进行访问优势:

  • 能够保证数据的读一致性;
  • 在数据永久改变前,可以预览数据变化;
  • 把逻辑相关的操作分成一个组。
sqlite 复制代码
select * FROM staff
--事务处理
BEGIN;
DELETE FROM staff WHERE sid=2;
--事务提交 提交之后无法回滚
COMMIT;
--事务回滚
ROLLBACK;

Qt操作SQLite数据库实战

1、QSqlDatabase 类

该类专门用于处理和数据库的连接。头文件需要导入

QSqlDatabase

在工程 qmake.pro 文件中加入 SQL 数据库支持:

QT +=sql

2、Qsqlquery 类

QSqlQuery 类提供执行和操作 SQL 语句的各种方法。比如执行

DML(数据操作语言)语句,如 select/insert/delete/update 及

DLL(数据定义语言),如 create table/create view 等。

CreateSQLConnection.h

cpp 复制代码
#ifndef CREATESQLCONNECTION_H
#define CREATESQLCONNECTION_H

#include <Qtsql/qsqldatabase>
#include <QSqlQuery>
#include <QMessageBox>

static bool CreateSQLConnectionFunc()
{
    QSqlDatabase sqldb=QSqlDatabase::addDatabase("QSQLITE");
    sqldb.setDatabaseName("test.db");

    if(!sqldb.open())
    {
        QMessageBox::critical(0,"错误","SQLite数据库打开失败,请重新打开",QMessageBox::Ok);
        return false;
    }
    else
    {
        QMessageBox::information(0,"正确","SQLite数据库打开成功!",QMessageBox::Ok);
    }
    QSqlQuery queryexec;

    //创建数据表
    queryexec.exec("create table emp(empid int primary key,empname varchar(20))");

    //插入记录
    queryexec.exec("insert into emp values(101,'vico')");
    queryexec.exec("insert into emp values(102,'abd')");
    queryexec.exec("insert into emp values(103,'eve')");
    queryexec.exec("insert into emp values(104,'lot')");
    queryexec.exec("insert into emp values(105,'clat')");
    return true;
}
#endif // CREATESQLCONNECTION_H

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "CreateSQLConnection.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    qDebug()<<"正在连接SQLite数据库......";
    if(!CreateSQLConnectionFunc())
    {
        QMessageBox::information(0,"错误","数据库创建失败,请重新检查",QMessageBox::Ok);
    }

    QSqlQuery query;
    query.exec("select *from emp");

    qDebug()<<"职工编号"<<"职工姓名";

    while(query.next())
    {
        qDebug()<<query.value(0).toInt()<<qPrintable(query.value(1).toString());
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}
相关推荐
蜕变的土豆15 分钟前
ubuntu22.04下安装mysql以及mysql-workbench
数据库·mysql
njsgcs17 分钟前
ubuntu24.04 cmake 报错 libldap-2.5.so.0 解决办法
开发语言·c++
notfindjob26 分钟前
QT Sqlite数据库-教程001 创建数据库和表-下
数据库·qt·sqlite
头发尚存的猿小二1 小时前
2024年第十五届蓝桥杯C&C++大学A组--成绩统计
c语言·开发语言·c++·蓝桥杯
涛思数据(TDengine)1 小时前
虚拟表、TDgpt、JDBC 异步写入…TDengine 3.3.6.0 版本 8 大升级亮点
大数据·数据库·tdengine
JuicyActiveGilbert1 小时前
【C++游戏引擎开发】第9篇:数学计算库GLM(线性代数)、CGAL(几何计算)的安装与使用指南
c++·线性代数·游戏引擎
betazhou1 小时前
sqlserver2017 分离附加数据库
数据库·oracle·sqlserver
我是小木鱼1 小时前
浅析Centos7安装Oracle12数据库
linux·运维·服务器·数据库
Arbori_262151 小时前
oracle 表空间(Tablespace)
数据库·oracle
DevangLic2 小时前
下【STL 之速通pair vector list stack queue set map 】
开发语言·c++·list