- Câu lệnh SELECT cơ bản trong SQL như thế nào?
Mẹo hiểu SELECT: SQL không chạy theo thứ tự bạn viết, mà theo thứ tự thực thi: FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT Hệ quả quan trọng: alias đặt trong SELECT (vd…
- INSERT, UPDATE, DELETE trong SQL hoạt động như thế nào?
Ba lệnh cốt lõi để thay đổi dữ liệu. Vài kỹ thuật hữu ích: - Bulk INSERT (một round-trip thay vì N, nhanh hơn nhiều với lượng lớn): - RETURNING (PostgreSQL): lấy giá trị vừa sinh ra ngay, khỏi query lại — INSERT INTO users…
- ER Diagram (Entity-Relationship Diagram) là gì? Các thành phần chính?
ER Diagram là bản vẽ schema trước khi code — như bản vẽ nhà trước khi xây, giúp tránh phải đập đi sửa lại tốn kém. Ba thành phần chính: - Entity (thực thể = bảng): vẽ hình chữ nhật. - Attribute (thuộc tính =…
- Cascade trong foreign key constraint là gì? ON DELETE CASCADE hoạt động thế nào?
CASCADE quy định "khi xoá/sửa dòng cha thì làm gì với dòng con". Các lựa chọn ON DELETE: - CASCADE: xoá cha → tự xoá luôn con (xoá user → mất hết order, comment, session). Tiện nhưng nguy hiểm nếu đặt nhầm. - SET NULL:…
- UUID vs Auto-increment ID: khi nào nên dùng loại nào?
Hai cách sinh khoá chính: - Auto-increment (SERIAL/BIGSERIAL): số tăng dần, nhỏ gọn (4/8 byte), index B-tree gọn, dễ debug. Nhược: lộ thông tin (đối thủ đoán được số bản ghi qua id), và không an toàn cho hệ phân tán vì cần bộ đếm…
- Database migration là gì? Tại sao quan trọng trong CI/CD?
- So sánh MongoDB và PostgreSQL: khi nào chọn cái nào?
Không phải "cái nào tốt hơn" mà là "hợp với dữ liệu nào". Chọn PostgreSQL khi: dữ liệu có quan hệ rõ, cần transaction ACID, schema ổn định, query phức tạp nhiều JOIN. PostgreSQL còn có kiểu JSONB (+ GIN index) cho phép lưu/truy vấn…
- ORM (Object-Relational Mapper) là gì? Lợi ích và nhược điểm?
ORM là lớp trung gian ánh xạ bảng DB thành object trong code, để bạn thao tác bằng ngôn ngữ lập trình thay vì viết SQL tay. Hai phong cách: Active Record (model tự chứa logic DB — Rails, Sequelize) và Data Mapper (tách object…
- Prisma ORM là gì? Tại sao phổ biến trong Node.js/TypeScript ecosystem?
Prisma là ORM thế hệ mới cho Node.js/TypeScript, theo hướng schema-first: bạn mô tả model trong schema.prisma, Prisma sinh ra mọi thứ từ đó. Điểm mạnh: - Client tự sinh, type-safe: mỗi lần chạy prisma generate tạo ra TypeScript types khớp chính xác với schema…
- Prisma schema file hoạt động như thế nào?
schema.prisma là source of truth duy nhất của Prisma, gồm ba phần: - datasource: kết nối DB. - generator: cấu hình Prisma Client. - models: định nghĩa bảng và quan hệ. Vài cú pháp hay dùng: - Quan hệ: @relation(fields: [authorId], references: [id]) cho khoá…
- Sequelize là gì? So sánh với Prisma?
Sequelize là ORM "đời trước" của Node.js, lâu đời và hỗ trợ nhiều DB (MySQL, PostgreSQL, SQLite, MSSQL, MariaDB). Vài tính năng đáng biết: - Migration: sequelize-cli sinh file có up/down — mạnh nhưng dài dòng. - Hooks (sự kiện vòng đời): beforeCreate, afterCreate, beforeUpdate...…
- Mongoose là gì? Schema trong Mongoose hoạt động như thế nào?
Mongoose là ODM (Object Document Mapper) cho MongoDB — thêm schema, validation và middleware lên trên MongoDB vốn không ràng buộc cấu trúc. Vài khái niệm cốt lõi: - Middleware (hooks): chạy quanh thao tác — pre/post save, pre/post find... Dùng cho audit log, hash…
- Khi nào nên dùng Redis làm cache?
Dùng Redis làm cache khi: dữ liệu đọc nhiều hơn ghi, tính toán tốn kém (query DB phức tạp, gọi API), cần giảm tải DB, và chấp nhận dữ liệu cũ trong chốc lát. Vài chiến lược cache: - Cache-aside (phổ biến nhất): xem cache…
- Database transactions trong Prisma: cách sử dụng?
- Drizzle ORM là gì? So sánh với Prisma?
Drizzle là ORM TypeScript nhẹ, query builder viết gần giống SQL nhưng vẫn type-safe — hợp người đã quen SQL: Schema khai báo bằng TypeScript, tự suy ra type: pgTable('users', { id: serial('id').primaryKey(), name: text('name').notNull() }). Migration qua drizzle-kit generate / push. Khác biệt lớn…
- Mô hình quan hệ (relational model) là gì? Table, row, column, quan hệ ra sao?
Mô hình quan hệ tổ chức dữ liệu thành các bảng (relation): - Column (attribute): một trường có kiểu dữ liệu xác định (int, text, timestamp...). - Row (tuple): một bản ghi — một thực thể cụ thể. - Table: tập các row cùng cấu…
- Phân biệt primary key, foreign key, unique key và composite key?
- Primary key (PK): định danh duy nhất mỗi hàng; không NULL, mỗi bảng chỉ một PK. Thường có index tự động. - Unique key: đảm bảo giá trị không trùng, nhưng cho phép NULL và một bảng có nhiều unique constraint. - Foreign key…
- Chuẩn hoá (normalization) là gì? Giải thích 1NF, 2NF, 3NF.
Chuẩn hoá là việc tổ chức bảng để giảm dư thừa và tránh bất thường khi thêm/sửa/xoá (update anomaly). - 1NF: mỗi ô chứa một giá trị atomic, không có nhóm lặp hay mảng trong cột; mỗi hàng là duy nhất. - 2NF: đạt 1NF…
- Denormalization là gì và khi nào nên chấp nhận dữ liệu dư thừa?
Denormalization là việc cố ý thêm dữ liệu dư thừa (nhân bản cột, lưu giá trị đã tính sẵn) để giảm số JOIN và tăng tốc đọc. Đánh đổi: - Lợi: đọc nhanh hơn (ít JOIN/aggregate lúc query), hợp báo cáo/analytics đọc nhiều. - Hại:…
- ACID là gì? Giải thích từng thuộc tính.
ACID là bốn đảm bảo cho transaction — nhóm thao tác chạy như một đơn vị: - Atomicity: toàn bộ thành công hoặc rollback hết, không có nửa vời. - Consistency (nhất quán): transaction đưa DB từ trạng thái hợp lệ này sang trạng thái…
- Transaction hoạt động thế nào (BEGIN/COMMIT/ROLLBACK) và savepoint dùng làm gì?
Một transaction bọc nhiều câu lệnh thành một đơn vị atomic: - BEGIN (hoặc START TRANSACTION): mở transaction. - COMMIT: xác nhận, làm mọi thay đổi bền vững và hiển thị cho transaction khác. - ROLLBACK: huỷ toàn bộ thay đổi từ khi BEGIN, DB…
- Các mức isolation và những hiện tượng (anomaly) mỗi mức ngăn được?
- Phân biệt dirty read, non-repeatable read và phantom read.
- B-tree index hoạt động thế nào? Vì sao tra cứu nhanh?
Index là cấu trúc dữ liệu có thứ tự giữ giá trị cột đã sắp xếp + con trỏ tới hàng thật. Loại phổ biến nhất là B-tree (cây cân bằng): - Root → branch → leaf: cây cân bằng nên mọi leaf ở cùng…
- Khi nào nên thêm index và khi nào không nên?
Nên index khi cột: - Xuất hiện trong WHERE, JOIN, ORDER BY, GROUP BY của truy vấn chạy thường xuyên. - Có độ chọn lọc (selectivity) cao — nhiều giá trị phân biệt (email, userid) nên index lọc bỏ được nhiều hàng. - Là foreign…
- Composite index là gì và thứ tự cột (leftmost prefix) quan trọng thế nào?
- Covering index / index-only scan là gì?
- EXPLAIN dùng để làm gì? Đọc query plan như thế nào?
EXPLAIN cho xem kế hoạch thực thi mà planner chọn cho một truy vấn; EXPLAIN ANALYZE còn chạy thật và báo thời gian + số hàng thực tế (cẩn thận với UPDATE/DELETE trên production — nó thực sự ghi). cost chỉ là ước lượng tương…
- N+1 query problem là gì và khắc phục ra sao?
N+1 xảy ra khi lấy một danh sách rồi lặp gọi thêm một truy vấn riêng cho từng phần tử: 1 query lấy N bản ghi cha + N query lấy dữ liệu con → N+1 lần vào DB. Thường gặp với ORM khi truy…
- Các loại JOIN (INNER, LEFT, RIGHT, FULL, CROSS) khác nhau thế nào?
JOIN ghép hàng của hai bảng theo điều kiện (thường qua khoá): - INNER JOIN: chỉ giữ hàng khớp cả hai bên. Hàng không có cặp bị loại. - LEFT (OUTER) JOIN: giữ mọi hàng bảng trái, bên phải không khớp thì điền NULL. -…
- View và materialized view khác nhau thế nào?
- View: một truy vấn lưu sẵn dưới dạng tên gọi — không lưu dữ liệu. Mỗi lần query view, DB chạy lại câu SQL bên dưới trên dữ liệu hiện tại → luôn mới, không tốn storage, nhưng nặng nếu truy vấn phức tạp…
- SQL và NoSQL khác nhau ở đâu?
SQL (quan hệ): dữ liệu ở bảng, schema cố định, quan hệ qua PK/FK, ngôn ngữ SQL chuẩn hoá, đảm bảo ACID mạnh, thường scale dọc (máy mạnh hơn). Hợp dữ liệu có cấu trúc rõ và ràng buộc chặt (tài chính, đơn hàng). NoSQL:…
- Các loại NoSQL (document, key-value, wide-column, graph) và ví dụ?
Bốn họ NoSQL chính, khác nhau ở mô hình dữ liệu: - Document: lưu tài liệu tự mô tả (JSON/BSON), schema linh hoạt; hợp catalog, profile, nội dung. Vd MongoDB, Couchbase. - Key-value: ánh xạ khoá → giá trị, đọc/ghi cực nhanh theo khoá; hợp…
- Khi nào chọn SQL, khi nào chọn NoSQL?
Chọn theo mô hình truy vấn + yêu cầu nhất quán + cách scale, không theo trào lưu. Chọn SQL khi: - Dữ liệu có cấu trúc rõ, quan hệ nhiều, cần JOIN linh hoạt. - Cần giao dịch ACID và nhất quán mạnh (thanh…
- Connection pooling là gì và vì sao cần?
Mở một kết nối DB tốn kém: bắt tay TCP, xác thực, cấp phát tài nguyên server. Nếu mỗi request lại mở rồi đóng kết nối thì độ trễ cao và DB dễ cạn kết nối. Connection pool giữ sẵn một tập kết nối mở,…
- Replication (leader/follower) là gì và giải quyết vấn đề gì?
Replication là nhân bản dữ liệu ra nhiều node. Mô hình phổ biến là leader–follower (primary–replica): - Leader nhận mọi ghi (write), ghi vào WAL rồi stream thay đổi tới các follower. - Follower áp lại thay đổi, phục vụ đọc (read). Giải quyết: -…
- Read replica là gì? Replication lag ảnh hưởng thế nào?
Read replica là bản sao chỉ-đọc của DB chính, dùng để chia tải đọc khỏi node ghi. Ứng dụng gửi INSERT/UPDATE/DELETE tới primary, còn các SELECT chịu được dữ liệu hơi cũ thì định tuyến sang replica → primary rảnh hơn, hệ chịu tải đọc…
- Sharding là gì? Khác gì với replication?
- Partitioning là gì? Phân biệt horizontal và vertical partitioning.
- Optimistic locking và pessimistic locking khác nhau thế nào?
- Deadlock là gì, do đâu và làm sao tránh?
- MVCC là gì và giải quyết vấn đề gì?
- VACUUM trong PostgreSQL làm gì và vì sao cần?
- JSONB trong PostgreSQL là gì? Khác JSON thường thế nào?
Postgres có hai kiểu lưu JSON: - json: lưu nguyên văn text, giữ nguyên khoảng trắng/thứ tự khoá/khoá trùng; mỗi lần truy vấn phải parse lại → ghi nhanh, đọc/thao tác chậm. - jsonb: lưu dạng nhị phân đã parse, bỏ khoảng trắng, không giữ…
- WAL (Write-Ahead Logging) là gì và đảm bảo điều gì?
- MongoDB lưu dữ liệu thế nào? Document, collection, BSON là gì?
MongoDB là document database: - Document: đơn vị dữ liệu dạng JSON (cặp field–value), có thể lồng nhau (object, array). Mỗi document có id làm khoá chính (mặc định là ObjectId). - Collection: nhóm các document — tương đương "bảng" nhưng không bắt schema cố…
- Aggregation pipeline trong MongoDB hoạt động thế nào?
Aggregation pipeline xử lý document qua một chuỗi stage, mỗi stage biến đổi luồng document rồi truyền sang stage kế — như pipeline, giống GROUP BY/JOIN/biến đổi trong SQL nhưng theo từng bước. Các stage hay dùng: - $match: lọc (như WHERE) — đặt sớm…
- Index trong MongoDB có những loại nào?
Cũng như DB quan hệ, MongoDB dùng B-tree index để tránh quét toàn collection (COLLSCAN). Mọi collection có sẵn index trên id. Các loại chính: - Single field: index một field. - Compound: nhiều field theo thứ tự — áp dụng leftmost prefix như SQL;…
- Replica set trong MongoDB là gì?
Replica set là nhóm các node MongoDB giữ cùng dữ liệu để đảm bảo khả dụng cao: - Primary: node duy nhất nhận ghi; ghi được ghi vào oplog (operation log). - Secondary: sao chép oplog của primary và áp lại → giữ bản sao,…
- Sharding trong MongoDB hoạt động thế nào?
- Trong MongoDB, khi nào nên embed và khi nào nên reference?
MongoDB có hai cách mô hình quan hệ giữa dữ liệu: Embedding (nhúng): đặt dữ liệu con bên trong document cha (mảng/object lồng). - Ưu: đọc tất cả trong một lần truy vấn, không cần join; ghi atomic ở cấp một document. - Hợp: quan…
- Làm sao migration schema mà không downtime?
- Một truy vấn chạy chậm — bạn chẩn đoán và tối ưu thế nào?
- Vì sao cần tầng cache và có những chiến lược nào?
Cache giữ dữ liệu hay dùng ở tầng nhanh (RAM, vd Redis) → giảm tải DB, giảm độ trễ đọc, chịu tải cao hơn. Hợp dữ liệu đọc nhiều-ghi ít, tốn công tính, hoặc chấp nhận hơi cũ. Chiến lược đọc/ghi: - Cache-aside (lazy loading):…
- CAP theorem là gì và áp dụng cho database thế nào?
- Eventual consistency là gì? Khi nào chấp nhận được?
- Ngoài B-tree, PostgreSQL còn loại index nào và dùng khi nào?
- OLTP và OLAP khác nhau thế nào?
Hai loại workload dữ liệu, tối ưu cho mục đích khác nhau: OLTP (Online Transaction Processing) — hệ giao dịch chạy ứng dụng: - Nhiều giao dịch nhỏ, nhanh: đọc/ghi vài hàng (đặt đơn, cập nhật hồ sơ). - Cần ACID, độ trễ thấp, đồng…
- Clustered index và non-clustered index khác nhau thế nào?
- Vì sao phân trang bằng OFFSET chậm? Keyset pagination là gì?
OFFSET/LIMIT (LIMIT 20 OFFSET 100000) buộc DB quét và bỏ đi toàn bộ hàng trước offset rồi mới trả 20 hàng → càng lật sâu càng chậm (chi phí tăng tuyến tính theo offset). Thêm rủi ro: nếu dữ liệu chèn/xoá giữa các lần lật,…
- Surrogate key và natural key — nên chọn cái nào làm primary key?
- Natural key: khoá lấy từ dữ liệu nghiệp vụ thật có sẵn ý nghĩa (email, số CMND, mã sản phẩm, countrycode). - Surrogate key: khoá nhân tạo, không mang nghĩa nghiệp vụ, sinh riêng để định danh — SERIAL/IDENTITY (số tăng), UUID, hoặc ObjectId…
- DELETE, TRUNCATE và DROP khác nhau thế nào?
- DELETE: xoá hàng theo điều kiện (DELETE FROM t WHERE ...), có thể xoá một phần. Là DML, ghi log từng hàng, chạy trong transaction (rollback được), kích hoạt trigger, chịu ràng buộc FK. Xoá nhiều hàng thì chậm và để lại dead tuple…
- GROUP BY, hàm tổng hợp và HAVING vs WHERE khác nhau thế nào?
Hàm tổng hợp (aggregate) gộp nhiều hàng thành một giá trị: COUNT, SUM, AVG, MIN, MAX. GROUP BY chia hàng thành các nhóm theo cột, rồi hàm tổng hợp tính trên từng nhóm. Vd doanh thu theo từng khách: Quy tắc: mọi cột trong SELECT…
- CTE (WITH) là gì và khác subquery thế nào?
CTE (Common Table Expression) là truy vấn phụ đặt tên khai báo bằng WITH, dùng lại như một bảng tạm trong câu lệnh chính: So với subquery lồng trong FROM/WHERE: - CTE giúp truy vấn phức tạp dễ đọc, chia thành các bước có tên,…
- Tìm kiếm văn bản: LIKE và full-text search khác nhau thế nào?
- LIKE / ILIKE: khớp mẫu chuỗi đơn giản. col LIKE '%from%' với % ở đầu không dùng được B-tree index → quét toàn bảng, chậm trên dữ liệu lớn. Không hiểu ngôn ngữ: không phân biệt gốc từ, thứ hạng, dấu câu. - Full-text…
- SQL gồm những nhóm lệnh nào (DDL, DML, DCL, TCL)?
SQL được chia thành các nhóm lệnh theo mục đích: - DDL (Data Definition Language) — định nghĩa cấu trúc: CREATE, ALTER, DROP, TRUNCATE. Tác động lên schema (bảng, index, ràng buộc). - DML (Data Manipulation Language) — thao tác dữ liệu bên trong bảng:…
- NULL trong SQL nghĩa là gì? Logic ba giá trị (three-valued logic) là sao?
NULL biểu thị giá trị chưa biết / không tồn tại, khác hẳn số 0 hay chuỗi rỗng ''. Vì "chưa biết", SQL dùng logic ba giá trị: mọi so sánh cho ra TRUE, FALSE, hoặc UNKNOWN. Hệ quả thực tế: - NULL = NULL…
- UNION và UNION ALL khác nhau thế nào? Còn INTERSECT/EXCEPT?
Các phép hợp tập hợp gộp kết quả của hai SELECT (phải cùng số cột và kiểu tương thích) theo chiều dọc: - UNION: gộp rồi loại bỏ hàng trùng → phải sắp xếp/băm để khử trùng nên tốn thêm chi phí. - UNION ALL:…
- Chọn kiểu dữ liệu chuỗi thế nào: CHAR, VARCHAR, TEXT?
Ba kiểu chuỗi thường gặp: - CHAR(n) — độ dài cố định, luôn chiếm n ký tự (đệm khoảng trắng nếu ngắn hơn). Phần đệm là một phần của giá trị và theo nó ra tới ứng dụng — riêng MySQL cắt khoảng trắng cuối…
- Các loại quan hệ (1–1, 1–nhiều, nhiều–nhiều) mô hình ra sao? Bảng nối là gì?
Ba loại quan hệ (cardinality) giữa hai thực thể và cách hiện thực bằng khoá: - Một–một (1:1): mỗi hàng bên A ứng với tối đa một hàng bên B (user ↔ hồ sơ chi tiết). Hiện thực: đặt FK có ràng buộc UNIQUE ở…
- Self join là gì và khi nào dùng?
Self join là ghép một bảng với chính nó — dùng hai bí danh (alias) khác nhau cho cùng bảng như thể là hai bảng riêng. Dùng khi các hàng trong cùng một bảng có quan hệ với nhau. Ví dụ kinh điển — quan…
- Subquery và correlated subquery khác nhau thế nào?
Subquery là truy vấn lồng bên trong truy vấn khác (ở SELECT, FROM, hoặc WHERE). - Subquery độc lập (non-correlated): chạy được một mình, không tham chiếu truy vấn ngoài. DB thường chạy một lần, lấy kết quả rồi dùng cho truy vấn ngoài. -…
- Window function là gì? Khác GROUP BY thế nào?
Window function tính toán trên một tập hàng liên quan tới hàng hiện tại nhưng không gộp các hàng lại — mỗi hàng gốc vẫn được giữ, kèm thêm giá trị tính được. Nhận biết qua mệnh đề OVER (...). Khác GROUP BY: - GROUP…
- Redis là gì? Có những kiểu dữ liệu nào và dùng cho việc gì?
Redis là kho dữ liệu key–value in-memory (lưu chủ yếu trong RAM) → đọc/ghi cực nhanh (thường dưới 1ms). Điểm mạnh là nó không chỉ lưu chuỗi mà là "data structure server" với nhiều kiểu dữ liệu có sẵn: - String: giá trị đơn (cache…
- BASE là gì và khác ACID thế nào?
BASE là triết lý nhất quán của nhiều hệ NoSQL/phân tán, đặt cạnh ACID của DB quan hệ như một sự đánh đổi. BASE viết tắt: - Basically Available: hệ luôn phản hồi cho request (ưu tiên khả dụng), dù có thể là dữ liệu…
- Stored procedure và trigger là gì? Ưu nhược điểm?
- Stored procedure: một khối code (SQL + logic thủ tục như PL/pgSQL) lưu và chạy bên trong DB, gọi theo tên (CALL proc(...)). Gói nhiều câu lệnh thành một đơn vị chạy sát dữ liệu. - Trigger: code tự động chạy khi có sự…
- Vì sao nên tránh SELECT * trong code production?
SELECT lấy mọi cột của bảng. Tiện lúc khám phá dữ liệu, nhưng trong code chạy thật gây nhiều vấn đề: - Truyền dữ liệu thừa: kéo cả cột không cần (blob, text lớn) → tốn băng thông, RAM, và I/O. - Chặn index-only scan:…
- UPSERT (INSERT ... ON CONFLICT) là gì và giải quyết vấn đề gì?
UPSERT = "insert nếu chưa có, update nếu đã có" trong một câu lệnh atomic. Tránh mẫu sai thường gặp "kiểm tra trước rồi ghi" (SELECT → nếu không có thì INSERT), vốn dính race condition: hai request cùng thấy "chưa có" rồi cùng INSERT…
- Soft delete và hard delete khác nhau thế nào? Khi nào dùng?
- Hard delete: DELETE thật, xoá hẳn hàng khỏi bảng. Dữ liệu biến mất. - Soft delete: không xoá mà đánh dấu đã xoá — thêm cột deletedat TIMESTAMP (tốt hơn isdeleted BOOLEAN vì ghi lại cả thời điểm xoá); mọi truy vấn "còn sống"…
- Vì sao không nên lưu tiền tệ bằng float? Dùng kiểu gì?
Số dấu phẩy động (float, double, real) lưu theo chuẩn nhị phân IEEE 754 → nhiều giá trị thập phân không biểu diễn chính xác được (kinh điển 0.1 + 0.2 !== 0.3). Với tiền tệ, sai số nhỏ tích luỹ qua nhiều phép cộng/nhân…
- Giao dịch phân tán: two-phase commit (2PC) và Saga pattern là gì?
- B-tree và LSM-tree khác nhau thế nào? Vì sao NoSQL ghi-nhiều hay dùng LSM?
- Star schema và snowflake schema khác nhau thế nào (mô hình chiều)?
- Chiến lược backup: full/incremental, PITR và RPO/RTO nghĩa là gì?
- Consistent hashing là gì và giải quyết vấn đề gì trong sharding/cache?
- MySQL và PostgreSQL khác nhau ở đâu? Khi nào chọn cái nào?
Cả hai là RDBMS mã nguồn mở phổ biến nhất, nhưng khác về kiến trúc và trọng tâm: - Kiến trúc kết nối: MySQL dùng thread cho mỗi kết nối (nhẹ RAM); PostgreSQL dùng process riêng cho mỗi kết nối (tốn RAM hơn khi kết…
- Thiết kế luồng trừ tồn kho / đặt vé chống race condition thế nào?
- Bài tập SQL thường gặp: tìm lương cao thứ 2 / top-N mỗi nhóm viết thế nào?
Hai bài "vào tay" xuất hiện trong hầu hết vòng SQL: Lương cao thứ 2 (phải xử lý trùng lương và trường hợp không tồn tại): Dùng DENSERANK (không phải ROWNUMBER/RANK) vì lương trùng phải tính cùng một hạng, không nhảy số. Biến thể LIMIT…
- SQL injection là gì? Vì sao parameterized query chặn được?
SQL injection là lỗ hổng khi input của user được nối chuỗi thẳng vào câu SQL, khiến dữ liệu bị thực thi như code: Hậu quả: lộ dữ liệu (bypass đăng nhập, đọc bảng khác qua UNION SELECT), sửa/xoá dữ liệu, có khi chiếm cả…
- Thiết kế schema đơn hàng e-commerce (orders / order_items) thế nào?
Bài thiết kế kinh điển — lõi là cặp bảng orders + orderitems (quan hệ user–product là nhiều–nhiều qua đơn hàng): Các quyết định phải giải thích được: - unitprice snapshot: giá lưu ngay trong orderitems, KHÔNG join sang products.price — giá sản phẩm đổi…
- EXISTS, IN và NOT EXISTS khác nhau thế nào? Khi nào dùng cái nào?
- IN so giá trị với một danh sách hoặc kết quả subquery: x IN (SELECT ...). Hợp khi danh sách nhỏ, giá trị cụ thể. - EXISTS kiểm tra "có tồn tại ít nhất một dòng khớp không" và dừng ngay khi tìm thấy…
- RANK(), DENSE_RANK() và ROW_NUMBER() khác nhau thế nào?
Cả ba là window function đánh số theo ORDER BY trong mỗi partition. Khác nhau khi gặp giá trị bằng nhau (ties): - ROWNUMBER(): đánh số liên tục duy nhất 1, 2, 3, 4... kể cả khi bằng nhau (thứ tự giữa các dòng bằng…
- Super key, candidate key, primary key và composite key khác nhau thế nào?
Các khái niệm khoá đều xoay quanh việc định danh duy nhất một dòng: - Super key: bất kỳ tập cột nào xác định duy nhất một dòng — có thể thừa (kèm thêm cột không cần thiết). - Candidate key: super key tối giản…
- DBMS và RDBMS khác nhau thế nào?
- DBMS (Database Management System): phần mềm quản lý dữ liệu nói chung — lưu, truy vấn, quản trị. Bao hàm mọi mô hình: file phẳng, phân cấp, mạng, quan hệ, tài liệu... - RDBMS (Relational DBMS): một loại DBMS theo mô hình quan hệ…
- B-tree và B+ tree khác nhau thế nào, và vì sao index database thường dùng B+ tree?
- Làm sao ánh xạ mô hình ER (thực thể - quan hệ) sang lược đồ quan hệ (bảng)?
Các quy tắc ánh xạ cơ bản: - Thực thể (entity) → một bảng; thuộc tính → cột; khoá của thực thể → primary key. - Thuộc tính đa trị (multi-valued) → tách ra một bảng riêng nối bằng foreign key. - Quan hệ 1–1:…
- Thứ tự thực thi logic của một câu SELECT là gì? Vì sao nó khác thứ tự bạn viết?
Câu SELECT được viết theo thứ tự SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY, nhưng được hiểu theo logic gần như ngược lại: 1. FROM + JOIN — dựng tập dòng nguồn. 2. WHERE — lọc từng dòng thô.…
- Vì sao không dùng được alias của cột trong `WHERE` nhưng lại dùng được trong `ORDER BY`?
Vì WHERE được đánh giá trước SELECT, còn ORDER BY được đánh giá sau. Khi WHERE chạy, alias chưa được tạo ra. Ba cách sửa cho WHERE: Lặp lại biểu thức không làm chậm truy vấn: optimizer chỉ tính một lần. GROUP BY nằm giữa…
- `COUNT(*)`, `COUNT(col)` và `COUNT(DISTINCT col)` khác nhau thế nào? `SUM`/`AVG` xử lý NULL ra sao?
Khác nhau ở chỗ NULL có được đếm hay không: - COUNT() — đếm số dòng, kể cả dòng toàn NULL. - COUNT(col) — đếm số dòng có col IS NOT NULL. - COUNT(DISTINCT col) — đếm số giá trị khác nhau, bỏ NULL. Mọi…
- `COALESCE` và `NULLIF` dùng để làm gì? Cho ví dụ thực tế.
COALESCE(a, b, c, ...) trả về đối số không NULL đầu tiên — dùng để đặt giá trị mặc định. NULLIF(a, b) trả về NULL nếu a = b, ngược lại trả về a — dùng để biến một giá trị "xấu" thành NULL. Cặp…
- Vì sao `NOT IN` với subquery chứa NULL luôn trả về rỗng? Sửa thế nào?
Vì NOT IN được khai triển thành chuỗi AND các phép khác (<), mà so sánh với NULL cho ra UNKNOWN chứ không phải TRUE/FALSE. Chỉ cần một NULL trong danh sách là toàn bộ điều kiện không bao giờ TRUE → không dòng nào…
- Vì sao `LEFT JOIN` của tôi lại hành xử như `INNER JOIN`? Điều kiện nên đặt ở `ON` hay `WHERE`?
Vì điều kiện lọc bảng bên phải bị đặt nhầm vào WHERE thay vì ON. LEFT JOIN sinh ra các dòng có cột bên phải toàn NULL; sau đó WHERE chạy và loại chính những dòng NULL đó → còn lại đúng bằng INNER JOIN.…
- Vì sao JOIN nhiều bảng rồi `SUM` lại ra số lớn gấp đôi? Xử lý fan-out thế nào?
Vì JOIN quan hệ một–nhiều làm nhân bản dòng ở bảng cha. Mỗi lần bảng cha xuất hiện thêm một dòng thì giá trị của nó bị cộng thêm một lần. Ba cách chữa: Cách 3 chỉ cứu được COUNT, không cứu được SUM —…
- Vì sao phân trang bằng `ORDER BY created_at LIMIT/OFFSET` lại bị lặp hoặc mất dòng?
Vì ORDER BY không xác định (non-deterministic) khi nhiều dòng có cùng giá trị sắp xếp. SQL không đảm bảo giữ nguyên thứ tự giữa các dòng bằng nhau, nên hai lần chạy có thể xếp chúng khác nhau — dòng ở cuối trang 1…
- Dùng `LAG`/`LEAD` để tính tăng trưởng doanh thu so với tháng trước như thế nào?
LAG(col, n) lấy giá trị của dòng trước trong cùng partition, LEAD(col, n) lấy dòng sau. Nhờ đó so sánh kỳ này với kỳ trước mà không cần self join. Ba điểm hay bị hỏi thêm: - Dòng đầu tiên không có dòng trước →…
- `GROUPING SETS`, `ROLLUP`, `CUBE` là gì? Khi nào dùng thay vì `UNION ALL` nhiều truy vấn?
Chúng cho phép tính nhiều mức tổng hợp trong một lần quét bảng, thay vì viết nhiều GROUP BY rồi UNION ALL. - GROUPING SETS ((a,b), (a), ()) — liệt kê tường minh các tổ hợp cần gom. - ROLLUP(a, b) — tổng theo cấp…
- Tính running total bằng window function thế nào? `ROWS` và `RANGE` trong frame clause khác nhau ra sao?
- Index làm truy vấn đọc nhanh hơn nhưng vì sao lại làm chậm ghi? Bao nhiêu index là quá nhiều?
Index là một cấu trúc dữ liệu song song với bảng. Đọc nhanh vì tra cứu chỉ đi qua vài tầng B-tree thay vì quét toàn bộ bảng, nhưng mỗi thao tác ghi phải cập nhật cả bảng lẫn từng index. Chi phí ghi cụ…
- Vì sao `WHERE DATE(created_at) = '2026-01-01'` không dùng được index trên `created_at`? Viết lại thế nào?
Vì index lưu giá trị gốc của cột, không lưu kết quả của hàm. Khi cột bị bọc trong một hàm, database phải tính hàm đó cho từng dòng rồi mới so sánh — nghĩa là phải đọc hết bảng. Điều kiện như vậy gọi…
- Đánh index lên cột `is_active` hay `status` (chỉ vài giá trị) có tác dụng không?
Thường là không, vì cột đó có cardinality thấp — số giá trị phân biệt quá ít nên selectivity kém. Nếu 90% dòng có isactive = true, đi qua index rồi nhảy về bảng đọc 90% số dòng còn chậm hơn quét tuần tự, do…
- Vì sao `LIKE 'abc%'` dùng được index còn `LIKE '%abc%'` thì không? Muốn tìm chuỗi con nhanh thì làm gì?
Vì B-tree sắp xếp theo thứ tự từ trái sang phải của giá trị. Với LIKE 'abc%' database biết mọi kết quả nằm liền nhau trong khoảng ['abc', 'abd') nên nhảy thẳng tới đó — đây là prefix search. Với '%abc%' thì phần đầu chuỗi…
- Truy vấn có index trên cột nhưng vẫn chậm vì ép kiểu ngầm (implicit cast). Chuyện gì xảy ra?
Khi hai vế của phép so sánh khác kiểu, database phải ép một vế về kiểu kia. Nếu vế bị ép là cột, index trên cột đó trở nên vô dụng — hoàn toàn giống trường hợp bọc cột trong hàm, chỉ khác là lần…
- Truy vấn `ORDER BY created_at DESC LIMIT 20` vẫn chậm dù bảng có index. Đánh index thế nào cho đúng?
Vấn đề nằm ở chỗ index có khớp được cả điều kiện lọc lẫn thứ tự sắp xếp hay không. Nếu chỉ khớp phần lọc, database phải gom hết dòng khớp rồi sort toàn bộ mới lấy được 20 dòng đầu — LIMIT không giúp…
- Giá trị `NULL` có được lưu trong index không? `WHERE col IS NULL` có dùng được index không?
Tuỳ database, và đây là chỗ hay nhầm khi chuyển giữa các hệ. PostgreSQL: B-tree có lưu NULL, nên WHERE col IS NULL dùng được index bình thường. Điều đó cũng có nghĩa index bao phủ mọi dòng của bảng, kể cả dòng NULL. Oracle:…
- Với `WHERE tenant_id = ? AND created_at > ? AND status = ?`, thứ tự cột trong composite index nên là gì?
- Nên dùng một composite index nhiều cột hay nhiều index đơn cột? Database tự kết hợp index được không?
- Không dùng transaction thì luồng chuyển tiền hỏng ở đâu? ACID nghĩa thực tế là gì với từng chữ?
Transaction gom nhiều câu lệnh thành một đơn vị: hoặc tất cả có hiệu lực, hoặc không câu nào. Thiếu nó, luồng chuyển tiền có thể trừ tiền tài khoản A xong thì tiến trình dừng trước khi cộng cho B — số tiền đó…
- Bốn isolation level chặn được anomaly nào? Mặc định của PostgreSQL và MySQL khác nhau chỗ nào?
Bốn mức chuẩn SQL, xếp từ lỏng đến chặt, mỗi mức chặn thêm một loại anomaly: Level Dirty read Non-repeatable read Phantom ------------ READ UNCOMMITTED có thể có thể có thể READ COMMITTED không có thể có thể REPEATABLE READ không không tuỳ engine SERIALIZABLE…
- Lost update xảy ra thế nào? Kể 3 cách chống.
Lost update xảy ra với luồng đọc — sửa — ghi: hai transaction cùng đọc giá trị cũ, cùng tính toán rồi cùng ghi lại, bản ghi sau đè lên bản ghi trước nên một lần cập nhật biến mất. Ba cách chống: 1. Cập…
- Một câu `UPDATE` bình thường khoá cái gì? Row lock và table lock khác nhau thế nào?
Một câu UPDATE/DELETE chỉ lấy row-level lock trên đúng những hàng nó thay đổi, giữ tới khi transaction kết thúc. Transaction khác vẫn SELECT được các hàng đó (đọc bản cũ qua MVCC), chỉ khi muốn sửa cùng hàng mới phải chờ. Row lock -…
- Optimistic locking bằng cột `version` triển khai thế nào? Khi nào chọn nó thay vì pessimistic lock?
Optimistic locking không giữ khoá nào cả. Bạn đọc dữ liệu kèm số version, khi ghi thì đưa version cũ vào WHERE; nếu ai đó đã sửa trước, câu lệnh cập nhật 0 hàng và bạn biết là có xung đột. Tầng ứng dụng bắt…
- Vì sao không nên để lệnh gọi API bên ngoài nằm trong transaction? Thiết kế lại thế nào?
Đoạn code dưới đây trông gọn nhưng sai ở hai điểm: Vấn đề 1 — giữ khoá theo thời gian mạng. Khoá hàng orders chỉ nhả khi COMMIT. Cổng thanh toán chậm 5 giây thì hàng đó bị giữ 5 giây, kết nối trong pool…
- Savepoint dùng làm gì? "Nested transaction" trong ORM thực chất là gì?
SAVEPOINT đánh dấu một điểm giữa transaction để có thể quay lui một phần thay vì huỷ toàn bộ. Điểm cần nắm: - Database quan hệ không có transaction lồng nhau thật sự. Chỉ có một transaction duy nhất; BEGIN lần thứ hai không tạo…
- Những bẫy nào khiến transaction trong ORM không thật sự bao trùm như bạn nghĩ?
Ba bẫy hay gặp, đều dẫn tới việc code trông như có transaction nhưng thực tế mỗi câu lệnh tự commit riêng. 1. Autocommit — không mở transaction thì mỗi câu là một transaction. Gọi hai lệnh ghi liên tiếp ngoài khối transaction() thì lệnh…
- Client timeout khi không biết transaction đã commit hay chưa — retry thế nào cho an toàn?
- Write skew là gì? Vì sao `REPEATABLE READ` không chặn được mà phải `SERIALIZABLE`? Chi phí ra sao?
- Gap lock và next-key lock của InnoDB là gì? Vì sao `UPDATE` trên cột không index có thể khoá gần hết bảng?
- Cần cập nhật dữ liệu ở hai service/hai database — chọn 2PC hay saga? Trade-off ở đâu?
- Bảng chi tiết đơn hàng đã có `product_id` rồi, vì sao vẫn phải lưu lại tên và giá sản phẩm tại thời điểm mua?
Vì đơn hàng là bản ghi lịch sử, còn bảng products là dữ liệu hiện hành, còn thay đổi. Nếu chỉ giữ productid rồi join sang products để lấy giá, thì hôm sau shop đổi giá hoặc đổi tên sản phẩm, hoá đơn cũ sẽ…
- Sản phẩm có nhiều biến thể (size, màu) thì mô hình bảng thế nào? Giỏ hàng trỏ vào đâu?
Tách sản phẩm (thông tin marketing) khỏi biến thể (thứ thực sự bán được). Áo thun là product; "áo thun đen size M" là variant, và variant mới là đơn vị có SKU, giá, tồn kho. Điểm mấu chốt: giỏ hàng và chi tiết đơn…
- Bán hàng ở nhiều kho: thiết kế bảng tồn kho thế nào để vừa biết tồn từng kho vừa giữ hàng khi khách đặt?
Tồn kho là quan hệ kho × biến thể, không phải một cột stock trên bảng sản phẩm. Tách onhand và reserved. Số bán được là onhand - reserved. Khi khách đặt hàng thì tăng reserved; khi xuất kho thực tế mới giảm onhand và…
- Thiết kế schema cho khuyến mãi và mã giảm giá thế nào? Làm sao chặn một mã bị dùng quá số lần cho phép?
Tách quy tắc khuyến mãi khỏi mã khỏi lần sử dụng — ba khái niệm khác nhau, gộp lại sẽ bế tắc khi cần một chiến dịch phát nhiều mã. Chặn dùng quá số lần không thể dựa vào SELECT count() rồi INSERT — hai…
- Hệ thống bán hàng ở nhiều nước: lưu tiền trong database thế nào cho đúng?
Một số tiền cần ba thông tin, không phải một: giá trị, đơn vị tiền tệ, và (nếu có quy đổi) tỷ giá tại thời điểm giao dịch. Giá trị: dùng numeric/decimal hoặc số nguyên đơn vị nhỏ nhất (cent, đồng). Không dùng float/double vì…
- Quan hệ nhiều-nhiều mà bản thân mối quan hệ cũng có dữ liệu (vd sinh viên đăng ký môn có điểm, ngày đăng ký) thì làm sao?
Bảng trung gian không còn là "bảng nối kỹ thuật" nữa mà trở thành một thực thể có tên riêng. Đặt tên theo nghiệp vụ (enrollments, memberships, subscriptions) rồi cho nó cột dữ liệu như bảng bình thường. Khoá chính composite hay surrogate id? -…
- Danh mục sản phẩm phân cấp nhiều tầng: so sánh adjacency list, materialized path và closure table. Chọn cái nào?
- Khoá chính nên dùng UUID hay bigint tự tăng? Ảnh hưởng tới index ra sao?
bigint tự tăng nhanh và gọn hơn; UUID đổi lấy tính tạo được ở phía client và không lộ số lượng bản ghi. Chi phí của UUID ngẫu nhiên (v4): - Kích thước: 16 byte so với 8 byte. Khoá chính nằm trong mọi index…
- Bảng users có `unique(email)` và dùng soft delete. Người dùng xoá tài khoản rồi đăng ký lại bằng chính email đó thì lỗi trùng — xử lý thế nào?
Đây là lỗi thường gặp của soft delete: hàng đã "xoá" vẫn nằm trong bảng nên vẫn chiếm chỗ trong unique index. Cách 1 — partial unique index (gọn nhất trên PostgreSQL): chỉ áp ràng buộc cho hàng còn sống. Hàng đã xoá không nằm…
- Yêu cầu: xem lại một bản ghi ở thời điểm bất kỳ trong quá khứ và biết ai đã sửa gì. Thiết kế lưu lịch sử thay đổi thế nào?
- Ứng dụng SaaS phục vụ nhiều khách hàng: chọn database riêng, schema riêng hay cột `tenant_id` chung? Đánh đổi ra sao?
- Địa chỉ giao hàng của khách thay đổi theo thời gian. Lưu thế nào để đơn hàng cũ vẫn hiện đúng địa chỉ đã giao?
Tách làm hai việc: địa chỉ hiện tại của khách và địa chỉ dùng cho một đơn cụ thể. Đơn hàng snapshot địa chỉ vì nó mô tả nơi hàng đã thực sự được giao. Nếu chỉ join sang addresses, khách sửa địa chỉ là…
- Trang danh sách bài viết cần hiển thị số bình luận, mỗi lần đều `count(*)` nên chậm. Có nên thêm cột `comment_count` không? Giữ đồng bộ ra sao?
Có — đây là trường hợp denormalize hợp lý (counter cache), nhưng phải trả lời được câu hỏi kèm theo: ai chịu trách nhiệm giữ số đó đúng. Khi nào denormalize là đúng: tỷ lệ đọc/ghi rất lệch (đọc liên tục, comment thêm thưa), phép…
- Trạng thái đơn hàng (pending, paid, shipped, cancelled) nên lưu bằng gì: số nguyên, chuỗi có CHECK, kiểu ENUM hay bảng tra cứu?
Bốn lựa chọn, khác nhau ở chỗ ai giữ danh sách giá trị hợp lệ. Số nguyên (0, 1, 2...) — tốn ít chỗ nhất nhưng đọc dữ liệu thô không hiểu gì, và ý nghĩa của số nằm trong code ứng dụng. Ai đó…
- Khách hàng muốn tự thêm trường dữ liệu riêng cho hồ sơ (mỗi tenant một bộ khác nhau). Dùng EAV hay JSONB? Đánh đổi thế nào?
- Bảng log/sự kiện tăng vài triệu dòng mỗi ngày, query chậm dần và xoá dữ liệu cũ thì database bị treo. Thiết kế lại thế nào?
- TTL của cache nên đặt bao nhiêu? Vì sao cần thêm jitter vào TTL?
TTL là thời gian sống của một entry trước khi bị xoá tự động. Không có con số đúng cho mọi trường hợp — chọn theo mức cũ mà nghiệp vụ chịu được: - Dữ liệu gần như tĩnh (danh mục, cấu hình): vài giờ…
- Bạn thiết kế cache key thế nào? Làm sao xoá sạch cache cũ khi đổi định dạng dữ liệu?
Key phải tự mô tả và chứa đủ mọi tham số ảnh hưởng tới kết quả. Quy ước phổ biến: <app:<entity:<id:<biến-thể. Nguyên tắc: - Thiếu tham số là bug: nếu response đổi theo locale, currency hay user role mà key không có, hai người dùng…
- Dữ liệu nào không nên cache? Kể một trường hợp cache gây sai nghiệp vụ.
Không cache khi cái giá của một lần đọc sai lớn hơn cái lợi về tốc độ: - Quyền và trạng thái tài khoản: role, permission, trạng thái khoá/ban. Admin thu quyền của một người, cache còn 10 phút → người đó vẫn thao tác…
- Cache hit ratio chỉ khoảng 40% — bạn kiểm tra những gì?
Hit ratio thấp nghĩa là phần lớn request vẫn xuống DB mà hệ thống vẫn phải trả chi phí duy trì cache. Thứ tự kiểm tra: 1. Key có bị phân mảnh quá mức không. Key chứa tham số không cần thiết (timestamp, request id,…
- Sau khi update DB, nên **xoá** cache hay **ghi đè** cache bằng giá trị mới?
Mặc định nên xoá (invalidate), rồi để lượt đọc kế tiếp nạp lại từ DB. Vì sao xoá an toàn hơn ghi đè: khi hai request cùng cập nhật một bản ghi, thứ tự ghi vào cache có thể ngược với thứ tự commit vào…
- Mỗi lần deploy hoặc restart Redis, hệ thống chậm hẳn vài phút vì cache trống. Xử lý thế nào?
Đây là cold cache: toàn bộ traffic đang dựa vào cache đột ngột dồn xuống DB. Xử lý theo ba lớp: 1. Không để cache biến mất cùng deploy. Cache phải nằm ở tiến trình riêng (Redis) chứ không phải in-process trong app; restart app…
- Đồng bộ dữ liệu từ Postgres sang Elasticsearch bằng cách nào? Độ trễ chấp nhận được là bao nhiêu?
Ba cách, đi từ đơn giản tới bền vững: 1. Ghi kép (dual write) trong code. Sau khi commit DB thì gọi ES index luôn. Đơn giản nhưng không atomic: DB commit xong mà ES lỗi thì hai bên lệch vĩnh viễn, không ai biết.…
- Postgres đã có full-text search — khi nào mới thật sự cần thêm Elasticsearch?
Postgres full-text search (tsvector/tsquery + index GIN) là đủ cho phần lớn ứng dụng vừa: tìm trong tiêu đề/mô tả, vài trăm nghìn tới vài triệu bản ghi, kết hợp WHERE với cột quan hệ khác. Lợi thế lớn nhất: một source of truth, không…
- Sau khi lưu, người dùng chuyển sang trang danh sách và không thấy bản ghi vừa tạo vì đọc từ read replica. Bạn xử lý thế nào?
Đây là vi phạm read-your-writes: replica bất đồng bộ luôn chậm hơn primary một khoảng (replication lag), và request đọc chạm replica trước khi WAL được áp xong. Các cách xử lý, chọn theo mức nghiêm ngặt cần thiết: 1. Định tuyến theo phiên (đơn…
- Lưu metrics/telemetry theo thời gian: dùng Postgres hay một time-series DB chuyên dụng?
- Team muốn thêm một datastore mới cho một tính năng. Chi phí thật sự của quyết định đó là gì?
- Thiết kế bảng DynamoDB khác thiết kế bảng quan hệ ở điểm nào? Khi nào chọn DynamoDB là sai?
- Dùng Postgres thay Redis làm cache và hàng đợi job được tới đâu?
- Key-value, document, wide-column, graph — mỗi loại thắng ở bài toán nào, và dấu hiệu nào cho thấy đang chọn nhầm?
- Một request đi qua những tầng cache nào? Nên đặt cache ở đâu?
Đi từ gần người dùng ra xa, mỗi tầng chặn bớt một phần lưu lượng cho tầng sau: 1. Trình duyệt — Cache-Control: max-age, cache HTTP local. Rẻ nhất: không có request nào rời máy client. 2. CDN / edge — tài nguyên tĩnh và…
- CDN quyết định "cùng một nội dung" dựa trên gì? Làm sao đẩy nội dung mới ra khi cần?
CDN lưu response theo cache key. Mặc định key là method + host + đường dẫn + query string; Vary trong response bổ sung thêm header vào key. Hệ quả thực tế: - Query string thừa (?utmsource=...) tạo ra key khác nhau cho cùng một…
- Sau khi deploy hoặc restart Redis, database bị quá tải và sập. Vì sao và chống thế nào?