Фото від Sunder Muthukumaran на Unsplash
Вступ
Бази даних — це основа сучасних додатків. Майже всі додатки потребують місця для зберігання даних, таких як інформація про користувачів, продукти або транзакції. Цей модуль навчить студентів, як:
- Використовувати MySQL, реляційну базу даних на основі SQL.
- Використовувати MongoDB, документно-орієнтовану базу даних NoSQL.
- Створювати повноцінний CRUD додаток, використовуючи обидва типи баз даних.
- Виконувати запити до баз даних за допомогою Node.js.
1. Основи баз даних
1.1 Що таке база даних?
База даних — це система для зберігання та управління даними, як структурованими, так і неструктурованими. У сучасних додатках бази даних використовуються для:
- Зберігання даних користувачів.
- Управління продуктами в інтернет-магазинах.
- Реєстрації транзакцій в фінансових додатках.
1.3 CRUD: Основні операції з базами даних
CRUD — це акронім для чотирьох основних операцій з базами даних:
- Create: Додавання нових даних.
- Read: Читання існуючих даних.
- Update: Оновлення даних.
- Delete: Видалення даних.
Приклад CRUD в реальному житті:
- Create: Додавання нового продукту до онлайн-магазину.
- Read: Перегляд списку продуктів в магазині.
- Update: Оновлення ціни або опису продукту.
- Delete: Видалення продукту, який більше не продається.
2. MySQL: Реляційна база даних
MySQL — це одна з найбільш популярних реляційних баз даних у світі. MySQL використовує Structured Query Language (SQL) для доступу до даних і їх маніпуляції.
2.1 Встановлення MySQL
- Завантаження та встановлення MySQL:
Завантажте з офіційного сайту: https://dev.mysql.com/downloads/. - Конфігурація MySQL:
Під час встановлення задайте пароль для користувача root. - Використання MySQL Workbench:
MySQL Workbench — це графічний інтерфейс для полегшення управління базами даних.
2.2 Створення бази даних і таблиць
- Увійдіть до MySQL CLI або GUI, наприклад, phpMyAdmin.
- Створіть нову базу даних:
CREATE DATABASE belajar_nodejs;
- Виберіть базу даних:
USE belajar_nodejs;
- Створіть таблицю
users
:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100),
age INT
);
Пояснення:
AUTO_INCREMENT
: Автоматично збільшує значення ID кожного разу, коли додаються нові дані.PRIMARY KEY
: Унікальний стовпець для ідентифікації кожного рядка даних.
2.3 Підключення Node.js до MySQL
Для підключення Node.js до MySQL потрібно використовувати бібліотеку mysql2.
Кроки:
- Встановлення бібліотеки mysql2:
npm install mysql2
2. Створіть файл підключення до бази даних: Створіть файл db.js
:
const mysql = require('mysql2');
// Конфігурація підключення до бази даних
const db = mysql.createConnection({
host: 'localhost', // Адреса сервера бази даних
user: 'root', // Ім'я користувача бази даних
password: 'password123', // Пароль до бази даних
database: 'belajar_nodejs', // Назва бази даних
});
// Підключення до бази даних
db.connect((err) => {
if (err) {
console.error('Не вдалося підключитися до бази даних:', err.message);
return;
}
console.log('Успішно підключено до бази даних MySQL!');
});
module.exports = db;
3. Запустіть файл: Перевірте, чи підключення успішне, запустивши файл:
node db.js
Пояснення коду:
mysql.createConnection()
: Створює підключення до бази даних.db.connect()
: Підключається до бази даних за допомогою вказаної конфігурації.module.exports
: Дозволяє іншим файлам використовувати підключення до бази даних.
2.4 Створення API CRUD з MySQL
Тепер ми створимо API CRUD за допомогою Express.js та MySQL.
Кроки:
- Підготовка:
- Переконайтесь, що підключення до бази даних (
db.js
) створене. - Встановіть Express.js:
npm install express
**Створення файлу API CRUD**: Створіть файл `app.js`:
const express = require('express');
const db = require('./db'); // Імпортуємо підключення до бази даних
const app = express();
// Middleware для читання JSON
app.use(express.json());
// 1. Читання всіх даних користувачів
app.get('/users', (req, res) => {
const query = 'SELECT * FROM users';
db.query(query, (err, results) => {
if (err) return res.status(500).json({ error: err.message });
res.json(results);
});
});
// 2. Додавання нового користувача
app.post('/users', (req, res) => {
const { name, email, age } = req.body;
const query = 'INSERT INTO users (name, email, age) VALUES (?, ?, ?)';
db.query(query, [name, email, age], (err, results) => {
if (err) return res.status(500).json({ error: err.message });
res.status(201).json({ id: results.insertId, name, email, age });
});
});
// 3. Оновлення даних користувача
app.put('/users/:id', (req, res) => {
const { id } = req.params;
const { name, email, age } = req.body;
const query = 'UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?';
db.query(query, [name, email, age, id], (err) => {
if (err) return res.status(500).json({ error: err.message });
res.json({ message: 'Дані користувача успішно оновлено!' });
});
});
// 4. Видалення користувача
app.delete('/users/:id', (req, res) => {
const { id } = req.params;
const query = 'DELETE FROM users WHERE id = ?';
db.query(query, [id], (err) => {
if (err) return res.status(500).json({ error: err.message });
res.status(204).send();
});
});
// Запуск сервера
app.listen(3000, () => {
console.log('Сервер працює на http://localhost:3000');
});
```
Тестування API CRUD:
- GET
/users
: Отримати всі дані користувачів. - POST
/users
:
- JSON тіло:
{
"name": "John Doe",
"email": "[email protected]",
"age": 30
}
3. PUT /users/:id
:
- JSON тіло:
{
"name": "Jane Doe",
"email": "[email protected]",
"age": 25
}
4. DELETE /users/:id
: Видалити дані користувача за ID.
3. MongoDB: База даних NoSQL
MongoDB — одна з найбільш популярних баз даних NoSQL. Дані в MongoDB зберігаються у вигляді документів формату JSON або BSON (Binary JSON), що робить її дуже гнучкою для зберігання неструктурованих даних.
3.1 Основи MongoDB
- Документ: MongoDB зберігає дані в документах, що подібні до об'єктів JSON. Приклад:
{
"_id": "64aef9e72cfc", // Унікальний ID документа
"name": "John Doe",
"email": "[email protected]",
"age": 30
}
2. Колекція: Колекція — це набір документів, схоже на таблицю в реляційній базі даних.
3. База даних: Набір колекцій, що організовані разом.
3.2 Встановлення MongoDB
- Завантаження MongoDB:
Завантажте з MongoDB Community Server. - Встановлення MongoDB:
- Дотримуйтесь інструкцій по встановленню відповідно до вашої операційної системи.
- На Windows MongoDB зазвичай встановлюється в
C:\Program Files\MongoDB\Server\
.
3. Запуск MongoDB:
- Запустіть сервер MongoDB за допомогою команди:
mongod
- Переконайтесь, що сервер працює на
localhost:27017
.
4. Використання MongoDB Compass (за бажанням):
MongoDB Compass — це графічний інтерфейс для управління базою даних MongoDB. Завантажте за https://www.mongodb.com/try/download/compass.
3.3 Підключення Node.js до MongoDB
MongoDB інтегрується з Node.js за допомогою бібліотеки Mongoose.
Кроки:
- Встановлення бібліотеки Mongoose:
npm install mongoose
2.
Створити файл db.js
для підключення:
const mongoose = require('mongoose');
// Підключення до бази даних MongoDB
mongoose
.connect('mongodb://localhost:27017/belajar_nodejs', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('Успішно підключено до MongoDB!'))
.catch((err) => console.error('Не вдалося підключитися до MongoDB:', err.message));
module.exports = mongoose;
3. Запуск файлу для перевірки підключення:
node db.js
Виведення: Якщо підключення успішне, в терміналі з’явиться повідомлення:
Успішно підключено до MongoDB!
Пояснення коду:
mongoose.connect()
: Використовується для підключення Node.js до MongoDB.useNewUrlParser
: Визначає використання нового парсера URL (стандарт).useUnifiedTopology
: Визначає нову топологію з’єднання для MongoDB.
3.4 Створення моделі в MongoDB
MongoDB не вимагає фіксованої схеми, але за допомогою Mongoose ми можемо визначити схему для полегшення валідації даних.
- Створіть файл
userModel.js
:
const mongoose = require('mongoose');
// Визначення схеми користувача
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
age: { type: Number, required: true },
});
// Створення моделі користувача
const User = mongoose.model('User', userSchema);
module.exports = User;
Пояснення коду:
mongoose.Schema
: Використовується для визначення структури документа.required: true
: Означає, що властивість обов’язково повинна бути заповнена.unique: true
: Означає, що значення властивості повинно бути унікальним.
3.5 Створення API CRUD з MongoDB
Тепер ми створимо API CRUD для колекції users.
Кроки:
- Створіть файл
app.js
:
const express = require('express');
const mongoose = require('./db'); // Підключення до MongoDB
const User = require('./userModel'); // Модель користувача
const app = express();
// Middleware для обробки JSON
app.use(express.json());
// 1. Читання всіх даних користувачів
app.get('/users', async (req, res) => {
try {
const users = await User.find(); // Отримання всіх даних
res.json(users);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// 2. Додавання нового користувача
app.post('/users', async (req, res) => {
try {
const user = new User(req.body); // Створення нового документа
await user.save(); // Збереження документа в MongoDB
res.status(201).json(user);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// 3. Оновлення даних користувача
app.put('/users/:id', async (req, res) => {
try {
const { id } = req.params;
const updatedUser = await User.findByIdAndUpdate(id, req.body, { new: true });
res.json(updatedUser);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// 4. Видалення даних користувача
app.delete('/users/:id', async (req, res) => {
try {
await User.findByIdAndDelete(req.params.id); // Видалення документа за ID
res.status(204).send(); // Без контенту
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Запуск сервера
app.listen(3000, () => console.log('API працює на http://localhost:3000'));
Пояснення коду CRUD:
- GET
/users
: Отримання всіх даних з колекціїusers
. - POST
/users
: Додавання нового документа в колекцію. - PUT
/users/:id
: Оновлення документа за ID. - DELETE
/users/:id
: Видалення документа за ID.
Тестування API CRUD:
Використовуйте Postman для тестування endpoint:
- GET
/users
: Показати всіх користувачів. - POST
/users
: JSON тіло:
{
"name": "John Doe",
"email": "[email protected]",
"age": 30
}
3. PUT /users/:id
: JSON тіло:
{
"name": "Jane Doe",
"email": "[email protected]",
"age": 25
}
4.
**Створити файл app.js
для API CRUD:
const express = require('express');
const db = require('./db'); // Імпортуємо підключення до бази даних
const app = express();
// Middleware для обробки JSON
app.use(express.json());
// 1. Отримати всі дані користувачів
app.get('/users', (req, res) => {
const query = 'SELECT * FROM users';
db.query(query, (err, results) => {
if (err) return res.status(500).json({ error: err.message });
res.json(results);
});
});
// 2. Додати нового користувача
app.post('/users', (req, res) => {
const { name, email, age } = req.body;
const query = 'INSERT INTO users (name, email, age) VALUES (?, ?, ?)';
db.query(query, [name, email, age], (err, results) => {
if (err) return res.status(500).json({ error: err.message });
res.status(201).json({ id: results.insertId, name, email, age });
});
});
// 3. Оновити дані користувача
app.put('/users/:id', (req, res) => {
const { id } = req.params;
const { name, email, age } = req.body;
const query = 'UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?';
db.query(query, [name, email, age, id], (err) => {
if (err) return res.status(500).json({ error: err.message });
res.json({ message: 'Дані користувача успішно оновлено!' });
});
});
// 4. Видалити дані користувача
app.delete('/users/:id', (req, res) => {
const { id } = req.params;
const query = 'DELETE FROM users WHERE id = ?';
db.query(query, [id], (err) => {
if (err) return res.status(500).json({ error: err.message });
res.status(204).send();
});
});
// Запуск сервера
app.listen(3000, () => {
console.log('Сервер працює на http://localhost:3000');
});
Тестування API CRUD:
- GET
/users
: Отримання всіх даних користувачів. - POST
/users
:
- JSON тіло:
{
"name": "John Doe",
"email": "[email protected]",
"age": 30
}
3. PUT /users/:id
:
- JSON тіло:
{
"name": "Jane Doe",
"email": "[email protected]",
"age": 25
}
4. DELETE /users/:id
: Видалення даних користувача за ID.
3. MongoDB: База даних NoSQL
MongoDB є однією з найпопулярніших баз даних NoSQL. Дані в MongoDB зберігаються у вигляді документів з форматом JSON або BSON (Binary JSON), що робить її дуже гнучкою для даних, які не мають чіткої структури.
3.1 Основи MongoDB
- Документ: MongoDB зберігає дані в документах, схожих на об'єкти JSON. Приклад:
{
"_id": "64aef9e72cfc", // Унікальний ID документа
"name": "John Doe",
"email": "[email protected]",
"age": 30
}
2. Колекція (Collection): Колекція документів, схожа на таблицю в реляційній базі даних.
3. База даних: Колекція колекцій, організована для зберігання даних.
3.2 Встановлення MongoDB
- Завантажте MongoDB:
Завантажте з MongoDB Community Server. - Інсталяція MongoDB:
- Слідуйте інструкціям по інсталяції відповідно до вашої операційної системи.
- На Windows MongoDB зазвичай встановлюється в
C:\Program Files\MongoDB\Server\
.
3. Запуск MongoDB:
- Запустіть сервер MongoDB командою:
mongod
- Перевірте, що сервер працює на
localhost:27017
.
4. Використання MongoDB Compass (необов’язково):
MongoDB Compass — це GUI для управління базою даних MongoDB. Завантажити можна за посиланням https://www.mongodb.com/try/download/compass.
3.3 Підключення Node.js до MongoDB
MongoDB інтегрується з Node.js через бібліотеку Mongoose.
Кроки:
- Встановлення бібліотеки Mongoose:
npm install mongoose
2. Створіть файл підключення до бази даних:
const mongoose = require('mongoose');
// Підключення до MongoDB
mongoose
.connect('mongodb://localhost:27017/belajar_nodejs', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('Успішно підключено до MongoDB!'))
.catch((err) => console.error('Не вдалося підключитися до MongoDB:', err.message));
module.exports = mongoose;
**Створення файлу** `productModel.js` **для схеми продуктів**:
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
min: [0, 'Ціна не може бути меншою за 0'],
},
category: {
type: mongoose.Schema.Types.ObjectId, // Посилання на категорію
ref: 'Category',
required: true,
},
});
const Product = mongoose.model('Product', productSchema);
module.exports = Product;
```
6.2 API CRUD
- API для категорій: Додати до
app.js
:
const Category = require('./categoryModel');
// Створення категорії
app.post('/categories', async (req, res) => {
try {
const category = new Category(req.body);
await category.save();
res.status(201).json(category);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// Отримання всіх категорій
app.get('/categories', async (req, res) => {
const categories = await Category.find();
res.json(categories);
});
2. API для продуктів: Додати до app.js
:
const Product = require('./productModel');
// Створення продукту
app.post('/products', async (req, res) => {
try {
const product = new Product(req.body);
await product.save();
res.status(201).json(product);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// Отримання всіх продуктів з категоріями
app.get('/products', async (req, res) => {
const products = await Product.find().populate('category'); // Заповнення категорії
res.json(products);
});
6.3 Тестування зв'язків даних
- Додавання категорії: Ендпоінт: POST
/categories
Тіло JSON:
{
"name": "Електроніка"
}
2. Додавання продукту: Ендпоінт: POST /products
Тіло JSON:
{
"name": "Ноутбук",
"price": 15000000,
"category": ""
}
3. Отримання продуктів: Ендпоінт: GET /products
Результат: Кожен продукт відображатиме деталі категорії.
7. Оптимізація запитів і продуктивності
- Індекси в MongoDB: Індекси використовуються для прискорення пошуку даних. Додати індекс для схеми категорії:
categorySchema.index({ name: 1 }); // Індекс по назві категорії
2. Пагінація для продуктів: Додати функціонал пагінації для ендпоінту GET /products
:
app.get('/products', async (req, res) => {
const { page = 1, limit = 10 } = req.query; // Параметри пагінації
const products = await Product.find()
.populate('category')
.limit(limit * 1) // Ліміт даних на сторінку
.skip((page - 1) * limit); // Пропуск даних відповідно до сторінки
res.json(products);
});
8. Додаткові завдання
- Імплементація CRUD для користувачів з додатковою валідацією:
- Переконайтеся, що
email
унікальний і валідний. - Переконайтеся, що
age
знаходиться в межах від 18 до 65.
2. Багато-до-багатьох зв'язки:
- Створіть зв'язок багато-до-багатьох між продуктами і тегами.
- Кожен продукт може мати багато тегів, і кожен тег може бути прикріплений до багатьох продуктів.
3. Тестування з Postman:
- Переконайтеся, що вся валідація працює коректно.
- Перевірте пагінацію на ендпоінті для продуктів.
9. Рефлексія та обговорення
- Питання для рефлексії:
- Яка основна різниця між зв'язками даних у MySQL і MongoDB?
- Які переваги дає валідація даних на рівні бази даних?
2. Подальше обговорення:
- Як ви управляєте даними з складними зв'язками в MongoDB?
- Які наступні кроки для покращення продуктивності API при великій кількості даних?
Перекладено з: Node.js 4: Menghubungkan dengan Database