今天来学习一些数据库相关的知识。 一. 用Docker安装数据库
- Docker 是一个容器化平台,允许您打包、交付和运行应用程序。在继续之前,让我们简要了解一下 Docker 的一些基本概念:
- 容器(Container): 容器是一个轻量级、独立、可执行的软件包,包含了运行应用程序所需的一切,包括代码、运行时、系统工具、库和设置。
- 镜像(Image): 镜像是一个只读的模板,用于创建容器。它包含了运行应用程序所需的所有信息。您可以将镜像看作是容器的蓝图。
- Mac安装docker,按照官方教程下载.dmg并安装即可
- 安装完,设置国内镜像docker.mirrors.ustc.edu.cn,设置完要重启Docker
- Linux Docker
- 不同的Linux发行版的教程不同
- 安装完同样需要设置镜像
- Windows 教程
- 新版Docker
- 注册https:/hub.docker.com/
- 下载Docker for Windows Installer(需要登录)
- 确保docker-version返回版本号
- 设置国内镜像https:/docker.mirrors.ustc.edu.cn,设置完要重启Docker
- 确保docker run hello-world输出Hello from Docker!
- 如果你因为Hyper-V等原因无法安装新版,可以考虑旧版Docker
- 旧版Docker
- 旧版Docker兼容性更好,性能差一点
- 下载Docker Toolbox
- 打开Docker QuickStart,运行后看到一个IP,退出
- 新开命令行,运行docker -v
- 以后会用到这个IP,用docker-machine ip可得到IP
- 设置国内镜像
- 确保docker run hello-world输出Hello from Docker!
- 新版Docker
二. 开始使用docker运行mysql
- 进入Docker上面MySQL的主页
- 选择版本,如5.7.27或者8.0.18
- 使用docker run命令启动容器
- 运行命令
docker run --name mysql1 -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.7.27
三. 刚才运行的命令的具体解释
docker run
: 这是Docker命令的一部分,用于启动一个新的容器。--name mysql1
: 这个选项用于给容器指定一个名字,这里是"mysql1"。-e MYSQL_ROOT_PASSWORD=123456
: 这个选项用于设置MySQL的root用户的密码。在这个例子中,设置了一个名为 MYSQL_ROOT_PASSWORD 的环境变量,并将其值设置为 123456。具体来说,MYSQL_ROOT_PASSWORD 环境变量是MySQL官方镜像中特定用途的环境变量之一。当启动MySQL容器时设置了这个环境变量,它会被用作root用户的初始密码。这样做的原因是为了确保在容器启动时有一个安全的初始密码,以防止未经授权的访问。-p 3306:3306
: 这个选项用于将容器内的端口映射到主机上。在这个例子中,MySQL默认使用3306端口,这里将容器的3306端口映射到主机的3306端口。这样,可以通过主机的3306端口访问MySQL服务。-d
: 这个选项表示在后台运行容器(即"守护模式")。这意味着容器会在后台运行,而不会阻塞当前终端。mysql:5.7.27
: 这是要运行的MySQL容器的镜像名称及版本。在这个例子中,使用的是MySQL 5.7.27版本。如果这个镜像在本地不存在,Docker会尝试从Docker Hub上下载。- 最后总结一下,这个命令的作用是在Docker中启动一个名为"mysql1"的MySQL容器,使用MySQL 5.7.27版本,设置root用户密码为"123456",并将容器的3306端口映射到主机的3306端口。
- 运行docker ps出现类似下图就说明成功启动
四. 常用Docker命令
-
常用命令:
- 运行docker ps查看容器运行状态
- 运行docker kill mysql1关掉容器
- 运行docker container start mysql1开启刚关掉的容器
- 运行docker rm mysql1删掉容器,必要时可加-f选项
- 运行docker run启动新容器
-
注意
-
用Docker运行的容器,默认不会持久化
-
也就是说如果容器被删掉了,那么数据也没了
-
学习阶段不需要持久化
五. 进入容器并能正确使用mysql
-
运行
docker exec -it mysql1 bash
- 此命令用于通过一个新的终端与正在运行的 Docker 容器进行交互。让我们来分解这个命令:
- docker exec: 这是 Docker 命令的一部分,用于在运行的容器中执行命令。
- -it: 这两个选项结合在一起,表示使用交互模式。这使得我们能够与正在运行的容器进行交互,例如在容器中运行交互式的 shell。
- mysql1: 这是容器的名称,指定要执行命令的目标容器。
- bash: 这是要在容器内运行的命令。在这个例子中,我们使用了 bash,这是一个常见的命令行 shell。
- 总结: 整个命令的作用是进入名为 mysql1 的运行中的 Docker 容器,并启动一个交互式的 bash shell。这样您可以在容器内执行命令,检查容器的状态,进行调试,或者进行其他需要交互式 shell 的操作。
- 此命令用于通过一个新的终端与正在运行的 Docker 容器进行交互。让我们来分解这个命令:
-
运行
mysql -u root -p
,输入密码123456,出现下图表示能成功的进入mysql
六. 学习并使用mysql一些基础命令
show databases;
,注意;
,查看所有数据库use mysql;
,使用mysql这个数据库show tables;
,查看数据库下的表select * from user
; 能查询到表的所有内容- 命令行常规套路
- Ctrl + C,用于中断,比如输错命令
- Ctrl + D,用于退出,比如退出mysql,bash等
七. 数据库基本知识
-
什么是数据库
- 将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合称为数据库
- 根据保存格式的不同,数据库一般被分为:
- 关系数据库-使用最广泛的数据库
- 面向对象数据库、ML数据库、键值存储系统、层次数据库
-
数据库管理系统DBMS
- 用来管理数据库的系统称为数据库管理系统
- 如MySQL、PostgreSQL、SQL Server、DB2、Oracle
-
DBMS的结构
- 我们使用的mysql命令,是一个客户端,而mysql背后还有一个Server在24小时不间断的运行着
八. 使用node.js连接数据库
- 创建文件夹mysql1,新建文件test.js,运行
yarn add mysql
- 之后在新建的test.js中写代码和mysql进行交互
- mysql的utf8是一个bug,需要使用utfmb4
js
const mysql = require('mysql');
// 创建数据库连接
const connection = mysql.createConnection({
host: 'localhost', // MySQL服务器的主机名,除了windows旧版的docker需要写ip其它都只需要写localhost
user: 'root', // MySQL用户名
password: '123456', // MySQL密码
});
// 连接到数据库
connection.connect((err) => {
if (err) {
console.error('Error connecting to MySQL:', err);
return;
}
console.log('Connected to MySQL database');
});
const databaseName = 'fang'; // 创建的数据库名称
const createDatabaseQuery = `CREATE DATABASE IF NOT EXISTS ${databaseName} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`;
connection.query(createDatabaseQuery, (error, results, fields) => {
if (error) {
console.error('Error creating database:', error);
} else {
console.log('Database created successfully');
}
// 关闭数据库连接
});
connection.end();
- 运行脚本见下图为成功
- 运行docker进入mysql来查看是否创建数据库成功
- 下面来创建一个数据库
js
const mysql = require('mysql');
// 创建数据库连接
const connection = mysql.createConnection({
host: 'localhost', // MySQL服务器的主机名,除了windows旧版的docker需要写ip其它都只需要写localhost
user: 'root', // MySQL用户名
password: '1234567', // MySQL密码
});
// 连接到数据库
connection.connect((err) => {
if (err) {
console.error('Error connecting to MySQL:', err);
return;
}
console.log('Connected to MySQL database');
});
const databaseName = 'fang'; // 创建的数据库名称
const createDatabaseQuery = `CREATE DATABASE IF NOT EXISTS ${databaseName} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`;
connection.query(createDatabaseQuery, (error, results, fields) => {
if (error) {
console.error('Error creating database:', error);
} else {
console.log('Database created successfully');
}
// 关闭数据库连接
});
connection.end();
- 创建表
js
// 创建表格
const createTableQuery = `CREATE TABLE IF NOT EXISTS user(name text, age int);`;
connection.query('use fang;')
connection.query(createTableQuery, (err, results, fields) => {
if (err) {
console.error('Error creating table:', err);
} else {
console.log('创建表', results);
}
});
- 通过docker检查是否表创建成功
九. 数据库的基本增删改查
- 数据的新增
sql
// 插入单条
INSERT INTO user (name, age) VALUES ('John Doe', 30);
// 插入多条
INSERT INTO user (name, age) VALUES
('Alice', 25),
('Bob', 28),
('Charlie', 22),
('David', 35);
- 数据的删除
sql
DELETE FROM user WHERE age = 30;
- 数据的修改
sql
UPDATE user SET age = 31 WHERE name = 'John Doe';
- 数据的查询
SELECT * FROM user; // 带条件 SELECT * FROM user WHERE age > 25;
- 需要注意删除,修改数据的时候如果没有加条件,会对整个表生效
十. mysql的数据类型,主要是五大类
-
数字类型: 包括整数和浮点数,如
int
、float
等。每种类型都有其适用场景,例如bigint
适合存储大整数,decimal
适合精确计算。 -
字符串类型: 用于存储文本数据,包括固定长度的
char
和可变长度的varchar
。text
类型适合存储较长的字符串,如博客文章。 -
时间和日期类型: 包括
date
、time
、datetime
、timestamp
等。这些类型用于存储与时间相关的信息。 -
JSON 类型: 从 MySQL 5.7.8 版本开始支持,用于存储 JSON 格式的数据。
-
其他特殊类型: 包括枚举(
enum
)和集合(set
)等。
- 具体每种类型的使用场景和特点,请参考 MySQL 官方文档。
十一. 学习使用ORM之Sequelize.js
- Sequelize.js 是一个基于 Node.js 的 ORM库,它提供了对多种数据库的支持
- 官方文档
- 创建一个空文件夹,并安装
sql
yarn add sequelize
yarn add --dev @types/sequelize
yarn add mysql2
- 代码案例
js
const { Sequelize, DataTypes } = require('sequelize');
// 创建 Sequelize 实例,连接到 MySQL 数据库
const sequelize = new Sequelize('fang', 'root', '123456', {
// host: 'localhost',
dialect: 'mysql',
});
// 定义 User 模型
const User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
allowNull: false,
},
birthDay: {
type: DataTypes.DATE,
allowNull: true, // 允许 birthday 字段为空
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
});
// 同步模型到数据库
sequelize.sync()
.then(() => {
console.log('Database and tables synced');
// 创建一条记录
return User.create({
username: 'john_doe',
birthDay: new Date(1991,11,12),
email: 'john_doe5@example.com',
})
})
.then(john_doe => {
// 打印出一条记录
console.log('record', john_doe)
console.log(JSON.stringify(john_doe))
})
.catch((error) => {
console.error('Error syncing database:', error);
});
- 数据库的查询
js
// 数据库查询
(async () => {
try {
// 查询所有用户
const allUsers = await User.findAll();
console.log('allUsers', allUsers)
console.log('JSON.stringify(allUsers)', JSON.stringify(allUsers))
console.log('All users:', allUsers.map(user => user.toJSON()));
} catch (error) {
console.error('Error:', error);
} finally {
// 关闭数据库连接
await sequelize.close();
}
})();
- 数据库的删除
js
// 数据库的删除
(async () => {
try {
// 查询特定用户
const foundUser = await User.findOne({
where: {username: 'john_doe'},
});
await foundUser.destroy();
console.log('User deleted.');
const allUsers = await User.findAll();
console.log('JSON.stringify(allUsers)', JSON.stringify(allUsers))
} catch (error) {
console.error('Error:', error);
} finally {
// 关闭数据库连接
await sequelize.close();
}
})()