MySQL là một trong những hệ quản trị cơ sở dữ liệu phổ biến nhất, được sử dụng rộng rãi trong các ứng dụng từ nhỏ đến lớn, nên sẽ thường xuất hiện trong các buổi phỏng vấn liên quan đến cơ sở dữ liệu. Danh sách 30+ câu hỏi phỏng vấn MySQL sau đây sẽ giúp bạn nắm vững không chỉ các kiến thức cơ bản mà còn cả các khía cạnh nâng cao như tối ưu hóa truy vấn, lập chỉ mục, hoặc thiết kế cơ sở dữ liệu.
Đọc bài viết này để hiểu rõ hơn về:
- Các câu hỏi phỏng vấn MySQL dành cho Fresher
- Các câu hỏi phỏng vấn MySQL dành cho Intermediate
- Các câu hỏi phỏng vấn MySQL dành cho Advanced
MySQL là gì?
MySQL là một hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở (Relational Database Management System – RDBMS), được phát triển bởi công ty MySQL AB vào năm 1995 và sau đó được Oracle Corporation mua lại vào năm 2010.
Đây là một trong những hệ thống quản lý cơ sở dữ liệu phổ biến nhất trên thế giới, được sử dụng rộng rãi trong các ứng dụng web, doanh nghiệp và phần mềm.
Đặc điểm chính của MySQL
- Kiến trúc cơ sở dữ liệu quan hệ (Relational Database): MySQL tổ chức dữ liệu dưới dạng bảng (table) với các hàng (rows) và cột (columns), giúp đảm bảo tính nhất quán và dễ dàng trong việc thao tác, quản lý dữ liệu.
- Mã nguồn mở và miễn phí: MySQL được phát hành theo giấy phép GNU General Public License (GPL), cho phép người dùng sử dụng miễn phí trong hầu hết các ứng dụng. Ngoài ra, Oracle cũng cung cấp phiên bản MySQL thương mại với các tính năng mở rộng.
- Hỗ trợ đa nền tảng: MySQL hoạt động trên nhiều hệ điều hành bao gồm Windows, Linux, macOS và Unix, giúp dễ dàng tích hợp vào các hệ thống khác nhau.
- Hiệu suất cao: MySQL được tối ưu hóa để xử lý khối lượng lớn dữ liệu với tốc độ cao, đặc biệt phù hợp với các ứng dụng web lớn.
- Cung cấp nhiều tính năng bảo mật và quản lý người dùng: MySQL hỗ trợ các tính năng bảo mật như mã hóa dữ liệu, SSL để bảo vệ kết nối, cùng khả năng quản lý quyền truy cập chi tiết cho từng người dùng.
- Hỗ trợ chế độ đồng bộ và bất đồng bộ trong quản lý dữ liệu: MySQL cung cấp khả năng replication dữ liệu giữa các máy chủ, cho phép người dùng lựa chọn giữa chế độ đồng bộ và bất đồng bộ, đáp ứng các yêu cầu khác nhau về hiệu năng và tính nhất quán.
- Sao lưu và phục hồi: MySQL hỗ trợ các công cụ sao lưu dữ liệu linh hoạt và phục hồi nhanh chóng, giúp đảm bảo an toàn cho dữ liệu trong các tình huống lỗi hoặc mất dữ liệu.
- Khả năng tích hợp với nhiều ngôn ngữ lập trình: MySQL có thể tích hợp tốt với nhiều loại ngôn ngữ lập trình như PHP, Python, Java, C++, .NET, giúp lập trình viên dễ dàng triển khai và phát triển ứng dụng.
Những ai cần biết câu hỏi phỏng vấn MySQL?
Việc nắm bắt các câu hỏi phỏng vấn MySQL không chỉ quan trọng đối với ứng viên mà còn mang lại lợi ích cho nhiều nhóm đối tượng khác nhau như:
- Ứng viên đang tìm việc trong lĩnh vực IT, như:
-
- Lập trình viên Backend hoặc Full-Stack: Những người làm việc với cơ sở dữ liệu quan hệ như MySQL cần chuẩn bị cho các câu hỏi về truy vấn SQL, tối ưu hóa cơ sở dữ liệu, và xử lý lỗi.
- Quản trị viên cơ sở dữ liệu (DBA – Database Administrator): Họ cần hiểu sâu về MySQL để trả lời các câu hỏi liên quan đến bảo mật, sao lưu, replication, và tối ưu hóa hiệu suất.
- Nhà phân tích dữ liệu (Data Analysts): Những người sử dụng MySQL để phân tích và trực quan hóa dữ liệu cũng cần biết cách viết các truy vấn hiệu quả.
- Nhà tuyển dụng và người phỏng vấn: Những người làm việc trong vai trò tuyển dụng cần chuẩn bị các câu hỏi phù hợp để xác định mức độ thành thạo của ứng viên, đặc biệt khi công ty sử dụng MySQL trong dự án.
- Sinh viên và người học công nghệ: Sinh viên những ngành về Công nghệ Thông tin nên chuẩn bị kiến thức MySQL để hoàn thiện kỹ năng cơ sở dữ liệu của mình. Ngoài ra, những người tự học lập trình muốn nắm chắc các kỹ năng thực tế cũng nên biết các câu hỏi phỏng vấn để kiểm tra để củng cố kiến thức.
Đọc thêm: Học MySQL cơ bản với lộ trình và tài liệu tổng quan
Các câu hỏi phỏng vấn MySQL thường gặp dành cho Fresher
MySQL khác gì so với các RDBMS khác?
Tiêu chí | MySQL | PostgreSQL | Oracle | SQL Server |
Mã nguồn | Mã nguồn mở (Community Edition); có bản trả phí (Enterprise Edition) | Mã nguồn mở | Độc quyền, thuộc sở hữu của Oracle Corporation | Có phiên bản miễn phí (Express) và bản trả phí, thuộc sở hữu của Microsoft |
Hiệu năng | Tối ưu cho các truy vấn đơn giản, hiệu suất cao với khối lượng dữ liệu lớn | Xử lý tốt các truy vấn phức tạp, hỗ trợ giao dịch nặng | Có thể xử lý khối lượng dữ liệu rất lớn trong thời gian thực | Hiệu suất cao khi tích hợp trong hệ sinh thái Microsoft |
Tính năng nổi bật | – Dễ sử dụng, thân thiện với người mới bắt đầu
– Hỗ trợ Replication, Sharding – InnoDB đảm bảo tính toàn vẹn dữ liệu |
– Hỗ trợ mạnh mẽ các tính năng nâng cao như Window Functions, CTE, JSON
– Tuân thủ chuẩn SQL tốt hơn |
– Tính năng mạnh mẽ cho doanh nghiệp như RAC (Real Application Clusters), Partitioning
– Khả năng bảo mật cao |
– Tích hợp tốt với hệ sinh thái Microsoft (.NET, Azure)
– Hỗ trợ công cụ báo cáo và phân tích dữ liệu mạnh mẽ |
Khả năng mở rộng | Phù hợp với ứng dụng vừa và nhỏ, hỗ trợ sharding và replication | Khả năng mở rộng cao, hỗ trợ sharding và replication | Khả năng mở rộng rất cao, hỗ trợ clustering phức tạp | Khả năng mở rộng tốt, hỗ trợ clustering và replication |
Nền tảng hỗ trợ | Windows, Linux, macOS, Unix | Windows, Linux, macOS, Unix | Windows, Linux, Unix | Windows, Linux |
Ứng dụng | – Phù hợp cho ứng dụng web, thương mại điện tử
– Các hệ thống quản lý vừa và nhỏ |
– Thích hợp với doanh nghiệp vừa và lớn
– Ứng dụng cho hệ thống tài chính, phân tích dữ liệu lớn |
– Dành cho các doanh nghiệp lớn, tập đoàn
– Hệ thống ERP, CRM và phân tích dữ liệu phức tạp |
– Hệ thống doanh nghiệp vừa và lớn
– Ứng dụng trong ngành tài chính, ngân hàng, quản trị doanh nghiệp |
Cộng đồng hỗ trợ | – Cộng đồng lớn, nhiều tài liệu và diễn đàn hỗ trợ
– Nhiều plugin và công cụ bổ trợ miễn phí |
Cộng đồng năng động, thường xuyên cập nhật tính năng mới | Hỗ trợ chủ yếu từ Oracle, cộng đồng nhỏ hơn nhưng nhiều tài liệu chuyên sâu | Được hỗ trợ mạnh mẽ từ Microsoft, hệ sinh thái bổ trợ phong phú |
DML, DDL và DCL là gì?
Trong MySQL cũng như các hệ quản trị cơ sở dữ liệu quan hệ khác, các câu lệnh SQL được chia thành các loại chính dựa trên mục đích sử dụng. Ba nhóm chính là:
- DML (Data Manipulation Language)
- DDL (Data Definition Language)
- DCL (Data Control Language)
Mỗi nhóm phục vụ một mục đích cụ thể trong việc quản lý và thao tác dữ liệu.
DML (Data Manipulation Language) – Ngôn ngữ thao tác dữ liệu
DML bao gồm các lệnh dùng để thao tác với dữ liệu bên trong bảng giúp thực hiện các thao tác như thêm, sửa, xóa và truy vấn dữ liệu. DML không thay đổi cấu trúc của bảng mà chỉ thay đổi dữ liệu trong các bảng. Các lệnh DML trong MySQL gồm:
- SELECT: Truy vấn dữ liệu từ một hoặc nhiều bảng.
- INSERT: Thêm dữ liệu mới.
- UPDATE: Cập nhật dữ liệu.
- DELETE: Xóa dữ liệu.
Ví dụ để truy vấn dữ liệu từ bảng employees, ta dung cú pháp sau:
SELECT * FROM employees;
Trong đó SELECT * dùng để truy vấn tất cả các cột trong một bảng.
Ví dụ để thêm dữ liệu vào bảng ta dùng lệnh INSERT với cú pháp:
INSERT INTO employees (id, name, age) VALUES (1, 'John Doe', 30);
Ví dụ để xoá thông tin của nhân viên có id=1 ra khỏi bảng employees, ta dùng cú pháp sau:
DELETE FROM employees WHERE id = 1;
Đọc thêm: Ngôn ngữ thao tác dữ liệu (DML) là gì? Các lệnh cơ bản với DML
DDL – Data Definition Language (Ngôn ngữ định nghĩa dữ liệu)
DDL là các câu lệnh SQL được sử dụng để định nghĩa cấu trúc của cơ sở dữ liệu, bảng và các đối tượng khác như chỉ mục (index), ràng buộc và quan hệ giữa các bảng. Câu lệnh DDL giúp tạo mới, thay đổi hoặc xóa các đối tượng trong cơ sở dữ liệu.
Lưu ý là DDL làm thay đổi cấu trúc của cơ sở dữ liệu và thường không thể hoàn tác (rollback) như DML.
Các câu lệnh DDL trong MySQL bao gồm:
- CREATE: Tạo cơ sở dữ liệu, bảng, view hoặc các đối tượng khác.
- ALTER: Sửa đổi cấu trúc của bảng hoặc cơ sở dữ liệu.
- DROP: Xóa bảng, cơ sở dữ liệu hoặc các đối tượng khác.
- TRUNCATE: Xóa toàn bộ dữ liệu trong bảng nhưng giữ nguyên cấu trúc.
Ví dụ để tạo một bảng employees dùng để lưu trữ thông tin của nhân viên, ta sử dụng cú pháp sau:
CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(100), age INT );
Ví dụ để thêm cột address để lưu trữ địa chỉ của nhân viên trong bảng employees, ta dùng lệnh ALTER với cú pháp sau:
ALTER TABLE employees ADD COLUMN address VARCHAR(255);
Ví dụ để xoá bảng employees ta sử dụng cú pháp sau:
DROP TABLE employees;
Ví dụ để xoá dữ liệu trong bảng employees nhưng không xoá bảng, ta sử dụng lệnh TRUNCATE với cú pháp như sau:
TRUNCATE TABLE employees;
Đọc thêm: Ngôn ngữ định nghĩa dữ liệu là gì? Các lệnh DDL cơ bản
DCL – Data Control Language (Ngôn ngữ điều khiển dữ liệu)
DCL là các câu lệnh SQL được sử dụng để kiểm soát quyền truy cập vào dữ liệu và các đối tượng trong cơ sở dữ liệu. Các câu lệnh DCL giúp xác định quyền hạn của người dùng và cấp hoặc thu hồi quyền sử dụng cơ sở dữ liệu.
Các câu lệnh DCL trong MySQL bao gồm:
- GRANT: Cấp quyền cho người dùng.
- REVOKE: Thu hồi quyền từ người dùng.
Ví dụ để cấp quyền SELECT và INSERT cho người dùng, ta sử dụng cú pháp sau:
GRANT SELECT, INSERT ON employees TO 'user'@'localhost';
Ví dụ để thu hồi quyền INSERT của người dùng trên bảng employees, ta sử dụng cú pháp như sau:
REVOKE INSERT ON employees FROM 'user'@'localhost';
Phân biệt CHAR và VARCHAR như thế nào?
CHAR và VARCHAR là hai kiểu dữ liệu phổ biến trong các hệ quản trị cơ sở dữ liệu, được sử dụng để lưu trữ chuỗi ký tự. Mặc dù cả hai đều xử lý dữ liệu dạng text, chúng có sự khác biệt rõ rệt về cách lưu trữ và hiệu suất.
Dưới đây là bảng so sánh của 2 kiểu dữ liệu này:
Tiêu chí | CHAR | VARCHAR |
Kiểu lưu trữ | Dữ liệu có độ dài cố định. | Dữ liệu có độ dài thay đổi. |
Dung lượng lưu trữ | Tốn dung lượng cố định số byte theo độ dài được khai báo (dù chuỗi ngắn hơn). | Tốn dung lượng đúng bằng độ dài chuỗi thực tế + 1 byte để lưu độ dài. |
Hiệu suất | Truy xuất nhanh hơn vì độ dài cố định, không cần xử lý thêm. | Truy xuất chậm hơn vì cần xử lý độ dài chuỗi thực tế. |
Ứng dụng phù hợp | Dữ liệu có độ dài cố định hoặc gần cố định (mã PIN, mã sản phẩm…). | Dữ liệu có độ dài thay đổi (tên, mô tả, địa chỉ…). |
Giới hạn kích thước | Tối đa 255 ký tự. | Tối đa 65,535 ký tự (tùy thuộc vào kích thước của hàng và bảng). |
Đệm khoảng trắng | Tự động đệm khoảng trắng nếu chuỗi ngắn hơn độ dài khai báo. | Không đệm khoảng trắng, lưu đúng dữ liệu thực tế. |
Phân biệt FLOAT và DOUBLE như thế nào?
FLOAT và DOUBLE là hai kiểu dữ liệu dùng để lưu trữ giá trị số thực trong các hệ quản trị cơ sở dữ liệu, tuy nhiên chúng có sự khác biệt về độ chính xác và dung lượng lưu trữ.
Dưới đây là bảng so sánh chi tiết:
Tiêu chí | FLOAT | DOUBLE |
Độ chính xác | Độ chính xác đơn (single precision), khoảng 7 chữ số thập phân. | Độ chính xác kép (double precision), khoảng 15 chữ số thập phân. |
Dung lượng lưu trữ | Tốn 4 byte (32-bit). | Tốn 8 byte (64-bit). |
Phạm vi giá trị | Rộng hơn INTEGER nhưng nhỏ hơn DOUBLE. | Phạm vi giá trị lớn hơn, thích hợp cho số rất lớn hoặc rất nhỏ. |
Hiệu suất | Nhanh hơn do tốn ít bộ nhớ hơn. | Chậm hơn một chút vì tốn nhiều bộ nhớ hơn. |
Ứng dụng phù hợp | Dùng trong các tính toán không yêu cầu độ chính xác cao (ví dụ: game, đồ họa). | Dùng trong các tính toán cần độ chính xác cao (ví dụ: khoa học, tài chính). |
Ví dụ | Lưu giá trị như 12345.67 (có thể bị làm tròn). | Lưu chính xác giá trị như 12345.6789012345. |
Phân biệt LENGTH và CHAR_LENGTH như thế nào?
LENGTH và CHAR_LENGTH là hai hàm trong SQL dùng để tính độ dài của chuỗi. Dù có vẻ giống nhau, nhưng chúng lại hoạt động khác nhau trong việc đo lường và xử lý ký tự.
Dưới đây là bảng so sánh giúp làm rõ 2 kiểu dữ liệu này:
Tiêu chí | LENGTH | CHAR_LENGTH |
Chức năng | Tính tổng số byte của chuỗi. | Tính tổng số ký tự trong chuỗi. |
Đơn vị đo lường | Số byte (tùy thuộc vào encoding, một ký tự có thể chiếm nhiều byte). | Số ký tự (mỗi ký tự được tính là một đơn vị, bất kể encoding). |
Ứng dụng | Dùng để kiểm tra kích thước chuỗi khi lưu trữ trong cơ sở dữ liệu, đặc biệt khi làm việc với các encoding phức tạp | Thích hợp khi xử lý chuỗi text ở mức ký tự logic, chẳng hạn kiểm tra độ dài tên người dùng |
Encoding ảnh hưởng | Có, các ký tự Unicode hoặc multi-byte sẽ làm tăng kết quả LENGTH. | Không, luôn đếm theo số ký tự, không phụ thuộc vào encoding. |
Ví dụ | LENGTH(‘A’) = 1, LENGTH(‘Á’) = 2 (với UTF-8 encoding). | CHAR_LENGTH(‘A’) = 1, CHAR_LENGTH(‘Á’) = 1. |
Phân biệt NOW() và CURRENT_DATE() như thế nào?
NOW() và CURRENT_DATE() là hai hàm thường được sử dụng trong SQL để làm việc với dữ liệu thời gian. Mặc dù cả hai đều liên quan đến thời gian, nhưng chúng có mục đích và cách trả về kết quả khác nhau.
Dưới đây là bảng so sánh chi tiết:
Tiêu chí | NOW() | CURRENT_DATE() |
Chức năng | Trả về ngày và giờ hiện tại. | Trả về ngày hiện tại, không bao gồm giờ. |
Định dạng trả về | YYYY-MM-DD HH:MM:SS | YYYY-MM-DD |
Dữ liệu trả về | Bao gồm cả ngày và thời gian cụ thể. | Chỉ trả về phần ngày (không có thời gian). |
Ứng dụng phù hợp | Sử dụng khi cần cả ngày và giờ (ví dụ: timestamp). | Sử dụng khi chỉ cần ngày (ví dụ: lưu ngày sinh). |
Ví dụ | 2024-12-14 15:30:45 | 2024-12-14 |
Sự khác biệt giữa SQL và MySQL là gì?
Tiêu chí | SQL | MySQL |
Định nghĩa | Là ngôn ngữ truy vấn cơ sở dữ liệu chuẩn | Là một hệ quản trị cơ sở dữ liệu – sử dụng SQL để xử lý dữ liệu |
Mục đích | Dùng để giao tiếp với cơ sở dữ liệu: truy vấn, cập nhật, xóa hoặc chỉnh sửa dữ liệu. | Dùng để quản lý cơ sở dữ liệu và cung cấp khả năng thực thi các câu lệnh SQL. |
Phân loại | Là một ngôn ngữ lập trình chuẩn, không phụ thuộc vào hệ quản trị cơ sở dữ liệu nào. | Là một phần mềm cụ thể, dựa trên SQL, thuộc sở hữu của Oracle Corporation. |
Tính năng | Quy định ngôn ngữ chuẩn để thao tác với cơ sở dữ liệu. | Cung cấp công cụ và môi trường để quản lý cơ sở dữ liệu một cách hiệu quả. |
Tính linh hoạt | Được sử dụng bởi nhiều hệ quản trị cơ sở dữ liệu (MySQL, PostgreSQL, SQL Server). | Chỉ hoạt động trong khung hệ thống của riêng nó. |
Công ty quản lý | Không thuộc quyền quản lý của bất kỳ công ty nào. | Thuộc quyền quản lý của Oracle Corporation. |
Các lệnh cơ bản trong MySQL và ví dụ cụ thể
MySQL là một hệ quản trị cơ sở dữ liệu phổ biến, cung cấp nhiều lệnh hữu ích để thao tác với dữ liệu. Dưới đây là một số lệnh cơ bản và cách sử dụng chúng:
Lệnh SELECT
Dùng để truy vấn dữ liệu từ một hoặc nhiều bảng, thường kết hợp với điều kiện WHERE để lọc dữ liệu.
Cú pháp:
SELECT column1, column2, ... FROM table_name WHERE condition;
Ví dụ để lấy danh sách tên và tuổi của người dùng từ bảng employees ta sử dụng cú pháp:
SELECT name, age FROM employees WHERE age > 18;
Lệnh INSERT
Dùng để thêm một hoặc nhiều bản ghi mới vào bảng.
Cú pháp:
INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);
Ví dụ để thêm dữ liệu một người dùng mới vào bảng employees ta sử dụng cú pháp:
INSERT INTO employees (id, name, age) VALUES (1, 'John Doe', 28);
Lệnh UPDATE
Dùng để cập nhật dữ liệu trong bảng, dựa trên điều kiện trong câu lệnh WHERE.
Cú pháp:
UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;
Ví dụ để cập nhật tuổi của nhân viên có ID là 1 thành 29 ta sử dụng cú pháp:
UPDATE employees SET age = 29 WHERE id = 1;
Lệnh DELETE
Dùng để xóa một hoặc nhiều bản ghi từ bảng, dựa trên điều kiện được cung cấp.
Cú pháp:
DELETE FROM table_name WHERE condition;
Ví dụ để xóa thông tin tất cả nhân viên có độ tuổi nhỏ hơn 25 khỏi bảng employees, ta sử dụng cú pháp:
DELETE FROM employees WHERE age < 25;
Lệnh CREATE TABLE
Dùng để tạo một bảng mới.
Cú pháp:
CREATE TABLE table_name ( column1 datatype, column2 datatype, ... );
Ví dụ để tạo bảng users ta sử dụng cú pháp:
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(100), age INT );
Lệnh DROP TABLE
Dùng để xóa bảng.
Cú pháp:
DROP TABLE <table_name>;
Ví dụ để xóa bảng users ta sử dụng cú pháp:
DROP TABLE users;
Lệnh ALTER
Dùng để thay đổi cấu trúc của bảng, ví dụ như thêm hoặc xóa cột.
Cú pháp:
–- Để thêm cột mới vào bảng ALTER TABLE table_name ADD column_name datatype; –- Để xoá cột khỏi bảng ALTER TABLE table_name DROP column_name;
Ví dụ để hêm một cột mới có tên address vào bảng employees, ta sử dụng cú pháp:
ALTER TABLE employees ADD address VARCHAR(255);
Import database trong MySQL như thế nào?
Import database trong MySQL là việc nạp dữ liệu từ một file sao lưu (thường là .sql) vào hệ thống cơ sở dữ liệu. Có 3 cách thực hiện import dữ liệu như sau:
Cách 1: Import bằng Command Line
Là cách phổ biến nhất, phù hợp với những người quen làm việc trên giao diện dòng lệnh, đặc biệt trên hệ thống Linux hoặc máy chủ.
Cách thực hiện:
Bước 1: Đảm bảo file .sql cần import đã sẵn sàng.
Bước 2: Kiểm tra và đảm bảo rằng cơ sở dữ liệu đích đã được tạo. Trong trường hợp database chưa được tạo, ta có thể dùng câu lệnh sau:
CREATE DATABASE database_name;
Bước 3: Mở Command Line (Terminal) trên máy tính. Nhập lệnh sau:
mysql -u username -p database_name < path/to/file.sql
Trong đó:
- username: Tên người dùng MySQL (thường là root).
- database_name: Tên cơ sở dữ liệu mà bạn muốn import.
- path/to/file.sql: Đường dẫn đến file .sql.
Cách 2: Import bằng MySQL Workbench (Hoặc các MySQL Database Management Tools khác)
MySQL Workbench là công cụ giao diện đồ họa, giúp bạn thao tác trực quan với MySQL. Cách này phù hợp với những người dùng không quen dùng lệnh hoặc cần giao diện trực quan.
Các bước thực hiện:
- Mở MySQL Workbench và kết nối đến máy chủ MySQL.
- Tạo một cơ sở dữ liệu mới hoặc chọn cơ sở dữ liệu có sẵn.
- Vào menu Server > Data Import.
- Chọn tùy chọn Import from Self-Contained File và tìm đến file .sql.
- Trong mục Default Schema to be Imported To, chọn cơ sở dữ liệu mục tiêu.
- Nhấn Start Import để bắt đầu quá trình.
Cách 3: Import bằng phpMyAdmin
phpMyAdmin là công cụ quản lý MySQL thông qua giao diện web, thường được dùng trên các máy chủ cài sẵn (như XAMPP, LAMP).
Cách thực hiện:
- Đăng nhập vào phpMyAdmin qua trình duyệt web.
- Chọn cơ sở dữ liệu mà bạn muốn import dữ liệu.
- Nhấn vào tab Import.
- Bấm Choose File để chọn file .sql từ máy tính của bạn.
- Nhấn Go để bắt đầu import.
MySQL có bao nhiêu loại storage engine?
MySQL hỗ trợ nhiều loại Storage Engine khác nhau, mỗi loại cung cấp các cách lưu trữ, truy xuất và quản lý dữ liệu phù hợp với những nhu cầu cụ thể. Hiện tại, MySQL tích hợp sẵn các Storage Engine chính và cũng cho phép bổ sung các loại engine bên ngoài tùy theo ứng dụng.
Storage Engine | Đặc điểm chính | Ứng dụng phổ biến | Hạn chế |
InnoDB (mặc định) | – Hỗ trợ giao dịch (transactions), tính năng ACID.
– Khóa cấp hàng (row-level locking). – Hỗ trợ khóa ngoại (foreign key constraints). |
Các ứng dụng yêu cầu tính toàn vẹn dữ liệu cao như ngân hàng, thương mại điện tử. | – Hiệu suất ghi thấp hơn MyISAM trong các tác vụ đơn giản.
– Tiêu thụ nhiều tài nguyên hệ thống hơn. |
MyISAM | – Tối ưu cho tốc độ đọc.
– Hỗ trợ khóa cấp bảng (table-level locking). – Tiết kiệm tài nguyên hơn InnoDB. |
– Ứng dụng chỉ đọc (read-heavy), như CMS hoặc blog.
– Phân tích dữ liệu. |
– Không hỗ trợ giao dịch hoặc khóa ngoại.
– Dữ liệu có thể bị mất trong trường hợp tắt máy đột ngột. |
MEMORY | – Lưu trữ dữ liệu trong RAM, tốc độ truy cập cực nhanh.
– Khóa cấp bảng (table-level locking). |
– Bảng tạm thời.
– Dữ liệu cần truy cập nhanh trong thời gian ngắn. |
– Dữ liệu bị mất khi tắt hoặc khởi động lại máy chủ.
– Không hỗ trợ dữ liệu lớn hoặc giao dịch. |
CSV | – Lưu dữ liệu dưới dạng file CSV (Comma-Separated Values).
– Dễ dàng trao đổi dữ liệu với các hệ thống khác |
Xuất/nhập dữ liệu với phần mềm bên ngoài như Excel. | Không hỗ trợ các tính năng nâng cao như giao dịch, chỉ mục, hoặc khóa. |
ARCHIVE | – Nén dữ liệu để tiết kiệm không gian.
– Chỉ hỗ trợ INSERT và SELECT. |
Lưu trữ log, dữ liệu thống kê, hoặc lịch sử giao dịch. | Không hỗ trợ cập nhật (UPDATE) hoặc xóa (DELETE) dữ liệu. |
BLACKHOLE | Không lưu dữ liệu, mọi thao tác ghi dữ liệu bị bỏ qua. | Kiểm tra hoặc ghi log đặc biệt. | Không lưu dữ liệu thực tế, chỉ dùng trong các trường hợp đặc biệt như kiểm thử. |
NDB (Clustered) | – Lưu trữ dữ liệu phân tán trên nhiều máy chủ (MySQL Cluster).
– Hiệu suất cao, độ trễ thấp. – Hỗ trợ khả năng mở rộng theo chiều ngang |
– Hệ thống phân tán yêu cầu tính sẵn sàng cao.
– Xử lý dữ liệu thời gian thực. |
Yêu cầu cấu hình phức tạp và tài nguyên lớn. |
FEDERATED | – Kết nối tới cơ sở dữ liệu từ xa, không lưu dữ liệu cục bộ.
– Chỉ lưu trữ cấu trúc bảng (schema), còn dữ liệu được truy vấn từ máy chủ từ xa |
Truy cập cơ sở dữ liệu trên máy chủ khác mà không cần sao chép. | – Hiệu suất phụ thuộc vào mạng và máy chủ từ xa.
– Khả năng quản lý hạn chế. – Không hỗ trợ giao dịch, khóa ngoại hay chỉ mục |
TokuDB | – Sử dụng cấu trúc lưu trữ đặc biệt, gọi là Fractal Tree Indexes
– Tối ưu lưu trữ dữ liệu lớn với khả năng nén cao. – Hỗ trợ giao dịch và ACID như InnoDB. – Khóa cấp dòng, sao lưu dữ liệu không gây gián đoạn ứng dụng |
– Hệ thống Big Data.
– Các ứng dụng yêu cầu xử lý lượng dữ liệu khổng lồ. |
– Yêu cầu tài nguyên lớn.
– Ít phổ biến so với các engine khác. |
Các quy tắc cơ bản của REGEXP là gì?
REGEXP (viết tắt của Regular Expression) là một tập hợp quy tắc hoặc mẫu (patterns) được sử dụng để khớp (match) hoặc tìm kiếm các chuỗi cụ thể trong văn bản thông qua biểu thức chính quy. Nó giống như một “ngôn ngữ mini” giúp định nghĩa các quy tắc để xử lý chuỗi.
Ký tự thường
Các ký tự như a,b,c sẽ so khớp chính xác với chúng trong chuỗi.
Ví dụ: Mẫu abc sẽ tìm thấy từ “abc” trong chuỗi “abc123”.
Ký tự đặc biệt
REGEXP có các ký hiệu đặc biệt giúp mở rộng khả năng tìm kiếm được quy định như sau:
Ký tự | Ý nghĩa | Ví dụ |
. | Đại diện cho bất kỳ ký tự nào | Mẫu a.c sẽ khớp với “abc”, “a1c”, “a-c” |
* | Lặp lại ký tự đứng trước 0 hoặc nhiều lần | Mẫu ab* sẽ khớp với “a”, “ab”, “abb”, “abbb” |
+ | Lặp lại ký tự đứng trước ít nhất 1 lần | Mẫu ab+ sẽ khớp với “ab”, “abb”, nhưng không khớp với “a” |
? | Ký tự trước nó có thể xuất hiện hoặc không | Mẫu colou?r sẽ khớp với cả “color” và “colour” |
[] | Đại diện cho một tập hợp ký tự | Mẫu [aeiou] sẽ tìm thấy các nguyên âm |
Tập hợp ký tự
- [abc]: Một ký tự trong danh sách. Ví dụ [abc] sẽ khớp với ‘a’
- [a-z]: Ký tự nằm trong khoảng a-z. Ví dụ [a-z] khớp “b”, “x”
- [^a-z]: Ký tự không nằm trong khoảng a-z. Ví dụ [^a-z] khớp “1”, “@”
Tập hợp mở rộng
- \d: Đại diện cho chữ số (0-9).
- \w: Đại diện cho chữ cái, chữ số và dấu gạch dưới ([a-zA-Z0-9_]).
- \s: Đại diện cho khoảng trắng (space, tab, newline).
- ^: Bắt đầu chuỗi. Ví dụ: Mẫu ^abc khớp với chuỗi bắt đầu bằng “abc”.
- $: Kết thúc chuỗi. Ví dụ: Mẫu xyz$ khớp với chuỗi kết thúc bằng “xyz”.
Ứng dụng của REGEXP là gì?
- Tìm kiếm văn bản: Tìm tất cả email, số điện thoại trong một đoạn văn.
- Kiểm tra định dạng: Xác minh định dạng email, URL, số điện thoại.
- Tách hoặc thay thế: Xóa ký tự đặc biệt hoặc tách chuỗi dựa trên dấu phân cách.
Ví dụ nếu muốn tìm tất cả các địa chỉ email trong một đoạn văn bản, ta có thể dùng mẫu REGEXP trong một bảng MySQL như sau:
SELECT * FROM users WHERE email REGEXP '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}';
- Giải thích: Mẫu REGEXP [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,} giúp tìm các chuỗi có định dạng email, ví dụ: example@domain.com.
Ví dụ nếu muốn kiểm tra số điện thoại Việt Nam, ta dùng mẫu như sau:
SELECT * FROM contacts WHERE phone_number REGEXP '^(\+84|0)[0-9]{9,10}$';
- Giải thích: Câu lệnh này tìm các số điện thoại bắt đầu bằng +84 hoặc 0, tiếp theo là 9-10 chữ số. Ví dụ: +84123456789 hoặc 0123456789.
Lệnh JOIN là gì?
Lệnh JOIN trong SQL được sử dụng để kết hợp dữ liệu từ hai hoặc nhiều bảng dựa trên một điều kiện chung. Mỗi loại JOIN phục vụ các mục đích khác nhau trong việc xử lý dữ liệu.
Cú pháp cơ bản của lệnh JOIN
SELECT columns FROM table1 JOIN_TYPE table2 ON table1.common_column = table2.common_column;
Trong đó:
- table1 và table2 là các bảng được tham gia (join).
- JOIN_TYPE là loại JOIN (INNER, LEFT, RIGHT, FULL).
- ON xác định điều kiện để kết nối hai bảng.
Giải thích các loại JOIN trong MySQL
Loại JOIN | Mô tả | Kết quả trả về | Ví dụ minh họa |
INNER JOIN | Chỉ lấy những bản ghi ở hai bảng có giá trị khớp ở cả hai bảng. | Chỉ dữ liệu giao nhau giữa hai bảng. | Ví dụ: Tìm kiếm thông tin khách hàng từ bảng KHACHHANG có đơn đặt hàng trong bảng DONHANG. |
LEFT JOIN | Lấy toàn bộ bản ghi từ bảng bên trái (table1), kể cả khi không có bản ghi khớp ở bảng bên phải. | Dữ liệu khớp từ hai bảng được join và dữ liệu từ bảng trái + NULL cho dữ liệu không khớp ở bảng phải. | Ví dụ: Lấy danh sách toàn bộ khách hàng từ bảng KHACHHANG, kể cả những khách hàng không có đơn đặt hàng trong bảng DONHANG. |
RIGHT JOIN | Lấy toàn bộ bản ghi từ bảng bên phải (table2), kể cả khi không có bản ghi khớp ở bảng bên trái. | Dữ liệu khớp từ hai bảng được join và dữ liệu từ bảng phải + NULL cho dữ liệu không khớp ở bảng trái. | Ví dụ: Lấy danh sách tất cả đơn hàng từ bảng DONHANG, kể cả những đơn hàng không có khách hàng tương ứng trong bảng KHACHHANG. |
FULL JOIN (MySQL không hỗ trợ trực tiếp) | Kết hợp tất cả bản ghi từ cả hai bảng, thêm NULL vào những nơi không khớp. | Dữ liệu từ cả hai bảng, bao gồm những bản ghi không khớp. | Ví dụ: Tổng hợp danh sách toàn bộ khách hàng từ bảng KHACHHANG và đơn hàng từ bảng DONHANG, kể cả những khách hàng hoặc đơn hàng không có liên kết. |
CROSS JOIN | Kết hợp tất cả các bản ghi từ bảng này với tất cả các bản ghi từ bảng kia. | Tích Descartes (Cartesian Product) của hai bảng. | Kết hợp tất cả khách hàng từ bảng KHACHHANG với tất cả sản phẩm từ bảng SANPHAM, để liệt kê mọi khả năng kết hợp khách hàng với sản phẩm. |
SELF JOIN | Thực hiện join chính bảng đó với chính nó | Tương tự các loại JOIN khác, nhưng áp dụng trên một bảng duy nhất để so sánh hoặc tìm liên kết trong bảng. | Tìm nhân viên từ bảng NHANVIEN có người quản lý (trường MANAGER_ID) là nhân viên khác trong cùng bảng NHANVIEN. |
Giả sử ta có hai bảng sau:
- Bảng Customers:
CustomerID | Name |
1 | John |
2 | Alice |
3 | Bob |
- Bảng Orders:
OrderID | CustomerID | Product |
101 | 1 | Laptop |
102 | 2 | Phone |
103 | 4 | Tablet |
Ví dụ để lấy danh sách khách hàng và sản phẩm mà họ đã đặt hàng, ta sử dụng INNER JOIN như sau:
SELECT Customers.Name, Orders.Product FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID;
Kết quả: Chỉ các hàng có CustomerID trùng khớp giữa hai bảng mới được trả về (khách hàng John và Alice) như sau:
Name | Product |
---|---|
John | Laptop |
Alice | Phone |
Ví dụ để lấy danh sách tất cả khách hàng, kèm theo sản phẩm mà họ đã đặt (nếu có), ta sử dụng LEFT JOIN như sau:
SELECT Customers.Name, Orders.Product FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID;
Kết quả: tất cả khách hàng trong bảng Customers đều được trả về. Đối với khách hàng Bob, không có đơn hàng nào khớp trong bảng Orders, nên giá trị Product là NULL.
Name | Product |
John | Laptop |
Alice | Phone |
Bob | NULL |
Ví dụ để lấy danh sách tất cả các sản phẩm đã được đặt hàng, kèm theo tên khách hàng (nếu có), ta sử dụng RIGHT JOIN như sau:
SELECT Customers.Name, Orders.Product FROM Customers RIGHT JOIN Orders ON Customers.CustomerID = Orders.CustomerID;
Kết quả: tất cả các đơn hàng trong bảng Orders được trả về. Sản phẩm Tablet không khớp với bất kỳ khách hàng nào trong bảng Customers, nên giá trị Name là NULL.
Name | Product |
John | Laptop |
Alice | Phone |
NULL | Tablet |
Ví dụ để lấy danh sách đầy đủ tất cả khách hàng và sản phẩm đã đặt hàng trong MySQL, ta cần sử dụng UNION để kết hợp hai câu lệnh LEFT JOIN và RIGHT JOIN như sau:
SELECT Customers.Name, Orders.Product FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID UNION SELECT Customers.Name, Orders.Product FROM Customers RIGHT JOIN Orders ON Customers.CustomerID = Orders.CustomerID;
Kết quả: trả về tất cả các hàng từ Customers và Orders. Khách hàng Bob không có đơn hàng nào, còn sản phẩm Tablet không khớp với bất kỳ khách hàng nào.
Name | Product |
John | Laptop |
Alice | Phone |
Bob | NULL |
NULL | Tablet |
MySQL WorkBench là gì?
MySQL Workbench là một công cụ trực quan (GUI – Graphical User Interface) được phát triển bởi Oracle Corporation để quản lý cơ sở dữ liệu. Nó cung cấp các tính năng mạnh mẽ cho việc thiết kế, phát triển, và quản trị cơ sở dữ liệu MySQL.
Công cụ này được sử dụng rộng rãi nhờ giao diện thân thiện và khả năng hỗ trợ đa nền tảng (Windows, macOS, Linux).
Các tính năng chính của MySQL Workbench
Tính năng | Mô tả |
Database Design | – Cho phép thiết kế, tạo và chỉnh sửa mô hình dữ liệu bằng cách kéo thả (ER Diagram).
– Hỗ trợ tạo sơ đồ ER (Entity-Relationship) và sinh mã SQL tự động từ mô hình. |
SQL Development | – Cung cấp giao diện để viết, chạy và kiểm tra các câu lệnh SQL.
– Hiển thị kết quả truy vấn trực tiếp, lưu các truy vấn dưới dạng tệp .sql. – Có trình biên dịch SQL tích hợp và công cụ gỡ lỗi SQL. |
Database Administration | Quản lý người dùng, quyền truy cập, sao lưu và phục hồi cơ sở dữ liệu. |
Data Modeling | Tạo mô hình cơ sở dữ liệu vật lý, logic và chuyển đổi qua lại giữa các dạng. |
Performance Monitoring | Theo dõi hiệu năng cơ sở dữ liệu và tối ưu hóa các truy vấn. |
Migration | Hỗ trợ chuyển đổi dữ liệu từ các hệ quản trị cơ sở dữ liệu khác sang MySQL. |
Ứng dụng của MySQL Workbench
- Thiết kế cơ sở dữ liệu: Một công ty cần thiết kế sơ đồ quan hệ cho hệ thống bán hàng, MySQL Workbench hỗ trợ tạo ERD (Entity-Relationship Diagram) và tự động chuyển đổi thành mã SQL.
- Phân tích dữ liệu: Chạy truy vấn để thống kê và phân tích dữ liệu kinh doanh.
- Quản trị cơ sở dữ liệu: Quản lý tài khoản người dùng, phân quyền, sao lưu dữ liệu định kỳ.
Ưu điểm của MySQL Workbench
- Thân thiện với người dùng: Giao diện đồ họa trực quan, dễ sử dụng, ngay cả với người mới bắt đầu.
- Tiết kiệm thời gian: Các công cụ như kéo thả mô hình, tự động sinh mã SQL giúp giảm thời gian thao tác thủ công.
- Hỗ trợ toàn diện: Tích hợp đầy đủ các tính năng từ thiết kế, phát triển đến quản trị.
- Hiệu quả cao: Giúp quản lý các cơ sở dữ liệu lớn và phức tạp một cách dễ dàng.
- Miễn phí: Phiên bản Community Edition miễn phí và đáp ứng hầu hết các nhu cầu cơ bản.
Các câu hỏi phỏng vấn MySQL thường gặp dành cho Intermediate
Cách tìm duplicate row trong MySQL
Cách 1: Dùng GROUP BY và HAVING
Phương pháp này gom nhóm các bản ghi dựa trên các cột được chỉ định và sử dụng COUNT(*) để đếm số lần xuất hiện trong từng nhóm.
Giả sử ta có bảng employees như sau:
id | name | age | department |
1 | John Doe | 30 | IT |
2 | Jane Smith | 25 | HR |
3 | John Doe | 30 | IT |
4 | Alice Brown | 28 | Marketing |
5 | John Doe | 30 | IT |
Ví dụ để tìm các bản ghi có giá trị trùng lặp trên các cột name, age và department ta sử dụng cú pháp:
SELECT name, age, department, COUNT(*) AS duplicate_count FROM employees GROUP BY name, age, department HAVING COUNT(*) > 1;
Trong đó:
- GROUP BY name, age, department: Gom nhóm các bản ghi dựa trên tổ hợp các giá trị name, age và department. Tất cả các bản ghi có cùng giá trị trong các cột này sẽ được gom thành một nhóm.
- COUNT(*): Đếm số bản ghi trong mỗi nhóm.
- HAVING COUNT(*) > 1: Lọc ra chỉ những nhóm có hơn 1 bản ghi (tức là trùng lặp).
Với cú pháp trên sẽ trả về kết quả như sau:
name | age | department | duplicate_count |
John Doe | 30 | IT | 3 |
Tiếp theo, để tìm tổng số bản ghi bị trùng lặp trong bảng mà không liệt kê chi tiết từng nhóm ta có thể thực hiện như sau:
SELECT SUM(duplicate_count - 1) AS total_duplicates FROM ( SELECT COUNT(*) AS duplicate_count FROM employees GROUP BY name, age, department HAVING COUNT(*) > 1 ) AS duplicates;
Trong đó:
- GROUP BY name, age, department: Gom nhóm các bản ghi trùng lặp.
- COUNT(*): Đếm số lượng bản ghi trong mỗi nhóm.
- HAVING COUNT(*) > 1: Lọc ra các nhóm có bản ghi trùng lặp.
- SUM(duplicate_count – 1): Tính tổng số bản ghi trùng lặp (trừ 1 bản ghi duy nhất cho mỗi nhóm).
Với cú pháp trên kết quả sẽ trả về như sau vì có tổng cộng 2 bản ghi bị trùng lặp (nhóm “John Doe – 30 – IT”):
total_duplicates = 2
Cách 2: Dùng DISTINCT để so sánh
Nếu muốn so sánh các bản ghi duy nhất và các bản ghi trùng lặp, ta có thể dùng DISTINCT để xác định số lượng bản ghi duy nhất và tổng số bản ghi.
Ví dụ:
SELECT (SELECT COUNT(*) FROM employees) AS total_records, (SELECT COUNT(DISTINCT name, age, department) FROM employees) AS unique_records, (SELECT COUNT(*) FROM employees) - (SELECT COUNT(DISTINCT name, age, department) FROM employees) AS duplicate_records;
Trong đó:
- COUNT(*): Đếm tổng số bản ghi trong bảng.
- COUNT(DISTINCT name, age, department): Đếm số bản ghi duy nhất (loại bỏ bản ghi trùng lặp dựa trên các cột name, age,và department).
- Phép trừ: Số bản ghi trùng lặp = Tổng số bản ghi – Số bản ghi duy nhất.
Kết quả trả về sẽ như sau:
total_records = 5 unique_records = 3 duplicate_records = 2
Giải thích các loại quan hệ trong MySQL
Quan hệ One-to-One (1:1)
Có nghĩa là một bản ghi trong bảng này chỉ có thể liên kết với một bản ghi duy nhất trong bảng khác và ngược lại. Ví dụ một người dùng (users) chỉ có một hồ sơ cá nhân (profiles).
Cách thiết lập: Sử dụng Primary Key trên một bảng và liên kết với Foreign Key trong bảng kia với cú pháp như sau:
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(100) ); CREATE TABLE profiles ( id INTPRIMARY KEY, user_id INT UNIQUE, bio TEXT, FOREIGN KEY (user_id) REFERENCES users(id) );
Trong đó: mỗi user có một profile và cột user_id trong bảng profiles liên kết với cột id trong bảng users. Vì cột user_id được ràng buộc UNIQUE nên mỗi user_id chỉ xuất hiện một lần trong bảng profile.
Quan hệ One-to-Many (1:N)
Có nghĩa là một bản ghi trong bảng A có thể liên kết với nhiều bản ghi trong bảng B, nhưng mỗi bản ghi trong bảng B chỉ liên kết với một bản ghi trong bảng A. Ví dụ một khách hàng (customers) có thể đặt nhiều đơn hàng (orders), nhưng mỗi đơn hàng chỉ thuộc về một khách hàng.
Cách thiết lập: Sử dụng Primary Key trong bảng cha (parent table) và liên kết với Foreign Key trong bảng con (child table) với cú pháp như sau:
CREATE TABLE customers ( id INT PRIMARY KEY, name VARCHAR(100) ); CREATE TABLE orders ( id INT PRIMARY KEY, customer_id INT NOT NULL, order_date DATE, FOREIGN KEY (customer_id) REFERENCES customers(id) );
Trong đó: mỗi customer có thể có nhiều order, nhưng mỗi order chỉ thuộc về một customer.
Quan hệ Many-to-Many (N:M)
Có nghĩa là một bản ghi trong bảng A có thể liên kết với nhiều bản ghi trong bảng B và ngược lại. Ví dụ một sinh viên (students) có thể tham gia nhiều khóa học (courses) và mỗi khóa học có thể có nhiều sinh viên tham gia.
Cách thiết lập: Tạo một bảng trung gian (junction table) chứa các Foreign Key liên kết với hai bảng chính với cú pháp như:
CREATE TABLE students ( id INT PRIMARY KEY, name VARCHAR(100) ); CREATE TABLE courses ( id INT PRIMARY KEY, title VARCHAR(100) ); CREATE TABLE student_courses ( student_id INT NOT NULL, course_id INT NOT NULL, PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES students(id), FOREIGN KEY (course_id) REFERENCES courses(id) );
Trong đó: bảng student_courses là bảng trung gian giúp quản lý mối quan hệ nhiều-nhiều giữa students và courses.
Quan hệ Self-Referencing (Tự tham chiếu)
Có nghĩa là một bản ghi trong bảng có thể liên kết với một bản ghi khác trên cùng bảng thông qua một khóa ngoại. Ví dụ một nhân viên (employees) có thể là cấp dưới của một nhân viên khác (quản lý).
Cách thiết lập: Sử dụng Foreign Key để tham chiếu đến Primary Key trong cùng một bảng với cú pháp như sau:
CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(100), manager_id INT, FOREIGN KEY (manager_id) REFERENCES employees(id) );
Trong đó: cột manager_id trong bảng employees tham chiếu đến cột id trong cùng bảng, thể hiện mối quan hệ cấp trên – cấp dưới.
Sự khác biệt giữa primary key và candidate key
Primary Key là một tập hợp một hoặc nhiều cột trong bảng được chọn để làm khóa chính và giúp đảm bảo rằng mỗi bản ghi trong bảng được định danh duy nhất và không được phép chứa giá trị NULL hoặc trùng lặp. Mỗi bảng chỉ có một Primary Key duy nhất.
Candidate Key là tập hợp một hoặc nhiều cột trong bảng có khả năng định danh duy nhất một bản ghi (khóa tiềm năng). Một bảng có thể có nhiều Candidate Keys, nhưng chỉ một Candidate Key sẽ được chọn làm Primary Key. Candidate Key không chứa giá trị NULL hoặc trùng lặp.
Giả sử ta có bảng sau:
emp_id | phone | name | |
101 | john.doe@gmail.com | 1234567890 | John Doe |
102 | jane.smith@gmail.com | 0987654321 | Jane Smith |
103 | alice.brown@gmail.com | 5678901234 | Alice Brown |
Trong đó:
- Các cột hoặc tổ hợp cột có thể được coi là Candidate Key vì chúng đều duy nhất và không chứa giá trị NULL là emp_id, email, phone
- Cột có thể làm Primary Key chỉ có thể là emp_id vì nó không thay đổi theo thời gian (trong khi email hoặc phone có thể thay đổi)
Phân biệt DELETE và TRUNCATE
Khi làm việc với cơ sở dữ liệu SQL, việc xóa dữ liệu là một thao tác phổ biến. Tuy nhiên, hai lệnh DELETE và TRUNCATE tuy cùng dùng để xóa dữ liệu nhưng lại có cách hoạt động và ứng dụng khác nhau.
Dưới đây là bảng so sánh chi tiết giữa hai lệnh này:
Tiêu chí | DELETE | TRUNCATE |
Chức năng | Xóa lần lượt các bản ghi trong bảng dựa trên điều kiện trong mệnh đề WHERE. | Xóa cùng lúc toàn bộ dữ liệu trong bảng mà không thể đặt điều kiện. |
Khôi phục dữ liệu | Có thể khôi phục bằng lệnh ROLLBACK nếu được sử dụng trong giao dịch (transaction). | Không thể khôi phục vì không hỗ trợ giao dịch (mặc định là lệnh không thể hoàn tác). |
Hiệu năng | Chậm hơn, vì phải thực hiện xóa lần lượt từng bản ghi. Mỗi bản ghi bị xóa được ghi lại trong log, và trigger (nếu có) sẽ được kích hoạt. | Nhanh hơn, vì xóa toàn bộ dữ liệu không ghi log từng bản ghi và không kích hoạt trigger. |
Cấp độ khóa | Sử dụng khóa dòng (row-level lock), cho phép xóa dữ liệu theo điều kiện cụ thể. | Sử dụng khóa bảng (table-level lock), vì xóa toàn bộ bảng. |
Ảnh hưởng đến cấu trúc bảng | Không ảnh hưởng đến cấu trúc bảng, các chỉ mục và khóa vẫn được giữ nguyên. | Giữ nguyên cấu trúc bảng, nhưng các chỉ mục và khóa sẽ được đặt lại (reset AUTO_INCREMENT). |
Khi nào sử dụng? | Sử dụng khi cần xóa dữ liệu có điều kiện hoặc cần kiểm soát quá trình xóa qua giao dịch. | Sử dụng khi cần xóa nhanh toàn bộ dữ liệu trong bảng mà không cần kiểm tra điều kiện. |
Cú pháp | DELETE FROM table_name WHERE condition; | TRUNCATE TABLE table_name; |
Chỉ mục (Index) trong MySQL là gì? Tại sao nó quan trọng?
Chỉ mục (Index) trong MySQL là một cấu trúc dữ liệu đặc biệt được tạo ra từ một hoặc nhiều cột, sử dụng để tăng tốc độ truy vấn dữ liệu trong bảng. Chỉ mục hoạt động tương tự như mục lục của một cuốn sách: thay vì phải duyệt qua toàn bộ dữ liệu trong bảng, MySQL có thể nhanh chóng tìm đến vị trí dữ liệu cụ thể dựa trên chỉ mục.
Giả sử ta có bảng dữ liệu employees như sau:
id | name | department | age |
1 | John Doe | IT | 30 |
2 | Jane Smith | HR | 25 |
3 | Alice Brown | Marketing | 28 |
Nếu bạn chạy lệnh sau:
SELECT * FROM employees WHERE department = 'IT';
MySQL phải duyệt qua toàn bộ bảng để tìm các hàng có department = ‘IT’ (full table scan), tức là phải kiểm tra từng bản ghi trong bảng để tìm kết quả phù hợp.
Nếu ta tạo chỉ mục trên cột department:
CREATE INDEX idx_department ON employees(department);
Khi đó nếu ta chạy lại câu lệnh trên, MySQL sẽ sử dụng chỉ mục idx_department để truy xuất nhanh các hàng có department = ‘IT’, thay vì quét toàn bộ bảng.
Sự khác nhau giữa MyISAM và InnoDB là gì?
MyISAM là Storage Engine mặc định trong các phiên bản MySQL cũ, được thiết kế để xử lý các truy vấn đơn giản, tốc độ cao và không yêu cầu các tính năng nâng cao như khóa ngoại.
InnoDB là Storage Engine hiện đại và hiện tại cũng là engine mặc định trong MySQL. Nó hỗ trợ một số tính năng quan trọng như:
- Giao dịch (transactions): Đảm bảo tính toàn vẹn dữ liệu thông qua các đặc tính ACID (Atomicity, Consistency, Isolation, Durability).
- Khóa ngoại (foreign key constraints): Duy trì tính toàn vẹn tham chiếu giữa các bảng.
InnoDB là engine thích hợp cho các ứng dụng yêu cầu độ tin cậy và tính toàn vẹn dữ liệu cao.
MyISAM và InnoDB có một số điểm khác biệt như sau:
Tiêu chí | MyISAM | InnoDB |
Hỗ trợ giao dịch (Transactions) | Không hỗ trợ. | Hỗ trợ đầy đủ giao dịch với các đặc tính ACID (Atomicity, Consistency, Isolation, Durability). |
Khóa ngoại (Foreign Key) | Không hỗ trợ. | Hỗ trợ, đảm bảo tính toàn vẹn dữ liệu giữa các bảng. |
Tốc độ đọc/ghi | Tốc độ nhanh hơn khi chỉ thực hiện đọc vì không có tính năng phức tạp như khóa ngoại hay giao dịch. | Chậm hơn MyISAM trong một số trường hợp vì phải quản lý các tính năng nâng cao.
Nhưng sẽ tốt hơn khi có nhiều thao tác đọc/ghi đồng thời. |
Khóa bảng (Table Lock) | Sử dụng khóa toàn bảng (table-level locking), dẫn đến hiệu năng kém khi có nhiều thao tác thêm/xóa/sửa đồng thời. | Sử dụng khóa dòng (row-level locking), cho phép hiệu năng tốt hơn khi ghi dữ liệu song song. |
Khôi phục dữ liệu | Không hỗ trợ khôi phục dữ liệu sau lỗi hệ thống. | Hỗ trợ khôi phục tự động sau lỗi nhờ cơ chế redo log. |
Tính toàn vẹn dữ liệu | Không đảm bảo tính toàn vẹn cao (vì không có giao dịch và khóa ngoại). | Đảm bảo tính toàn vẹn cao nhờ hỗ trợ giao dịch và khóa ngoại. |
Kích thước tệp | Tệp bảng nhỏ hơn vì không có các tính năng giao dịch. | Kích thước lớn hơn do lưu trữ thêm metadata và thông tin giao dịch. |
Ứng dụng phù hợp | Phù hợp cho hệ thống đọc nhiều hơn ghi, như các trang web tĩnh hoặc hệ thống báo cáo. | Thích hợp cho các ứng dụng đòi hỏi độ tin cậy cao, như hệ thống tài chính, thương mại điện tử. |
Làm thế nào để tạo một View trong MySQL?
View trong MySQL là một bảng ảo được tạo dựa trên kết quả của một câu lệnh truy vấn SQL. View không lưu trữ dữ liệu thực tế, mà chỉ lưu trữ định nghĩa câu truy vấn. Khi bạn truy vấn một View, MySQL sẽ chạy câu truy vấn gốc và trả về kết quả như một bảng.
Cú pháp tạo view tổng quát:
CREATE VIEW view_name AS SELECT column1, column2, ... FROM table_name WHERE condition;
Giả sử ta có bảng employees như sau:
id | name | department | salary |
1 | John Doe | IT | 5000 |
2 | Jane Smith | HR | 6000 |
3 | Alice Brown | IT | 7000 |
4 | Bob Johnson | Finance | 8000 |
Ví dụ để tạo một View high_salary_employees hiển thị nhân viên có lương trên 6000, ta sử dụng cú pháp như sau:
CREATE VIEW high_salary_employees AS SELECT name, department, salary FROM employees WHERE salary > 6000;
Sau khi tạo, ta có thể truy vấn View giống như một bảng với cú pháp:
SELECT * FROM high_salary_employees;
Ta được kết quả như sau:
name | department | salary |
Alice Brown | IT | 7000 |
Bob Johnson | Finance | 8000 |
Ứng dụng của view trong MySQL là gì?
- Đơn giản hóa truy vấn phức tạp: View giúp lưu trữ các truy vấn phức tạp và sử dụng lại chúng như một bảng, giảm bớt việc phải viết lại câu truy vấn nhiều lần.
- Tăng tính bảo mật: View cho phép kiểm soát quyền truy cập. Bạn có thể cấp quyền cho người dùng chỉ trên View thay vì bảng gốc, ẩn đi các cột nhạy cảm.
- Tăng tính linh hoạt trong quản lý dữ liệu: View có thể được sử dụng để tổng hợp dữ liệu từ nhiều bảng khác nhau, giúp truy vấn dữ liệu một cách dễ dàng và nhất quán.
- Đảm bảo tính nhất quán của dữ liệu: Sử dụng View để chuẩn hóa các truy vấn và dữ liệu hiển thị, giúp các truy vấn phức tạp trả về dữ liệu chính xác hơn.
- Hỗ trợ phân tích dữ liệu: View hữu ích trong các báo cáo, nơi dữ liệu được lọc hoặc tổng hợp theo các điều kiện cụ thể.
Một số lưu ý khi sử dụng View:
- Hiệu suất: Vì View không lưu trữ dữ liệu, mỗi lần truy vấn View, MySQL phải thực thi lại câu truy vấn gốc, dẫn đến ảnh hưởng đến hiệu suất nếu câu truy vấn gốc phức tạp.
- Giới hạn cập nhật: Không phải View nào cũng có thể được cập nhật. Các View phức tạp (dùng hàm tổng hợp, GROUP BY, JOIN) thường chỉ cho phép đọc dữ liệu.
- Quản lý thay đổi: Nếu cấu trúc bảng gốc thay đổi (xóa hoặc đổi tên cột), View liên quan có thể bị lỗi và cần được cập nhật lại.
Triggers trong MySQL là gì? Làm thế nào để tạo một Trigger?
Trigger trong MySQL là một thủ tục lưu trữ đặc biệt tự động thực thi khi có một sự kiện cụ thể xảy ra trên một bảng trong cơ sở dữ liệu. Trigger được sử dụng để xử lý tự động các tác vụ như kiểm tra tính toàn vẹn dữ liệu, ghi log, hoặc thực hiện các thao tác khác trước hoặc sau khi thực hiện các câu lệnh INSERT, UPDATE hoặc DELETE.
Cú pháp tạo Trigger:
CREATE TRIGGER trigger_name {BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name FOR EACH ROW BEGIN -- SQL code to execute END;
Trong đó:
- BEFORE hoặc AFTER: Xác định thời điểm thực thi Trigger (trước hoặc sau sự kiện).
- INSERT | UPDATE | DELETE: Xác định loại sự kiện kích hoạt Trigger.
- table_name: Bảng mà Trigger gắn liền.
- FOR EACH ROW: Xác định Trigger sẽ áp dụng cho từng hàng được tác động bởi sự kiện.
- SQL code: là đoạn mã SQL sẽ được thực thi khi Trigger được kích hoạt.
Ví dụ: giả sử ta có bảng employees và muốn lưu log mỗi khi có bản ghi mới được chèn vào bảng này, ta có thể tạo Trigger như sau:
CREATE TRIGGER after_employee_insert AFTER INSERT ON employees FOR EACH ROW BEGIN INSERT INTO employee_logs (log_message) VALUES (CONCAT('New employee added: ', NEW.name)); END;
Trong đó:
- AFTER INSERT: Trigger được thực thi sau khi chèn dữ liệu vào bảng employees.
- NEW: Là từ khóa đại diện cho dữ liệu mới được chèn vào.
- CONCAT: Kết hợp chuỗi để tạo thông báo log.
Lưu ý khi sử dụng Trigger
Mặc dù Trigger giúp góp phần đảm bảo tính toàn vẹn của dữ liệu và thực hiện các tác vụ tự động, giúp giảm thiểu lỗi thủ công và tăng tính tự động hóa nhưng khi sử dụng trigger cần lưu ý một số vấn đề như:
- Hiệu suất: Trigger có thể làm giảm hiệu suất nếu sử dụng các truy vấn phức tạp hoặc tính toán lớn.
- Không tương tác trực tiếp: Trigger không thể gọi trực tiếp từ câu lệnh SQL mà chỉ kích hoạt khi có sự kiện xảy ra.
Giới hạn trong Trigger:
- Trigger không hỗ trợ sử dụng toàn bộ các lệnh SQL (như COMMIT, ROLLBACK).
- Trigger không thể trực tiếp gọi một Trigger khác (tránh vòng lặp vô hạn).
Stored Procedures và Functions khác nhau như thế nào?
Tiêu chí | Stored Procedures | Functions |
Định nghĩa | Một tập hợp các câu lệnh SQL được lưu trữ trong cơ sở dữ liệu để thực thi nhiều thao tác. | Một tập hợp các câu lệnh SQL được lưu trữ để thực hiện một tác vụ cụ thể và trả về một giá trị. |
Output | Không bắt buộc phải trả về giá trị, nhưng có thể trả về thông qua tham số đầu ra (OUT parameter). | Luôn trả về một giá trị duy nhất. |
Cách gọi | Được gọi bằng lệnh CALL. | Được gọi trực tiếp trong các câu lệnh SQL như SELECT hoặc trong các biểu thức. |
Sử dụng trong câu lệnh SQL | Không thể sử dụng trực tiếp trong câu lệnh SELECT. | Có thể sử dụng trực tiếp trong câu lệnh SQL như SELECT, WHERE, ORDER BY hoặc JOIN. |
Tham số | Hỗ trợ tham số đầu vào (IN), đầu ra (OUT) và cả đầu vào/đầu ra (INOUT). | Chỉ hỗ trợ tham số đầu vào (IN). |
Mục đích | Thường được sử dụng để thực hiện các tác vụ phức tạp hoặc thao tác trên dữ liệu. | Thường được sử dụng để thực hiện các tính toán hoặc trả về kết quả dựa trên đầu vào. |
Gọi nhiều lần trong truy vấn | Không phù hợp để gọi lặp lại trong một truy vấn vì không thể sử dụng trong biểu thức. | Phù hợp để gọi nhiều lần trong một truy vấn (ví dụ: sử dụng trong cột tính toán). |
Độ phức tạp | Có thể bao gồm nhiều câu lệnh SQL, vòng lặp, điều kiện, và các thủ tục khác. | Đơn giản hơn, tập trung vào tính toán và trả về giá trị. |
Hỗ trợ giao dịch | Có thể thực hiện các lệnh như COMMIT và ROLLBACK. | Không hỗ trợ giao dịch như COMMIT và ROLLBACK. |
Hiệu suất | Phù hợp với các thao tác dữ liệu lớn hoặc logic phức tạp. | Phù hợp cho các phép tính toán hoặc xử lý dữ liệu nhỏ. |
Ứng dụng | Xử lý logic phức tạp: thêm, sửa, hoặc xóa dữ liệu trong bảng. | Tính toán: tính tổng, trả về kết quả từ các cột hoặc giá trị. |
Subquery là gì?
Subquery (truy vấn con) trong MySQL là một câu truy vấn SQL lồng bên trong một câu truy vấn khác và thường được bao trong dấu ngoặc đơn (). Subquery được sử dụng để trả về dữ liệu mà câu truy vấn bên ngoài sẽ sử dụng để thực hiện các tác vụ khác. Subquery thường xuất hiện trong các mệnh đề như SELECT, FROM, WHERE hoặc HAVING.
Ví dụ cú pháp Subquery trong mệnh đề Where:
SELECT column1, column2, ... FROM table_name WHERE column_name operator (SELECT column_name FROM another_table WHERE condition);
Giả sử ta có 2 bảng:
- Bảng employees:
id | name | department_id |
1 | John Doe | 101 |
2 | Jane Smith | 102 |
3 | Alice Brown | 101 |
- Bảng Departments:
id | name |
101 | IT |
102 | HR |
103 | Marketing |
Ví dụ để tìm nhân viên thuộc phòng IT, ta sử dụng cú pháp sau:
Cách 1: Sử dụng IN
SELECT name FROM Employees WHERE department_id IN (SELECT id FROM Departments WHERE name = 'IT');
Cách 2: Thêm LIMIT 1 vào subquery
SELECT name FROM Employees WHERE department_id = (SELECT id FROM Departments WHERE name = 'IT' LIMIT 1);
Giải thích:
- Toán tử IN: Phù hợp khi subquery có thể trả về nhiều giá trị. Lựa chọn này an toàn và chính xác hơn khi có khả năng nhiều phòng ban cùng tên “IT”.
- LIMIT 1: Sử dụng trong trường hợp chắc chắn chỉ cần lấy một giá trị đầu tiên từ subquery, điều này sẽ tránh lỗi khi subquery trả về nhiều giá trị.
Các câu hỏi phỏng vấn MySQL dành cho Advanced
Replication trong MySQL hoạt động như thế nào?
Replication trong MySQL là quá trình sao chép dữ liệu từ một máy chủ cơ sở dữ liệu (Master) sang một hoặc nhiều máy chủ khác (Slave). Replication giúp cải thiện tính sẵn sàng (availability), khả năng mở rộng (scalability), và khả năng sao lưu (backup) của cơ sở dữ liệu.
Các thành phần chính trong Replication
- Primary (Master): Máy chủ chính, nơi các thay đổi dữ liệu (INSERT, UPDATE, DELETE) được thực hiện và ghi lại trong Binary Log.
- Replica (Slave): Máy chủ phụ, sao chép dữ liệu từ Primary thông qua các nhật ký và thực hiện lại các thay đổi để đồng bộ hóa dữ liệu.
Cách hoạt động của Replication trong MySQL
Replication trong MySQL hoạt động dựa trên mô hình Master-Slave, theo các bước sau:
- Ghi nhật ký giao dịch trên Master (Binary Log): Khi dữ liệu được chèn, cập nhật, hoặc xóa trên máy chủ Master, các thay đổi này sẽ được ghi vào Binary Log (tệp nhật ký nhị phân). Binary Log chứa thông tin về các thay đổi ở dạng sự kiện (event).
- Sao chép nhật ký giao dịch từ Master đến Slave: Máy chủ Slave kết nối với Master và sao chép dữ liệu trong Binary Log thông qua hai luồng: I/O Thread và SQL Thread.
- Áp dụng các thay đổi trên Slave: Máy chủ Replica không đọc trực tiếp từ Binary Log. Thay vào đó, sau khi các sự kiện được sao chép từ Binary Log về Relay Log, Replica sẽ đọc nội dung từ Relay Log và thực hiện lại các thay đổi trên cơ sở dữ liệu của nó.
- Đồng bộ hóa dữ liệu: Quá trình sao chép diễn ra gần như liên tục, đảm bảo dữ liệu trên Slave luôn phản ánh các thay đổi mới nhất trên Master.
Chuẩn hóa là gì?
Chuẩn hóa (Normalization) trong cơ sở dữ liệu là một quá trình tổ chức dữ liệu trong các bảng để giảm thiểu sự dư thừa (redundancy) và đảm bảo tính toàn vẹn của dữ liệu.
Mục tiêu của chuẩn hóa là tổ chức dữ liệu hợp lý để tránh dư thừa và đảm bảo tính toàn vẹn, thường là phân tách dữ liệu thành các bảng nhỏ hơn, với mỗi bảng tập trung vào một khía cạnh cụ thể, đồng thời duy trì mối quan hệ logic giữa các bảng.
Chuẩn hoá có những loại sau:
Dạng Chuẩn hoá | Yêu cầu Chính | Mục Tiêu | Ví Dụ |
1NF | – Không có giá trị lặp hoặc mảng trong các cột.
– Mỗi cột chỉ chứa một giá trị duy nhất trên mỗi hàng. |
Đảm bảo cấu trúc cơ bản của bảng, dữ liệu có tổ chức rõ ràng. | Bảng lưu số điện thoại: Nếu một cột chứa danh sách số điện thoại 1234567890, 0987654321, cần tách thành các hàng riêng biệt. |
2NF | – Đáp ứng 1NF.
– Không có phụ thuộc một phần vào khóa chính. |
Loại bỏ dư thừa do phụ thuộc một phần, tập trung vào khóa chính. | Nếu bảng chứa student_id, course_id và student_name (giả sử student_id, course_id là khóa chính), thì student_name nên được tách ra bảng riêng vì nó phụ thuộc vào student_id, không phụ thuộc course_id. |
3NF | – Đáp ứng 2NF.
– Không có phụ thuộc bắc cầu giữa các cột không phải là khóa. |
Loại bỏ phụ thuộc bắc cầu để tăng tính toàn vẹn và logic dữ liệu. | Nếu bảng chứa student_id, course_id và department_name, thì department_name nên tách ra bảng khác nếu nó chỉ phụ thuộc vào course_id. |
BCNF | – Đáp ứng 3NF.
– Mọi phụ thuộc hàm (functional dependency) phải liên quan đến Candidate Key. |
Xử lý các phụ thuộc phức tạp hơn so với 3NF. | Nếu bảng chứa employee_id, department_id, và manager_id trong đó manager_id phụ thuộc vào department_id, cần tách manager_id ra thành bảng riêng. |
4NF | – Đáp ứng BCNF.
– Không có phụ thuộc đa trị (multivalued dependency). |
Loại bỏ mối quan hệ đa trị giữa các cột. | Nếu bảng lưu thông tin nhân viên và các dự án họ tham gia, cùng với kỹ năng của họ, nên tách thành 2 bảng riêng: một cho dự án và một cho kỹ năng. |
5NF | – Đáp ứng 4NF.
– Loại bỏ phụ thuộc kết hợp (join dependency). |
Tránh dư thừa do các bảng kết hợp phức tạp. | Bảng lưu mối quan hệ giữa khách hàng, sản phẩm, và nhân viên bán hàng cần được tách thành các bảng nhỏ hơn để tránh dư thừa trong các kết hợp ba chiều. |
6NF | – Dữ liệu được phân tách hoàn toàn, không còn dư thừa nào tồn tại dựa trên phụ thuộc hàm thời gian trong cơ sở dữ liệu quan hệ phân tán.
– Thường áp dụng cho cơ sở dữ liệu phân tán. |
Đảm bảo tối ưu hóa dữ liệu trong hệ thống linh hoạt cao. | Thường áp dụng cho các kho dữ liệu lớn. Ví dụ, chia bảng giao dịch thành các bảng lưu riêng từng yếu tố như khách hàng, sản phẩm, và ngày giao dịch để tối ưu hóa. |
Clustered index và non clustered index là gì?
Trong cơ sở dữ liệu, Index (chỉ mục) là một cấu trúc dữ liệu giúp tăng tốc độ truy vấn và thao tác với bảng. Trong đó, có hai loại chỉ mục phổ biến: Clustered Index và Non-Clustered Index.
Tiêu chí | Clustered Index | Non-Clustered Index |
Định nghĩa | Là chỉ mục mà dữ liệu vật lý trong bảng được sắp xếp theo thứ tự của chỉ mục. | Là chỉ mục mà dữ liệu vật lý trong bảng không được sắp xếp theo chỉ mục, chỉ lưu trữ tham chiếu (pointer). |
Sắp xếp dữ liệu | Dữ liệu trong bảng được lưu trữ vật lý theo thứ tự của Clustered Index. | Dữ liệu không bị thay đổi thứ tự lưu trữ vật lý, chỉ mục lưu tham chiếu đến vị trí của dữ liệu. |
Số lượng chỉ mục | Một bảng chỉ có thể có một Clustered Index, vì dữ liệu vật lý chỉ được sắp xếp theo một thứ tự duy nhất. | Một bảng có thể có nhiều Non-Clustered Index. |
Không gian lưu trữ | Không yêu cầu thêm không gian lưu trữ cho chỉ mục (dữ liệu tự sắp xếp). | Yêu cầu thêm không gian lưu trữ để lưu trữ chỉ mục và các tham chiếu. |
Tốc độ truy vấn | Nhanh hơn khi truy vấn các dữ liệu được sắp xếp hoặc lọc theo cột được lập Clustered Index. | Chậm hơn vì cần tra cứu tham chiếu (pointer) để tìm vị trí dữ liệu thực trong bảng. |
Ứng dụng phổ biến | Thường được tạo trên Primary Key để sắp xếp và tăng tốc độ truy vấn dựa trên cột chính. | Thường được tạo trên các cột thường xuyên dùng trong tìm kiếm hoặc lọc dữ liệu (WHERE, JOIN). |
Truy vấn phạm vi (Range Query) | Hiệu quả cao khi thực hiện các truy vấn phạm vi (BETWEEN, <, >, ORDER BY). | Kém hiệu quả hơn trong các truy vấn phạm vi vì cần tham chiếu thêm. |
Thay đổi dữ liệu (INSERT/UPDATE/DELETE) | Thay đổi dữ liệu có thể chậm hơn vì cần sắp xếp lại dữ liệu trong bảng để duy trì thứ tự của Clustered Index. | Không ảnh hưởng đến thứ tự lưu trữ, nhưng cần cập nhật chỉ mục tương ứng với thay đổi dữ liệu. |
Ví dụ | Nếu bảng employees có cột emp_id là Primary Key, Clustered Index sẽ sắp xếp dữ liệu theo thứ tự emp_id. | Non-Clustered Index có thể được tạo trên cột email để tăng tốc độ truy vấn các bản ghi dựa trên tên. |
Trình bày một số phương pháp bảo mật MySQL
Bảo mật MySQL là một bước quan trọng để bảo vệ dữ liệu khỏi các mối đe dọa tiềm ẩn. Một số phương pháp bảo mật MySQL bao gồm:
- Thiết lập mật khẩu mạnh cho người dùng:
-
- Sử dụng mật khẩu phức tạp chứa ký tự đặc biệt, chữ in hoa, in thường và số.
- Đặt mật khẩu khi tạo người dùng và thay đổi mật khẩu định kỳ
- Sử dụng quyền tối thiểu:
-
- Chỉ cấp quyền cần thiết cho người dùng để hạn chế các tác vụ không mong muốn.
- Tránh sử dụng tài khoản root cho các hoạt động thông thường.
- Kiểm soát quyền truy cập bằng địa chỉ (Host): Giới hạn quyền truy cập của người dùng từ các địa chỉ cụ thể, ví dụ: localhost hoặc một IP xác định.
- Sử dụng giao thức SSL: Bật SSL để mã hóa kết nối giữa máy khách và máy chủ MySQL, giúp ngăn chặn việc nghe lén dữ liệu trong mạng.
- Xóa người dùng không cần thiết: Loại bỏ các tài khoản không sử dụng hoặc không rõ nguồn gốc
- Bảo vệ file cấu hình: Đảm bảo file cấu hình MySQL (my.cnf) chỉ có quyền đọc và ghi cho tài khoản quản trị.
- Giám sát và ghi log: Bật log truy cập và giám sát các hoạt động đáng ngờ trong MySQL để phát hiện sớm các mối nguy cơ.
Làm thế nào để tạo người dùng mới và cấp quyền?
Tạo người dùng mới
Sử dụng lệnh CREATE USER để tạo người dùng:
CREATE USER 'username'@'hostname' IDENTIFIED BY 'password';
Trong đó:
- username: Tên người dùng.
- hostname: Máy chủ mà người dùng được phép kết nối, ví dụ: localhost (chỉ từ máy cục bộ) hoặc % (cho phép từ bất kỳ máy chủ nào – không khuyến nghị vì lý do bảo mật).
- password: Mật khẩu người dùng.
Ví dụ để tạo người dùng john với quyền truy cập từ máy cục bộ, ta sử dụng cú pháp:
CREATE USER 'john'@'localhost' IDENTIFIED BY 'strong_password';
Cấp quyền
Lệnh GRANT được sử dụng để cấp quyền cho người dùng trên các cấp độ khác nhau như toàn cơ sở dữ liệu, bảng hoặc cột.
Cú pháp:
GRANT privileges ON database_name.table_name TO 'username'@'hostname';
Trong đó:
- privileges: Các quyền cần cấp như SELECT, INSERT, UPDATE, DELETE, hoặc ALL PRIVILEGES để cấp toàn bộ quyền.
- database_name.table_name: Cơ sở dữ liệu và bảng mà quyền áp dụng (*.* cho toàn bộ cơ sở dữ liệu và bảng).
Ví dụ để cấp quyền SELECT và INSERT trên bảng employees trong cơ sở dữ liệu company ta sử dụng cú pháp:
GRANT SELECT, INSERT ON company.employees TO 'john'@'localhost';
Thu hồi quyền (REVOKE)
Cú pháp:
REVOKE privileges ON database_name.table_name FROM 'username'@'hostname';
Ví dụ để thu hồi quyền INSERT trên bảng employees từ người dùng john, ta sử dụng cú pháp
REVOKE INSERT ON company.employees FROM 'john'@'localhost';
Làm thế nào để thiết lập các phương thức backup dữ liệu?
Backup dữ liệu trong MySQL là một phần quan trọng để bảo vệ dữ liệu khỏi mất mát do lỗi hệ thống, phần cứng hoặc các sự cố bất ngờ khác. MySQL hỗ trợ nhiều phương thức backup, bao gồm Full Backup (sao lưu toàn bộ) và Incremental Backup (sao lưu gia tăng).
Full Backup
Full Backup là quá trình sao lưu toàn bộ dữ liệu của cơ sở dữ liệu, bao gồm cả cấu trúc và dữ liệu trong các bảng. Loại backup này thường được thực hiện định kỳ như hàng ngày hoặc hàng tuần.
Cách thực hiện Full Backup:
Bước 1: Sử dụng công cụ mysqldump với cú pháp như sau:
mysqldump -u [username] -p [database_name] > [backup_file.sql]
Trong đó:
- [username]: Tên người dùng MySQL.
- [database_name]: Tên cơ sở dữ liệu cần sao lưu.
- [backup_file.sql]: Tên tệp để lưu bản sao lưu.
Ví dụ để sao lưu cơ sở dữ liệu company ta sử dụng cú pháp:
mysqldump -u root -p company > company_backup.sql
Bước 2: Sao lưu tất cả cơ sở dữ liệu:
Dùng tùy chọn –all-databases để sao lưu toàn bộ cơ sở dữ liệu trên máy chủ MySQL:
mysqldump -u root -p --all-databases > full_backup.sql
Bước 3: Nén file backup: Để tiết kiệm dung lượng, ta có thể nén file với cú pháp:
mysqldump -u root -p company | gzip > company_backup.sql.gz
Incremental Backup (Sao lưu gia tăng)
Incremental Backup chỉ sao lưu những thay đổi đã diễn ra kể từ lần backup trước đó. Loại backup này tiết kiệm thời gian và dung lượng lưu trữ hơn so với Full Backup.
Cách thực hiện:
Bước 1: Bật chế độ Binary Log
MySQL sử dụng Binary Log để ghi lại các thay đổi trong cơ sở dữ liệu. Đây là điều kiện tiên quyết để thực hiện Incremental Backup. Bật chế độ Binary Log trong file cấu hình MySQL (my.cnf) với cú pháp như sau:
[mysqld] log-bin=mysql-bin server-id=1
Bước 2: Khởi động lại MySQL
Bước 3: Sao lưu Binary Log
Sao chép các file Binary Log để thực hiện Incremental Backup với cú pháp sau:
mysqlbinlog [binary_log_file] > incremental_backup.sql
Trong đó:
- [binary_log_file] là tên file log
Bước 4: Sau khi sao lưu Binary Log, bạn có thể xóa log cũ để tiết kiệm dung lượng với cú pháp:
RESET MASTER;
Làm thế nào để tối ưu hóa cấu trúc bảng?
Tối ưu hóa cấu trúc bảng và chỉ mục là một bước quan trọng để cải thiện hiệu suất cơ sở dữ liệu MySQL. Dưới đây là các phương pháp:
Chọn kiểu dữ liệu phù hợp
Sử dụng kiểu dữ liệu chính xác và phù hợp với phạm vi giá trị lưu trữ để tiết kiệm không gian lưu trữ và tăng tốc độ xử lý.
- Sử dụng INT thay vì BIGINT nếu giá trị không vượt quá phạm vi của INT.
- Sử dụng VARCHAR thay vì TEXT cho các chuỗi ngắn.
- Chọn kiểu dữ liệu ngày như DATE, DATETIME hoặc TIMESTAMP phù hợp với yêu cầu.
Tránh sử dụng kiểu dữ liệu không cần thiết
Tránh sử dụng các kiểu dữ liệu quá lớn cho các cột ít được truy cập. Ví dụ dùng ENUM hoặc SET thay cho VARCHAR khi cột chỉ chứa một số giá trị cố định.
Chuẩn hóa cơ sở dữ liệu
Áp dụng các quy tắc chuẩn hóa để loại bỏ sự dư thừa dữ liệu. Tuy nhiên, đối với các hệ thống lớn, cân nhắc giữa chuẩn hóa và hiệu suất (denormalization) để giảm số lượng JOIN.
Sử dụng Partitioning
Chia bảng lớn thành các phần nhỏ hơn bằng Partitioning để cải thiện hiệu suất truy vấn, đặc biệt với các bảng có hàng triệu bản ghi.
Làm thế nào để tối ưu hóa cấu trúc các chỉ mục?
Tạo chỉ mục cho các cột thường xuyên được truy vấn
Đảm bảo các cột trong mệnh đề WHERE, JOIN hoặc ORDER BY được chỉ mục để tăng tốc độ truy vấn.
Sử dụng chỉ mục phù hợp với loại truy vấn
- B-Tree Index: Phù hợp với hầu hết các truy vấn thông thường (=, >, <, BETWEEN, LIKE ‘abc%’).
- Hash Index: Nhanh hơn cho các truy vấn chính xác (=), nhưng không hỗ trợ phạm vi.
- Full-Text Index: Hữu ích cho tìm kiếm văn bản với các cột kiểu TEXT hoặc VARCHAR.
Chỉ số nhiều cột (Composite Index)
Nếu truy vấn sử dụng nhiều cột cùng lúc, hãy tạo chỉ mục trên các cột đó và đảm bảo thứ tự các cột trong chỉ mục phù hợp với thứ tự trong truy vấn.
Ví dụ: Nếu thường tìm kiếm theo name và age, hãy tạo chỉ mục (name, age).
Không tạo quá nhiều chỉ mục
Quá nhiều chỉ mục làm chậm thao tác ghi (INSERT, UPDATE, DELETE). Hãy kiểm tra chỉ mục nào thực sự cần.
Sử dụng chỉ mục duy nhất (Unique Index)
Sử dụng chỉ mục duy nhất để đảm bảo tính toàn vẹn dữ liệu, đặc biệt với các cột như email, username.
Kiểm tra và bảo trì chỉ mục
Sử dụng câu lệnh ANALYZE TABLE và OPTIMIZE TABLE để đánh giá và tối ưu hóa hiệu suất của các chỉ mục.
Sharding là gì? Khi nào nên sử dụng sharding?
Sharding là một kỹ thuật phân chia dữ liệu trong cơ sở dữ liệu thành các phân đoạn nhỏ hơn (gọi là shard) và phân phối các phân đoạn này trên nhiều máy chủ khác nhau. Mỗi shard hoạt động như một cơ sở dữ liệu độc lập, chứa một phần dữ liệu tổng thể.
Thay vì lưu trữ toàn bộ dữ liệu trên một máy chủ duy nhất, Sharding giúp phân phối dữ liệu để giảm tải và cải thiện hiệu suất.
Cách hoạt động của Sharding
Dữ liệu được chia thành các shard dựa trên một sharding key, thường là một cột hoặc một nhóm cột trong bảng. Sharding key phải đảm bảo tính duy nhất và phân phối dữ liệu đều để tránh tình trạng shard quá tải hoặc mất cân bằng tải. Một số phương pháp Sharding phổ biến bao gồm:
- Horizontal Sharding (Phân đoạn ngang): Dữ liệu được chia theo hàng. Ví dụ: mỗi shard chứa một tập hợp các bản ghi dựa trên UserID hoặc Region.
- Vertical Sharding (Phân đoạn dọc): Dữ liệu được chia theo cột. Ví dụ: các cột quan trọng (thường xuyên truy cập) được đặt trên một shard riêng.
- Hash Sharding: Sử dụng hàm băm trên giá trị của sharding key để phân phối dữ liệu vào các shard.
Ưu và nhược điểm của Sharding
Ưu điểm | Nhược điểm |
Tăng hiệu suất: Xử lý tải đọc/ghi lớn dễ dàng. | Phức tạp hơn: Quản lý nhiều máy chủ shard phức tạp hơn một máy chủ duy nhất. |
Mở rộng dễ dàng: Thêm shard để mở rộng hệ thống. | Khó khăn trong truy vấn liên shard: JOIN hoặc tổng hợp dữ liệu trên nhiều shard mất thời gian hơn. |
Giảm rủi ro sự cố: Sự cố trên một shard không ảnh hưởng đến toàn hệ thống. | Cân bằng tải: Phân phối dữ liệu không đều có thể dẫn đến shard quá tải. |
Linh hoạt với dữ liệu lớn: Quản lý cơ sở dữ liệu có dung lượng vượt quá giới hạn phần cứng. | Tăng độ phức tạp: Backup, đồng bộ, và tái phân phối dữ liệu giữa các shard khó khăn hơn. |
Khi nào nên sử dụng Sharding?
Sharding phù hợp với các hệ thống lớn, phức tạp và có khối lượng dữ liệu lớn. Sharding nên được sử dụng khi:
- Dữ liệu quá lớn để lưu trữ trên một máy chủ duy nhất: Khi kích thước cơ sở dữ liệu vượt quá dung lượng ổ đĩa hoặc bộ nhớ của máy chủ, Sharding cho phép chia nhỏ dữ liệu để lưu trữ trên nhiều máy chủ.
- Hiệu suất truy vấn giảm do tải nặng: Khi một máy chủ duy nhất không thể xử lý số lượng lớn truy vấn đọc và ghi, Sharding phân tán tải trên nhiều máy chủ để tăng hiệu suất.
- Cần mở rộng hệ thống theo chiều ngang (Horizontal Scaling): Nếu muốn tăng khả năng xử lý mà không cần nâng cấp phần cứng của máy chủ (vertical scaling), Sharding giúp mở rộng bằng cách thêm nhiều máy chủ hơn.
- Dữ liệu có thể phân đoạn rõ ràng: Nếu dữ liệu có thể được chia nhỏ dựa trên các sharding key tự nhiên, như UserID, Region hoặc Timestamp, thì Sharding là lựa chọn phù hợp.
Tổng kết câu hỏi phỏng vấn MySQL
Bên cạnh nắm vững các lý thuyết từ cơ bản đến chuyên sâu, ứng viên cũng cần trang bị thêm một số câu trả lời về các kinh nghiệm sử dụng thực tiễn để có thể chinh phục được các nhà tuyển dụng. ITviec hy vọng bài viết về các câu hỏi phỏng vấn MySQL trên đã giúp ích cho các bạn trong quá trình chuẩn bị hành trang để có thể tìm được vị trí nghề nghiệp phù hợp.