Cơ sở dữ liệu trong Backend – MySQL và Sequelize ORM

I. Khái niệm cơ bản về cơ sở dữ liệu trong hệ thống Backend

Trong bất kỳ hệ thống Backend nào, dữ liệu luôn là thành phần trung tâm. Tất cả mọi thao tác như đăng nhập, đăng ký, xem danh sách sản phẩm, tìm kiếm, thanh toán… đều liên quan đến việc tương tác với một hệ quản trị cơ sở dữ liệu (DBMS).

Trong những bài trước, API backend của chúng ta làm việc với dữ liệu lưu trong RAM hoặc biến JavaScript tạm thời. Tuy nhiên, cách lưu trữ này không đảm bảo tính bền vững và không thể triển khai trong thực tế. Để xây dựng một backend đúng chuẩn, ta cần kết hợp với một cơ sở dữ liệu ngoại vi (external database).

II. Giới thiệu về cơ sở dữ liệu quan hệ (Relational Database)

1. Cấu trúc logic

Cơ sở dữ liệu quan hệ (Relational Database – RDBMS) được thiết kế xoay quanh khái niệm bảng (table). Mỗi bảng là tập hợp các dòng (row) và cột (column) tt (column) tu1b0ơng ứng với các thuộc tính của thực thể ngoài đời (như người dùng, sản phẩm, đơn hàng).

2. MySQL

Là hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở, được sử dụng rộng rãi trong các hệ thống web. MySQL cho phép xử lý tốt các truy vấn SQL, tự động tối ưu hoá khi kết hợp với ORM.

III. ORM và Sequelize trong Node.js

1. ORM là gì?

ORM (Object Relational Mapping) là công nghệ giúp làm trung gian giữa ngôn ngữ lập trình hướng đối tượng và cơ sở dữ liệu quan hệ. ORM cho phép developer làm việc với database như thao tác với object trong ngôn ngữ.

2. Sequelize ORM

Là thư viện ORM phổ biến nhất cho Node.js, hỗ trợ nhiều DBMS: MySQL, PostgreSQL, SQLite…

Lợi ích khi dùng Sequelize:

  • Quản lý schema qua các model JS
  • Dễ migrate thay đổi database
  • Dễ test, maintain, scale

IV. Thực hành: Kết nối Sequelize với MySQL

1. Chuẩn bị database MySQL

Khởi tạo local MySQL server, tạo database:

CREATE DATABASE backend_db;

2. Cài đặt package:

npm install sequelize mysql2

3. Cấu hình Sequelize

Tạo file config/database.js:

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

const sequelize = new Sequelize('backend_db', 'root', 'password', {
  host: 'localhost',
  dialect: 'mysql',
});

module.exports = sequelize;

4. Định nghĩa model User

File: models/user.js

const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');

const User = sequelize.define('User', {
  name: {
    type: DataTypes.STRING,
    allowNull: false
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true
  }
});

module.exports = User;

5. Khởi tạo Express và sync schema

const express = require('express');
const app = express();
const sequelize = require('./config/database');
const User = require('./models/user');

app.use(express.json());

sequelize.sync({ alter: true }).then(() => {
  console.log('Synced with MySQL');
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

V. Tạo API CRUD

// POST /users
app.post('/users', async (req, res) => {
  const user = await User.create(req.body);
  res.status(201).json(user);
});

// GET /users
app.get('/users', async (req, res) => {
  const users = await User.findAll();
  res.json(users);
});

// GET /users/:id
app.get('/users/:id', async (req, res) => {
  const user = await User.findByPk(req.params.id);
  if (!user) return res.status(404).send('Not found');
  res.json(user);
});

// PUT /users/:id
app.put('/users/:id', async (req, res) => {
  const user = await User.findByPk(req.params.id);
  if (!user) return res.status(404).send('Not found');
  await user.update(req.body);
  res.json(user);
});

// DELETE /users/:id
app.delete('/users/:id', async (req, res) => {
  const user = await User.findByPk(req.params.id);
  if (!user) return res.status(404).send('Not found');
  await user.destroy();
  res.status(204).send();
});

VI. Mở rộng và phân tích

1. So sánh ORM và SQL thuần

Tiêu chíORM (Sequelize)SQL truy vấn tay
Tốc độ ban đầuNhanhCần biết SQL
Tối ưu chi tiếtHạn chế điều khiểnLinh hoạt cao
Dễ maintainCaoPhụ thuộc vào style code
Migrate schemaTự động với alterCần tự viết script

2. Bài tập

  1. Thêm model Product với các trường namepricequantity
  2. Viết API cho Product (tương đồng CRUD)
  3. Tìm hiểu các method Sequelize: findOnefindAllwhereorder

3. Gợi ý triển khai thực tế

  • Sử dụng docker-compose cho MySQL
  • Tách các model ra folder riêng
  • Thêm middlewares cho validate

VII. Chuẩn bị cho bài 4

Trong bài 4, chúng ta sẽ tìm hiểu về xác thực người dùng:

  • Hash password
  • Đăng nhập, đăng ký
  • Tạo và xác minh token JWT
  • Bảo vệ API route bằng middleware auth