[Công nghệ Thông tin] -- [Web] -- [Công nghệ phần mềm] -- [PhoThong] -- [Đăng ký các khóa học] -- [Langbiang's Portfolio] -- [Học viên cũ] -- [10.000 giờ]
--------------- <> -----------------
---  KHOA HỌC - CÔNG NGHỆ - GIÁO DỤC - VIỆC LÀM --->>>  CÁC KHÓA HỌC...
---  Nhận làm website, web app, chạy quảng cáo, digital marketing --->>>  LIÊN HỆ...

Tìm kiếm trong Blog

Web back-end (23) - Tạo các bảng và mối quan hệ

Bài trước: Web back-end (22) - Tạo cơ sở dữ liệu bằng Sequelize

-----

23. Tạo các bảng và mối quan hệ

23.1 Tạo các bảng có mối quan hệ 1-n

Vào cửa sổ dòng lệnh, tắt web server, nhập vào đoạn mã sau để tạo model cho bảng Images:

E:\TeoShop>sequelize model:create --name Image --attributes name:string,imagePath:string 

Sequelize CLI [Node: 22.14.0,

CLI: 6.6.2, ORM: 6.37.7]

New model was created at E:\TeoShop\models\image.js .

New migration was created at E:\TeoShop\migrations\20250506035103-create-image.js .

Nhập vào đoạn mã sau để tạo model cho bảng Brands:

E:\TeoShop>sequelize model:create --name Brand --attributes name:string,imagePath:string 

Sequelize CLI [Node: 22.14.0,

CLI: 6.6.2, ORM: 6.37.7]

New model was created at E:\TeoShop\models\brand.js .

New migration was created at E:\TeoShop\migrations\20250506035329-create-brand.js .

Tạo mối quan hệ 1-n

Mối quan hệ giữa 2 bảng Products và Images là 1-n, nghĩa là một sản phẩm (product) sẽ có nhiều hình ảnh (image).

Vào tập tin models\product.js, thêm đoạn mã sau:

[models\product.js]

  */

    static associate(models) {

      // define association here

      Product.hasMany(models.Image, { foreignKey: 'productId' });

    }

  }

  Product.init({

Hiểu đoạn mã nguồn là: một product thì có nhiều (hasMany) image, khóa ngoại trong bảng Images sẽ có tên là productId.

Vào tập tin models\image.js, thêm vào đoạn mã sau:

[models\image.js]

 */

    static associate(models) {

      // define association here

      Image.belongsTo(models.Product, { foreignKey:'productId'});

    }

  }

  Image.init({

Hiểu đoạn mã nguồn là: một image thuộc về (belongs to) một product, thông qua khóa ngoại productId.

Tương tự, mối quan hệ giữa 2 bảng Brands và Products là 1-n, nghĩa là một thương hiệu (brand) sẽ có nhiều sản phẩm (product).

Vào tập tin models\brand.js, thêm đoạn mã sau:

[models\brand.js]

    */

    static associate(models) {

      // define association here

      Brand.hasMany(models.Product, { foreignKey:'brandId' });

    }

  }

  Brand.init({

Hiểu đoạn mã nguồn là: một brand có nhiều (hasMany) product, thông qua khóa ngoại brandId.

Vào tập tin models\product.js, thêm đoạn mã sau:

[models\product.js]

static associate(models) {

      // define association here

      Product.hasMany(models.Image, { foreignKey: 'productId' });

      Product.belongsTo(models.Brand, { foreignKey:'brandId' } );

    }

Hiểu đoạn mã nguồn là: một product thuộc về (belongsTo) một brand, thông qua khóa ngoại brandId.

Để cập nhật các khai báo về mối quan hệ 1-n vừa khai báo ở trên vào cơ sở dữ liệu, chúng ta cần thực hiện các bước sau:

- Lưu lại mã nguồn của các tập tin vừa được thêm mã nguồn.

- Mở pgAdmin, xóa các bảng liên quan (Products).

- Khởi chạy lại web server.

- Mở trình duyệt web, gõ lại lệnh /createTables (http://localhost:9000/createTables).

- Nếu lệnh /createTables chạy thành công, bạn sẽ thấy dòng thông báo “tables created” trên trình duyệt

- Mở lại cơ sở dữ liệu trong pgAdmin sẽ thấy 3 bảng xuất hiện, trong mỗi bảng sẽ có thêm trường khóa ngoại (ví dụ, trong bảng Products sẽ là brandId; trong bảng Images sẽ là productId). Các trường createdAt và updateAt trong mỗi bảng cũng được tạo tự động. Trong mỗi bảng, bạn vào mục Constraints để xem các khóa ngoại đã được tạo ra (ví dụ Images_productId_fkey).

23.2 Tạo các bảng có mối quan hệ n-n

Quay trở lại các bảng dữ liệu của ứng dụng TeoShop, chúng ta có bảng Tags, dùng để lưu các thẻ (từ khóa, nhãn); thẻ này sẽ được gắn vào sản phẩm (product). Những thẻ này giúp mô tả các đặc điểm, phong cách, hoặc thuộc tính nổi bật của sản phẩm, từ đó hỗ trợ việc tìm kiếm, lọc và khám phá sản phẩm một cách hiệu quả hơn cho cả người quản lý và khách hàng.

Một product có thể gắn nhiều tag; một tag có thể gắn cho nhiều product. Do vậy, mối quan hệ giữa bảng Products và Tags là n - n (nhiều - nhiều).

Vào cửa sổ dòng lệnh, tắt web server, nhập vào đoạn mã sau để tạo model cho bảng Tags:

E:\TeoShop>sequelize model:create --name Tag --attributes name:string

Sequelize CLI [Node: 22.14.0,

CLI: 6.6.2, ORM: 6.37.7]

New model was created at E:\TeoShop\models\tag.js .

New migration was created at E:\TeoShop\migrations\20250506091413-create-tag.js .

Nhập tiếp đoạn mã sau để tạo model cho bảng ProductTags (vì bảng này chỉ có 2 thuộc tính là khóa ngoại, nên sẽ không cần tùy chọn --attributes, nhưng thiếu tùy chọn này lệnh sẽ bị lỗi, vì vậy chúng ta cứ thêm tùy chọn --attributes name:string rồi sẽ xóa sau):

E:\TeoShop>sequelize model:create --name ProductTag --attributes name:string

Sequelize CLI [Node: 22.14.0,

CLI: 6.6.2, ORM: 6.37.7] 

New model was created at E:\TeoShop\models\producttag.js .

New migration was created at E:\TeoShop\migrations\20250506091721-create-product-tag.js .

Để định nghĩa mối quan hệ nhiều-nhiều giữa bảng Products và Tags, chúng ta cần định nghĩa trên 3 model, gồm: product.js, tag.js và producttag.js.

Vào tập tin models\tag.js, thêm đoạn mã sau:

[models\tag.js]

     */

    static associate(models) {

      // define association here

      Tag.belongsToMany(models.Product, { through: 'ProductTag', foreignKey: 'tagId', otherKey: 'productId' });

    }

  }

  Tag.init({

Hiểu đoạn mã nguồn là: một tag thuộc về nhiều (belongsToMany) product, được thể hiện trong bảng ProductTags, với khóa chính được tạo ra từ 2 khóa ngoại là tagId và productId.

Tương tự, vào tập tin models\product.js, thêm vào đoạn mã sau:

[models\product.js]

      Product.hasMany(models.Image, { foreignKey: 'productId' });

      Product.belongsTo(models.Brand, { foreignKey:'brandId' } );

      Product.belongsToMany(models.Tag, { through: 'ProductTag', foreignKey: 'productId', otherKey: 'tagId' });

    }

  }

...

Tương tự, vào tập tin models\producttag.js, thêm vào đoạn mã sau:

[models\producttag.js]

    static associate(models) {

      // define association here

      ProductTag.belongsTo(models.Product, { foreignKey: 'productId' });

      ProductTag.belongsTo(models.Tag, { foreignKey: 'tagId' });

    }

  }

  ProductTag.init({

Chúng ta cũng xóa bỏ dòng tô đậm (tạo cột name: name: DataTypes.STRING) trong models\producttag.js

[models\producttag.js]

}

  ProductTag.init({

    name: DataTypes.STRING

  }, {

    sequelize,

    modelName: 'ProductTag',

  });

  return ProductTag;

Do chúng ta không chỉnh sửa các cột của bảng Products, nên chúng ta không cần xóa bảng Products, mà chỉ cần chạy lệnh \createTables để tạo bảng Tags và ProductTags từ model tag.js và producttag.js.

- Lưu lại mã nguồn các model: product.js, tag.js và producttag.js.

- Khởi chạy lại web server

- Mở trình duyệt, nhập vào đường dẫn: http://localhost:9000/createTables

- Nếu việc tạo bảng thành công, trình duyệt sẽ có dòng chữ “tables created”

- Vào pgAdmin sẽ thấy có bảng Tags, ProductTags được tạo ra.

Bạn có thể xem Sơ đồ quan hệ thực thể (ERD - Entity Relationship Diagram) của cơ sở dữ liệu teoshopDB. Ví dụ trong pgAdmin, chuột phải vào teoshopDB > chọn ERD For Database.

Xem hình minh họa ERD.

23.3 Bài tập

Bài tập 23.1 Tạo các bảng và thiết lập các quan hệ giữa các bảng.

-----

Cập nhật: 7/5/2025

Bài sau:

Web back-end (22) - Tạo cơ sở dữ liệu bằng Sequelize

Bài trước: Web back-end (21) - Lập trình với cơ sở dữ liệu 

-----

22 Tạo cơ sở dữ liệu bằng Sequelize

22.1 Tạo cơ sở dữ liệu rỗng

- Sử dụng pgAdmin (hoặc một phần mềm thao tác với Postgresql bất kỳ) để tạo một cơ sở dữ liệu rỗng (ví dụ, đặt tên là teoshopDB).

- Vào tập tin config/config.json của dự án (TeoShop), chỉnh sửa thông tin kết nối tới cơ sở dữ liệu.

[config/config.json]

{

  "development": {

    "username": "postgres",

    "password": "p@ssword1",

    "database": "teoshopDB",

    "host": "127.0.0.1",

    "dialect": "postgres"

  },

  "test": {

    "username": "root",

    "password": null,

    "database": "database_test",

Lưu ý: bạn sửa lại thông tin của mục password, database theo cài đặt trên máy của bạn.

22.2 Tạo lớp đối tượng

Vậy là chúng ta đã có cơ sở dữ liệu rỗng (tên là teoshopDB), chưa có bảng dữ liệu, chưa định nghĩa mối quan hệ giữa các bảng, chưa có dữ liệu.

Công việc tiếp theo chúng ta cần thực hiện là tạo các bảng cho cơ sở dữ liệu.

Để tạo bảng, chúng ta sẽ tạo lớp đối tượng tương ứng.

Ví dụ, chúng ta sẽ tạo lớp đối tượng có tên là Product (lưu ý: không có chữ s sau Product), bằng lệnh sau:

sequelize model:create --name Product --attributes name:string,imagePath:string

Trong đó,

- sequelize: lệnh của sequelize

- model:create: tạo model mới

- tùy chọn --name Product: tên của model sẽ tạo có tên là Product

- tùy chọn --attributes name:string,imagePath:string : định nghĩa tên và kiểu dữ liệu các cột của bảng. Bạn không nhất thiết phải liệt kê đầy đủ các cột của bảng ở dòng lệnh (vì dễ bị lỗi đánh máy), mà nên chỉnh sửa ở trong mã nguồn.

E:\TeoShop>sequelize model:create --name Product --attributes name:string,imagePath:string

Sequelize CLI [Node: 22.14.0,

CLI: 6.6.2, ORM: 6.37.7]

New model was created at E:\TeoShop\models\product.js .

New migration was created at E:\TeoShop\migrations\20250505121847-create-product.js .

Nếu lệnh sequelize model:create chạy thành công, nó sẽ tạo cho chúng ta 2 tập tin, là models\product.jsmigrations\ -create-product.js.

Chúng ta sẽ mở tập tin models\product.js để định nghĩa các cột còn lại của bảng Products (khi tạo bảng trong cơ sở dữ liệu sẽ có thêm chữ “s” sau chữ Product).

[models\product.js]

Product.init({

    name: DataTypes.STRING,

    imagePath: DataTypes.STRING,

    oldPrice: DataTypes.DECIMAL,

    summary: DataTypes.TEXT,

    description: DataTypes.TEXT,

    specification: DataTypes.TEXT,

    stars: DataTypes.FLOAT,

    quantity: DataTypes.INTEGER

  }, {

    sequelize,

    modelName: 'Product',

  });

Để thực thi nội dung đã được khai báo trong models\product.js, nhằm tạo ra bảng Products trong cơ sở dữ liệu teoshopDB, chúng ta sẽ viết đoạn mã trong TeoShop\index.js.

[TeoShop\index.js]

// khai bao de su dung engine da dinh nghia

app.set('view engine', 'hbs');

 

// routes va render trang index

app.get('/createTables', (req, res) => {

    let models = require('./models');

    models.sequelize.sync().then(()=> {

        res.send('tables created');

    });

});

app.get('/', (req, res) => {

    res.render('index'); // se lay index.hbs do vao {{{ body }}} trong main.hbs

});

Ý nghĩa của đoạn mã:

- Đoạn mã này định nghĩa một route GET tại /createTables. Khi người dùng truy cập đường dẫn này, ứng dụng sẽ:

- Tham chiếu tới (import) các định nghĩa model từ thư mục ./models.

- Gọi phương thức sync() của Sequelize để tạo các bảng trong cơ sở dữ liệu (nếu chúng chưa tồn tại) dựa trên các model đã định nghĩa.

- Sau khi quá trình đồng bộ hóa hoàn tất thành công, ứng dụng sẽ gửi phản hồi 'tables created' về cho client (trình duyệt). Học thêm về viết hàm theo kiểu Promise (.then()).

Lưu ý: đoạn mã này thường được sử dụng trong quá trình phát triển (development) hoặc trong các thiết lập ban đầu để nhanh chóng tạo cấu trúc cơ sở dữ liệu dựa trên các model đã định nghĩa. Trong môi trường triển khai (production), việc tự động tạo hoặc cập nhật bảng theo cách này thường không được khuyến khích hoặc cần được kiểm soát chặt chẽ hơn. Việc thay đổi schema cơ sở dữ liệu trong môi trường production có thể gây ra rủi ro mất dữ liệu hoặc ngưng hệ thống (downtime). Thay vào đó, người ta thường sử dụng migrations để quản lý các thay đổi lược đồ cơ sở dữ liệu một cách an toàn và có kiểm soát.

Lưu lại tập tin mã nguồn TeoShop\index.js, khởi động lại web server, mở trình duyệt, nhập vào đường dẫn: http://localhost:9000/createTables

Nếu quá trình tạo bảng thành công, bạn sẽ thấy trên trình duyệt xuất hiện dòng chữ “tables created”; mở cửa sổ dòng lệnh trên máy server sẽ thấy xuất các dòng lệnh tạo bảng; mở cơ sở dữ liệu (teoshopDB) trong pgAdmin sẽ thấy xuất hiện bảng Products với các cột đã định nghĩa (teoshopDB\Schemas\public\Tables).

22.3 Bài tập

Bài tập 22.1 Tạo bảng Products bằng Sequelize.

-----

Cập nhật: 6/5/2025

Bài sau: Web back-end (23) - Tạo các bảng và mối quan hệ

Web back-end (21) - Lập trình với cơ sở dữ liệu

Bài trước: Web back-end (20) - Làm việc với Postgresql

-----

21 Lập trình với cơ sở dữ liệu

Như đã đề cập, để làm việc với hệ quản trị cơ sở dữ liệu (HQTCSDL), ngoài sử dụng công cụ dòng lệnh, công cụ đồ họa; chúng ta còn có thể sử dụng ngôn ngữ lập trình.

Chúng ta sẽ cùng tìm hiểu về cách sử dụng ngôn ngữ lập trình để làm việc với HQTCSDL (cũng được gọi là làm việc với cơ sở dữ liệu). 

21.1 Code first và Database first

Trong phần này, chúng ta cùng tìm hiểu về hai cách tiếp cận phổ biến khi làm việc với cơ sở dữ liệu trong phát triển ứng dụng nói chung và trong phát triển ứng dụng web nói riêng. Đó là Code first và Database first.

Cả hai đều sử dụng công cụ ORM (Object-Relational Mapping) để ánh xạ giữa mã nguồn (thường là các đối tượng trong lập trình) và cơ sở dữ liệu quan hệ.

Code first

Code first là cách tiếp cận mà bạn định nghĩa mô hình dữ liệu trong mã nguồn trước (thường là các lớp hoặc đối tượng trong ngôn ngữ lập trình), sau đó sử dụng ORM để tự động tạo hoặc cập nhật schema cơ sở dữ liệu (bảng, cột, mối quan hệ) dựa trên mã nguồn.

Database first

Database first là cách tiếp cận mà bạn thiết kế cơ sở dữ liệu trước (tạo bảng, cột, mối quan hệ bằng SQL hoặc công cụ GUI), sau đó sử dụng ORM để sinh ra các mô hình (lớp hoặc đối tượng) trong mã nguồn dựa trên schema cơ sở dữ liệu.

Chọn cách tiếp cận nào?

Để biết chúng ta nên chọn cách tiếp cận nào. Chúng ta cùng xem xét ưu và nhược điểm của mỗi cách tiếp cận.

Ưu điểm

Code first

Database first

- Tăng tốc phát triển: tập trung vào mã nguồn, không cần viết SQL thủ công.

- Linh hoạt: dễ dàng thay đổi mô hình bằng cách cập nhật mã nguồn và cập nhật hệ thống kiểm soát lược đồ dữ liệu (migration).

- Phù hợp dự án mới: thích hợp khi cơ sở dữ liệu chưa tồn tại hoặc đang được thiết kế từ đầu.

- Tích hợp tốt với ORM: tận dụng các tính năng của ORM như quản lý mối quan hệ, validation.

- Tương thích với cơ sở dữ liệu hiện có: thích hợp khi làm việc với cơ sở dữ liệu đã được thiết kế sẵn.

- Kiểm soát schema chặt chẽ: người thiết kế có thể tối ưu hóa cơ sở dữ liệu (chỉ mục, phân vùng, v.v.) trước khi tích hợp với mã nguồn.

- Phù hợp với đội ngũ lớn: phân tách trách nhiệm giữa lập trình viên back-end và người quản trị cơ sở dữ liệu.

- Đảm bảo tối ưu hóa: schema được thiết kế thủ công, tránh các vấn đề từ migration tự động.

Nhược điểm

Code first

Database first

- Khó tích hợp với cơ sở dữ liệu đã tồn tại: nếu cơ sở dữ liệu đã được thiết kế sẵn, việc ánh xạ mô hình có thể phức tạp.

- Hiệu suất: migration tự động có thể tạo schema không tối ưu (ví dụ: thiếu chỉ mục hoặc cấu hình không phù hợp).

- Phụ thuộc vào ORM: cần hiểu sâu về cách ORM ánh xạ để tránh lỗi.

- Tốn thời gian ban đầu: cần thiết kế và tạo schema bằng SQL hoặc công cụ GUI trước.

- Đồng bộ phức tạp: khi muốn thay đổi schema, yêu cầu cập nhật cơ sở dữ liệu trước, sau đó tái tạo hoặc chỉnh sửa mô hình (model).

Ít linh hoạt: không phù hợp với các dự án mà cấu trúc dữ liệu thay đổi thường xuyên.

Khi nào nên sử dụng?

Code first

Database first

- Dự án mới, chưa có cơ sở dữ liệu.

- Đội phát triển muốn kiểm soát schema thông qua mã nguồn.

- Ưu tiên phát triển nhanh và tập trung nhiều vào logic ứng dụng.

- Làm việc với cơ sở dữ liệu hiện có hoặc được thiết kế sẵn.

- Dự án có đội ngũ thiết kế dữ liệu chuyên trách, nhiều kinh nghiệm.

- Cần kiểm soát chặt chẽ schema hoặc có yêu cầu phức tạp về hiệu suất.

21.2 ORM

ORM (Object-Relational Mapping: Ánh xạ Quan hệ - Đối tượng) là một kỹ thuật (công cụ) lập trình cho phép ánh xạ giữa các đối tượng trong mã nguồn (thường là các lớp trong lập trình hướng đối tượng) và các bảng trong cơ sở dữ liệu quan hệ. 

ORM giúp lập trình viên thao tác với cơ sở dữ liệu bằng cú pháp của ngôn ngữ lập trình thay vì viết câu lệnh SQL trực tiếp, từ đó tăng hiệu suất phát triển, giảm độ phức tạp và cải thiện tính bảo trì của mã nguồn.

Một số ORM phổ biến:

- Node.js: Sequelize, TypeORM, Prisma.

- Python: Django ORM, SQLAlchemy.

- Java: Hibernate, Spring Data JPA.

- Ruby: ActiveRecord (Ruby on Rails).

- PHP: Eloquent (Laravel).

21.3 Sequelize

Trước khi cài Sequelize, là công cụ để ánh xạ các đối tượng trong mã nguồn thành các bảng trong cơ sở dữ liệu, chúng ta sẽ cài đặt 2 gói có tên là pg và pg-hstore.

Gói pg

Pg là trình điều khiển (driver) PostgreSQL phổ biến và mạnh mẽ nhất cho Node.js. Nó cung cấp một bộ API để bạn có thể kết nối đến máy chủ PostgreSQL, thực hiện các truy vấn SQL, và xử lý kết quả trả về.

Gói pg-hstore

PostgreSQL cung cấp một kiểu dữ liệu đặc biệt gọi là hstore, cho phép bạn lưu trữ các cặp khóa-giá trị (key-value) trong một cột của bảng. Điều này rất hữu ích khi bạn có các thuộc tính động hoặc bán cấu trúc mà không muốn tạo ra các cột riêng biệt cho mỗi thuộc tính.

pg-hstore là một plugin hoặc tiện ích mở rộng cho thư viện pg. Nó cung cấp khả năng:

- Chuyển đổi giữa kiểu dữ liệu hstore của PostgreSQL và các đối tượng JavaScript. Khi bạn truy vấn dữ liệu có cột kiểu hstore, pg-hstore sẽ tự động chuyển đổi giá trị hstore từ cơ sở dữ liệu thành một đối tượng JavaScript (ví dụ: { key1: 'value1', key2: 'value2' }).

- Chuyển đổi các đối tượng JavaScript thành kiểu dữ liệu hstore khi bạn chèn hoặc cập nhật dữ liệu. Khi bạn muốn lưu trữ dữ liệu dưới dạng hstore từ ứng dụng Node.js, pg-hstore sẽ chuyển đổi đối tượng JavaScript của bạn thành định dạng hstore mà PostgreSQL có thể hiểu được.

Cài đặt: pg và pg-hstore:

- Mở cửa sổ dòng lệnh, di chuyển dấu nhắc chuột vào thư mục dự án (TeoShop)

- Nhập lệnh: E:\TeoShop>pnpm i -s pg pg-hstore

- Mở tập tin package.json để kiểm tra xem việc cài đặt pg và pg-hstore được chưa. Nếu có thông tin của 2 gói này trong mục dependencies là đã cài đặt thành công.

Cài đặt sequelize

- Mở cửa sổ dòng lệnh, di chuyển dấu nhắc chuột vào thư mục dự án (TeoShop)

- Nhập lệnh: E:\TeoShop>pnpm i -s sequelize

- Mở tập tin package.json để kiểm tra xem việc cài đặt sequelize được chưa. Nếu có thông tin của sequelize trong mục dependencies là đã cài đặt thành công.

Cài đặt sequelize-cli

- sequelize-cli là công cụ dòng lệnh (cli - command line interface) để ra lệnh cho sequelize

- Cài ở chế độ global

- Nhập lệnh: E:\TeoShop>npm i g sequelize-cli

E:\TeoShop>npm i -g sequelize-cli

 added 100 packages in 21s

 18 packages are looking for funding

  run `npm fund` for details

npm notice

npm notice New major version of npm available! 10.9.2 -> 11.3.0

npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.3.0

npm notice To update run: npm install -g npm@11.3.0

npm notice

- Mở tập tin package.json sẽ không thấy thông tin gì về sequelize-cli. Vì cài đặt global nên bạn cần vào C:\Users\Teo\AppData\Roaming\npm\node_modules, bạn sẽ thấy được gói sequelize-cli.

21.4 Sử dụng sequelize

Lệnh sequelize init

Lệnh sequelize init được sử dụng để khởi tạo cấu trúc thư mục và các tập tin cấu hình cần thiết cho một dự án có sử dụng sequelize.

Khi bạn chạy lệnh sequelize init trong thư mục gốc của dự án Node.js, Sequelize-CLI sẽ tạo ra các thư mục và tập tin sau:

- config/config.json (hoặc config/config.js tùy thuộc vào cấu hình): tập tin này chứa các cấu hình kết nối đến cơ sở dữ liệu cho các môi trường khác nhau (development, test, production). Bạn sẽ cần chỉnh sửa tập tin này để cung cấp thông tin đăng nhập và chi tiết kết nối đến cơ sở dữ liệu bạn muốn sử dụng (ví dụ: PostgreSQL, MySQL, SQLite, SQL Server).

- models/: thư mục này sẽ chứa các tập tin định nghĩa model của bạn. Mỗi tập tin model thường tương ứng với một bảng trong cơ sở dữ liệu. Bạn sẽ định nghĩa tên bảng, các cột, kiểu dữ liệu, và các ràng buộc trong các tập tin này.

- migrations/: thư mục này sẽ chứa các tập tin migration. Migration là các tập tin JavaScript chứa mã nguồn để thực hiện các thay đổi lược đồ cơ sở dữ liệu theo thời gian (ví dụ: tạo bảng, thêm cột, sửa đổi cột). Sequelize-CLI cung cấp các lệnh để tạo, chạy và rollback các migration.

- seeders/: thư mục này sẽ chứa các tập tin seeder. Seeder là các tập tin JavaScript chứa mã nguồn để chèn dữ liệu mẫu ban đầu vào cơ sở dữ liệu (ví dụ: tạo các tài khoản người dùng quản trị ban đầu, thêm các danh mục sản phẩm mặc định). Sequelize-CLI cũng cung cấp các lệnh để chạy các seeder.

21.5 Bài tập

Câu hỏi 21.1 Phát biểu nào sau đây KHÔNG đúng về Code First và Database First trong lập trình với cơ sở dữ liệu?

A. Code First là phương pháp định nghĩa mô hình dữ liệu trong mã nguồn trước, sau đó ORM sẽ tạo hoặc cập nhật schema cơ sở dữ liệu.

B. Database First là phương pháp thiết kế cơ sở dữ liệu trước, sau đó ORM sẽ sinh ra các mô hình trong mã nguồn dựa trên schema đã có.

C. Cả Code First và Database First đều bỏ qua vai trò của ORM và cho phép lập trình viên tương tác trực tiếp với cơ sở dữ liệu bằng SQL.

D. Code First thường phù hợp với các dự án mới, trong khi Database First thích hợp với các dự án làm việc trên cơ sở dữ liệu đã tồn tại.

Câu hỏi 21.2 Phát biểu nào sau đây KHÔNG đúng về ORM (Object-Relational Mapping)?

A. ORM là một kỹ thuật lập trình giúp ánh xạ giữa các đối tượng trong mã nguồn và các bảng trong cơ sở dữ liệu quan hệ.

B. ORM làm tăng độ phức tạp của mã nguồn và giảm hiệu suất phát triển ứng dụng.

C. ORM cho phép lập trình viên thao tác với cơ sở dữ liệu bằng cú pháp của ngôn ngữ lập trình thay vì viết câu lệnh SQL trực tiếp.

D. Sequelize (Node.js) và Django ORM (Python) là những ví dụ về các ORM phổ biến

Câu hỏi 21.3 Bốn thư mục chính được tạo ra bởi lệnh sequelize init là config, models, migrations, và seeders. Phát biểu nào sau đây về mục đích của các thư mục này là KHÔNG đúng?

A. Thư mục migrations chứa các tập tin SQL script để thực hiện các thay đổi lược đồ cơ sở dữ liệu theo thời gian.

B. Thư mục config chứa các tập tin cấu hình kết nối đến cơ sở dữ liệu cho các môi trường phát triển, kiểm thử và sản xuất.

C. Thư mục models chứa các tập tin định nghĩa cấu trúc các bảng trong cơ sở dữ liệu dưới dạng các model (lớp) JavaScript.

D. Thư mục seeders chứa các tập tin JavaScript để chèn dữ liệu mẫu ban đầu vào cơ sở dữ liệu.

Bài tập 21.4 Cài đặt các gói trong bài học.

-----

Cập nhật: 5/5/2025

Bài sau: Web back-end (22) - Tạo cơ sở dữ liệu bằng Sequelize