阅读本文您将收获
- SQLite 基本和基本设计能力
- 基于 Rrisma 的 SQLite 数据操作
一、简介
数据库设计是后端的代码编写代码的坚实基础,用户前端所看到的内容,其实就是数据库内容的映射,数据库的类型有很多种,本文选择 SQLite 进行设计和编码工作。SQLite 简单易学,支持事务等特性。
二、资源
- sqlite 官方网站
- sqlite download SQLite 的下载地址
- sqlite sqlite 代码托管地址
- sqlitestudio 官方网站
- sqlitestudio 下载地址
sqlite 号称测试覆盖率 100%,如果你其感兴趣不妨阅读源码。sqlite 是作为嵌入式系统,无需启动服务,存储本地数据极为方便,并且可以以内存的形式进行管理。
三、安装
3.1)安装 sqlite
选择一个合适的版本安装 sqlite,安装之后在终端中输入:
sh
sqlite3
如果正确的响应则安装正常。
3.2)安装 sqlitestudio
四、认识 sqlite 基础
4.1)数据类型
- NULL: null
- INTEGER: 整型
- REAL: 浮点值
- TEXT: 字符串
- BLOB: 二进制
总体来说就是 null,二进制、数据、字符串。是不是特别简单。当然 sqlite 支持 Affinity 类型,也就是将其他的数据类型将。
4.2)基本 cli 操作和 sql 操作
sqlite3 命令,很多语言和工具以及运行时内置对 sqlite 的支持。sqlite3 以 .
开始一些常用命令和 sql 语句:
.open
: 打开一个数据库.quit
: 退出.show
: 展示当前各种值.database
: 展示数据库.tables
: 展示表.schema
: 展示表 schemasql
语句- ...
4.3)与其他的数据库的不同?
sqlite 与其他数据不同很明显了,无需联网,本地嵌入,类型少,简单易用。
五、设计一个用户-角色系统
假设我们有一些数据库基础,了解数据库的基本数据类型,主键、外键、关联关系等等...
- 表 user
- 表 role
- 中间表 user_role
sql
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
email TEXT UNIQUE,
password TEXT
)
CREATE TABLE role (
id INTEGER PRIMARY KEY AUTOINCREMENT,
role_name TEXT NOT NULL,
description TEXT UNIQUE
)
CREATE TABLE user_role (
user_id INTEGER,
role_id INTEGER,
FOREIGN KEY (user_id) REFERENCES user(user_id) ON DELETE CASCADE,
FOREIGN KEY (role_id) REFERENCES role(role_id) ON DELETE CASCADE,
PRIMARY KEY (user_id, role_id)
)
如果还在学习 sql 中早期,手写 sql 表的效率是没有图形化高的,我们需要借助图形化辅助我们更加快速的设计表结构。
六、SQLiteStudio
界面 UI 系统熟悉
- 添加数据库
- 建表
- 表操作
- 工具:sql 编辑器
- 工具:导入和导出
SQLiteStudio 支持的导出数据类型:
- sql
- json
- html
- xml
支持导入的格式:
- csv
- regexp
七、使用 sqlitestudio 设计表结构
有了以上基础知识点,我们使用 sqlitestudio 就能快速的实现表结构的设计。
7.1) user 表
7.2) role 表
7.3) user_role 表
八、基于 node.js + prisma 操作 sqlite
虽然很多库能够操作 sqlite,我们选择 Prisma 来操作 sqlite 数据。下面快速初始化一个 Node.js + Prisma 项目,由于是 SQL,我们使用 prisma 的原生 sql 处理方案。
8.1) 快速开始一个项目
sh
pnpm init
# 设置 prisma 引擎地址为阿里云镜像
PRISMA_ENGINES_MIRROR=https://registry.npmmirror.com/-/binary/prisma
pnpm add prisma typescript esno -D
# 初始化 sqlite
npx prisma init --datasource-provider sqlite
这里有两种方案,之前已经设计表结构,sqlite 数据库中有了表结构,我们可以使用 prisma 链接到 sqlite 数据库然后拉回生成 schema, 然后使用。
sh
npx prisma db pull
方案二:如果熟悉 prisma 的 schemas 直接重新写 prisma.schemas
schema
model User {
id Int @id @default(autoincrement())
username String @unique
email String? @unique
password String?
roles UserRole[]
}
model Role {
id Int @id @default(autoincrement())
roleName String
description String? @unique
users UserRole[]
}
model UserRole {
userId Int
roleId Int
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
@@id([userId, roleId])
}
有了 schemas 需要对其进行一次迁移:
sh
npx prisma migrate dev --name init
迁移之后会自动生成 db 文件和迁移文件,下面我们可以进行操作:
- 查询:
$queryRaw
- 修改:
$executeRaw
8.2) 简单的封装 prisma
ts
import { PrismaClient } from "@prisma/client"
export const prisma = new PrismaClient();
8.3) CURD
ts
import { prisma } from "./prisma";
async function query() {
const users = await prisma.$queryRaw`SELECT * FROM User`;
console.log('All users:', users);
}
async function insert() {
const username = `A` + Date.now()
const email = `E` + Date.now()
const password = `P` + Date.now()
await prisma.$executeRaw`INSERT INTO User (username, email, password) VALUES (${username}, ${email}, ${password})`;
const users = await prisma.$queryRaw`SELECT * FROM User WHERE username = ${username}`;
console.log('Inserted user:', users);
}
async function udpate() {
await prisma.$executeRaw`UPDATE User SET email = 'news.email@example.com' WHERE id = 1`;
const updatedUser = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1`;
console.log('Updated user:', updatedUser);
}
async function delete() {
await prisma.$executeRaw`DELETE FROM User WHERE id = 1`;
const users = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1`;
console.log('Remaining users:', users);
}
prisma 提供了对原生 sql 的支持,当然也支持 api 的方式,写到这里集成 web 框架就很容易写接口了。
九、小结
本文主要介绍了 sqlite 相关的内容,侧重点在于数据库设计初期的使用软件与效率问题的思考与实践,结合 Node.js + Prisma 在 JavaScript 运行时操作自己设计的数据库的流程,更加侧重数据库表的基本设计。