跳至正文

💾 什么是数据库?

📖 定义

数据库(Database, DB)是系统地结构化的数据集合。DBMS(Database Management System,数据库管理系统)是创建、管理和访问数据库的软件。数据库可以高效地存储和检索数据,允许多个用户同时安全访问。

🎯 用类比理解

图书馆系统

将数据库比作图书馆:

  • 数据库: 整个图书馆
  • : 各个区域(小说、科学、历史等)
  • 行(Row): 单独的书
  • 列(Column): 书的属性(标题、作者、出版年等)
  • 主键(Primary Key): 图书唯一编号
  • DBMS: 图书管理员和管理系统
图书馆 (数据库)
├─ 小说区 (表)
│ ├─ 书1: 哈利波特, J.K.罗琳, 1997
│ ├─ 书2: 指环王, 托尔金, 1954
│ └─ 书3: 小王子, 圣埃克苏佩里, 1943
├─ 科学区 (表)
│ ├─ 书1: 宇宙, 卡尔·萨根, 1980
│ └─ 书2: 自私的基因, 理查德·道金斯, 1976
└─ 借阅记录 (表)
├─ 记录1: 会员123, 哈利波特, 2024-01-15
└─ 记录2: 会员456, 宇宙, 2024-01-20

⚙️ 工作原理

1. 数据库结构

数据库 (Database)
└─ 表 (Table)
├─ 行 (Row/Record) - 单个数据项
│ └─ 例: 一个用户的信息
└─ 列 (Column/Field) - 数据属性
└─ 例: 姓名、邮箱、年龄

2. 关系型数据库示例

-- users表
users
┌────┬────────┬──────────────────┬─────┐
│ id │ name │ email │ age │
├────┼────────┼──────────────────┼─────┤
1 │ 张三 │ zhang@mail.com25
2 │ 李四 │ li@mail.com30
3 │ 王五 │ wang@mail.com28
└────┴────────┴──────────────────┴─────┘

-- orders表
orders
┌────┬─────────┬─────────────┬───────┐
│ id │ user_id │ product │ price │
├────┼─────────┼─────────────┼───────┤
11 │ 笔记本 │ 1500
21 │ 鼠标 │ 30
32 │ 键盘 │ 80
└────┴─────────┴─────────────┴───────┘

└─ 外键: 引用users表的id

3. CRUD操作

CRUD是数据库的4种基本操作:

C - Create (创建): 添加新数据
R - Read (读取): 查询数据
U - Update (更新): 修改现有数据
D - Delete (删除): 删除数据

💡 实际示例

使用SQL进行CRUD

-- CREATE (创建): 创建表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- CREATE (创建): 添加数据
INSERT INTO users (name, email, age)
VALUES ('张三', 'zhang@mail.com', 25);

INSERT INTO users (name, email, age)
VALUES
('李四', 'li@mail.com', 30),
('王五', 'wang@mail.com', 28);

-- READ (读取): 查询所有用户
SELECT * FROM users;

-- READ (读取): 条件查询
SELECT name, email FROM users
WHERE age >= 28;

-- READ (读取): 排序查询
SELECT * FROM users
ORDER BY age DESC;

-- READ (读取): 搜索
SELECT * FROM users
WHERE name LIKE '张%';

-- UPDATE (更新): 修改数据
UPDATE users
SET age = 26
WHERE name = '张三';

-- UPDATE (更新): 修改多个字段
UPDATE users
SET email = 'new@mail.com', age = 31
WHERE id = 2;

-- DELETE (删除): 删除数据
DELETE FROM users
WHERE id = 3;

-- DELETE (删除): 条件删除
DELETE FROM users
WHERE age < 20;

Node.js中使用数据库

const mysql = require('mysql2/promise');

// 数据库连接
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp',
waitForConnections: true,
connectionLimit: 10
});

// CREATE - 添加用户
async function createUser(name, email, age) {
const [result] = await pool.execute(
'INSERT INTO users (name, email, age) VALUES (?, ?, ?)',
[name, email, age]
);
console.log('创建的ID:', result.insertId);
return result.insertId;
}

// READ - 获取所有用户
async function getAllUsers() {
const [rows] = await pool.execute('SELECT * FROM users');
return rows;
}

// READ - 获取特定用户
async function getUserById(id) {
const [rows] = await pool.execute(
'SELECT * FROM users WHERE id = ?',
[id]
);
return rows[0];
}

// UPDATE - 更新用户信息
async function updateUser(id, name, email, age) {
const [result] = await pool.execute(
'UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?',
[name, email, age, id]
);
console.log('更新的行数:', result.affectedRows);
return result.affectedRows;
}

// DELETE - 删除用户
async function deleteUser(id) {
const [result] = await pool.execute(
'DELETE FROM users WHERE id = ?',
[id]
);
console.log('删除的行数:', result.affectedRows);
return result.affectedRows;
}

// 使用示例
async function main() {
try {
// 创建
const userId = await createUser('张三', 'zhang@mail.com', 25);

// 查询
const users = await getAllUsers();
console.log('所有用户:', users);

// 查询特定用户
const user = await getUserById(userId);
console.log('特定用户:', user);

// 更新
await updateUser(userId, '张三', 'new@mail.com', 26);

// 删除
await deleteUser(userId);
} catch (error) {
console.error('错误:', error);
}
}

main();

ORM使用 (Sequelize)

const { Sequelize, DataTypes } = require('sequelize');

// 数据库连接
const sequelize = new Sequelize('myapp', 'root', 'password', {
host: 'localhost',
dialect: 'mysql'
});

// 模型定义 (表结构)
const User = sequelize.define('User', {
name: {
type: DataTypes.STRING(50),
allowNull: false
},
email: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true
},
age: {
type: DataTypes.INTEGER
}
});

// CRUD操作 (无需SQL,只用JavaScript!)
async function ormExample() {
// CREATE - 创建
const user = await User.create({
name: '张三',
email: 'zhang@mail.com',
age: 25
});
console.log('创建:', user.toJSON());

// READ - 查询
const allUsers = await User.findAll();
console.log('所有用户:', allUsers);

// READ - 条件查询
const youngUsers = await User.findAll({
where: { age: { [Sequelize.Op.gte]: 20 } },
order: [['age', 'DESC']]
});

// READ - 查询单个
const oneUser = await User.findOne({
where: { email: 'zhang@mail.com' }
});

// UPDATE - 更新
await User.update(
{ age: 26 },
{ where: { name: '张三' } }
);

// DELETE - 删除
await User.destroy({
where: { id: 1 }
});
}

关系设置 (JOIN)

// 用户和订单的关系设置
const User = sequelize.define('User', {
name: DataTypes.STRING,
email: DataTypes.STRING
});

const Order = sequelize.define('Order', {
product: DataTypes.STRING,
price: DataTypes.DECIMAL(10, 2)
});

// 关系定义: 一个用户可以有多个订单
User.hasMany(Order);
Order.belongsTo(User);

// JOIN查询
async function getUserWithOrders(userId) {
const userWithOrders = await User.findOne({
where: { id: userId },
include: Order // JOIN
});

console.log(userWithOrders.toJSON());
// {
// id: 1,
// name: '张三',
// email: 'zhang@mail.com',
// Orders: [
// { product: '笔记本', price: 1500 },
// { product: '鼠标', price: 30 }
// ]
// }
}

🤔 常见问题

Q1. 为什么使用数据库?

A: 比文件系统有很多优势:

❌ 文件系统 (例: users.txt)
├─ 可能数据重复
├─ 并发访问问题
├─ 备份/恢复困难
├─ 安全漏洞
└─ 搜索慢

✅ 数据库
├─ 保证数据完整性
├─ 并发控制 (多用户)
├─ 自动备份/恢复
├─ 访问权限管理
├─ 快速搜索 (索引)
└─ 事务支持

Q2. 应该选择哪个数据库?

A: 取决于项目需求:

// 关系型数据库 (SQL)
MySQL / PostgreSQL / SQLite
├─ 优点: 精确的数据结构、事务
├─ 缺点: 灵活性低、可扩展性有限
└─ 适用: 金融、电子商务、用户管理

// 非关系型数据库 (NoSQL)
MongoDB / Redis / Cassandra
├─ 优点: 灵活的模式、水平扩展
├─ 缺点: 复杂关系处理困难
└─ 适用: 社交媒体、实时分析、缓存

Q3. 什么是索引(Index)?

A: 加速数据检索的数据结构:

-- 没有索引
SELECT * FROM users WHERE email = 'test@mail.com';
-- → 检查所有100万行 (慢)

-- 创建索引
CREATE INDEX idx_email ON users(email);

-- 有索引
SELECT * FROM users WHERE email = 'test@mail.com';
-- → 通过索引直接查找 (快!)

-- 缺点: 数据插入/更新时索引也要更新 (写入变慢)

类比: 就像书的目录或索引,可以快速找到想要的内容。

Q4. 什么是事务(Transaction)?

A: 将多个操作作为一个单元捆绑处理:

// 银行转账示例
async function transferMoney(fromId, toId, amount) {
const connection = await pool.getConnection();

try {
// 开始事务
await connection.beginTransaction();

// 1. 减少发送方余额
await connection.execute(
'UPDATE accounts SET balance = balance - ? WHERE id = ?',
[amount, fromId]
);

// 2. 增加接收方余额
await connection.execute(
'UPDATE accounts SET balance = balance + ? WHERE id = ?',
[amount, toId]
);

// 全部成功 → 提交
await connection.commit();
console.log('转账完成!');

} catch (error) {
// 发生错误 → 全部取消
await connection.rollback();
console.log('转账失败,已回滚');
throw error;
} finally {
connection.release();
}
}

// ACID原则
// Atomicity (原子性): 全部执行 or 全部取消
// Consistency (一致性): 不违反规则
// Isolation (隔离性): 与其他事务独立
// Durability (持久性): 完成后永久保存

Q5. 什么是SQL注入(SQL Injection)?

A: 注入恶意SQL代码的攻击:

// ❌ 危险代码 (SQL注入漏洞)
const email = req.body.email; // "admin@mail.com' OR '1'='1"
const query = `SELECT * FROM users WHERE email = '${email}'`;
// 执行: SELECT * FROM users WHERE email = 'admin@mail.com' OR '1'='1'
// → 所有用户信息泄露!

// ✅ 安全代码 (预处理语句)
const [rows] = await pool.execute(
'SELECT * FROM users WHERE email = ?',
[email] // 自动转义
);

// ORM使用 (自动防护)
const user = await User.findOne({
where: { email: email } // 安全
});

🎓 下一步

了解数据库后,继续学习:

  1. SQL vs NoSQL - 数据库选择指南
  2. 什么是Node.js? - 后端开发
  3. 什么是API? - 数据库与前端连接

实践练习

# MySQL 安装和运行
brew install mysql # macOS
sudo apt install mysql # Linux

# 连接数据库
mysql -u root -p

# 创建数据库
CREATE DATABASE myapp;
USE myapp;

# 创建表和添加数据
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
email VARCHAR(100)
);

INSERT INTO users (name, email) VALUES ('张三', 'test@mail.com');
SELECT * FROM users;

🎬 总结

数据库是所有应用程序的核心:

  • 数据库: 结构化数据集合
  • CRUD: 创建、读取、更新、删除 - 基本操作
  • : 以行和列组织数据
  • 关系: 表之间的连接 (JOIN)
  • 事务: 安全的数据处理

深入理解数据库能够构建稳定且可扩展的应用程序! 💾✨