CodeGym /Các khóa học /SQL SELF /Thay đổi kiểu dữ liệu của cột

Thay đổi kiểu dữ liệu của cột

SQL SELF
Mức độ , Bài học
Có sẵn

Hãy tưởng tượng, bạn đang tạo bảng sinh viên cho trường đại học. Lại nữa! :)

Lúc đầu bạn quyết định trường tuổi age sẽ là số nguyên và đặt kiểu SMALLINT (phù hợp cho số từ -32,768 đến 32,767). Nhưng sau một thời gian, database lớn dần, bạn thêm thông tin sinh viên từ các nước khác, họ lại ghi tuổi... bằng số ngày từ khi sinh! Lúc này SMALLINT của bạn không đủ nữa — đã đến lúc chuyển sang, ví dụ, INTEGER.

Đây là vài trường hợp phổ biến khác khi bạn phải đổi kiểu dữ liệu:

  1. Tăng hoặc giảm phạm vi số.
  2. Thay đổi độ dài chuỗi (ví dụ, từ VARCHAR(50) sang VARCHAR(100)).
  3. Chuyển sang kiểu dữ liệu khác để tối ưu (ví dụ, chuyển TEXT thành VARCHAR).
  4. Lỡ chọn sai kiểu cột lúc đầu (ví dụ, bạn chọn BOOLEAN thay vì INTEGER).

Cú pháp lệnh thay đổi kiểu dữ liệu

Trong PostgreSQL, thay đổi kiểu dữ liệu của cột dùng lệnh ALTER TABLE. Lệnh này giúp bạn điều chỉnh cấu trúc bảng cho phù hợp nhu cầu mới.

ALTER TABLE table_name
ALTER COLUMN column_name TYPE new_data_type;

Rất đơn giản: bạn chỉ cần ghi tên bảng, cột muốn đổi và kiểu dữ liệu mới cho nó.

Ví dụ 1: Chuyển từ INTEGER sang BIGINT

Giả sử bạn có bảng sinh viên:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INTEGER
);

Mọi thứ đều ổn cho đến khi tuổi vượt quá hàng triệu năm (đừng hỏi, chỉ là ví dụ thôi!). Để làm PostgreSQL yên tâm, hãy đổi kiểu cột age từ INTEGER sang BIGINT:

ALTER TABLE students
ALTER COLUMN age TYPE BIGINT;

Ví dụ 2: Tăng độ dài chuỗi

Bạn tạo bảng lưu các khoá học và đặt tên khoá học tối đa 50 ký tự:

CREATE TABLE courses (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50)
);

Nhưng rồi phát hiện ra tên khoá học phức tạp và dài hơn bạn nghĩ. Giải quyết rất dễ:

ALTER TABLE courses
ALTER COLUMN name TYPE VARCHAR(150);

Ví dụ 3: Chuyển đổi kiểu

Giả sử bạn có bảng mà trường birth_date lưu dưới dạng text:

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    birth_date TEXT
);

Bạn nhận ra làm việc với ngày tháng kiểu TEXT rất bất tiện, vì không thể lọc hay sắp xếp. Giải pháp? Chuyển TEXT thành DATE:

ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE USING birth_date::DATE;

Lưu ý phần USING birth_date::DATE. Nó bảo PostgreSQL phải chuyển đổi dữ liệu trước khi đổi kiểu.

Tại sao đôi khi cần chuyển đổi dữ liệu rõ ràng?

Khi PostgreSQL gặp đổi kiểu, nó sẽ tự động thử chuyển dữ liệu sang kiểu mới. Nếu không được, sẽ báo lỗi. Ví dụ, đổi trường TEXT sang INTEGER mà không nói rõ cách chuyển text thành số sẽ fail ngay.

Ví dụ lỗi

ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE;
-- Lỗi: không thể chuyển giá trị 'not a date' sang kiểu DATE.

Có cách giải quyết. Thêm chuyển đổi dữ liệu rõ ràng bằng USING:

ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE USING to_date(birth_date, 'YYYY-MM-DD');

Ở đây mình dùng hàm to_date() để chuyển chuỗi thành ngày tháng.

Lệnh USING

Trong PostgreSQL, khi bạn đổi kiểu cột bằng ALTER TABLE ... ALTER COLUMN ... TYPE, đôi khi phải chỉ rõ cách chuyển dữ liệu cũ — lúc này dùng từ khoá USING.

Cú pháp:

ALTER TABLE table_name
ALTER COLUMN column_name TYPE new_data_type
USING expression;

Giải thích:

  • USING cho phép bạn ghi rõ công thức chuyển đổi giá trị từ kiểu cũ sang kiểu mới.
  • Rất hữu ích khi không thể chuyển tự động hoặc chuyển đổi không rõ ràng.

Ví dụ đơn giản: chuỗi → số

ALTER TABLE users
ALTER COLUMN age TYPE INTEGER
USING age::INTEGER;

Ở đây age ban đầu là TEXT, mình muốn chuyển sang INTEGER. USING age::INTEGER là chuyển đổi kiểu rõ ràng.

Ví dụ: text → date

ALTER TABLE events
ALTER COLUMN event_date TYPE DATE
USING TO_DATE(event_date, 'YYYY-MM-DD');

Nếu event_date là text kiểu '2023-10-25', mình bảo PostgreSQL cách chuyển nó thành kiểu DATE.

Khi nào USING là bắt buộc?

  • Khi không có chuyển đổi kiểu trực tiếp.
  • Khi dữ liệu cần biến đổi.
  • Khi kiểu không tương thích (TEXTBOOLEAN, VARCHARINTEGER v.v.).

Lỗi thường gặp khi đổi kiểu dữ liệu

Lỗi khi không chuyển đổi dữ liệu. Nếu dữ liệu không tự động chuyển sang kiểu mới được, nhất định phải ghi cách chuyển bằng USING.

ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE;
-- Lỗi: cột 'birth_date' chứa giá trị không hợp lệ cho kiểu DATE

Lệnh này sẽ khoá bảng. Lưu ý, đổi kiểu dữ liệu có thể khoá bảng không cho ghi cho đến khi xong. Đặc biệt quan trọng với bảng lớn. Hãy lên kế hoạch đổi vào lúc ít người dùng.

Vấn đề với bảng liên kết và khoá ngoại. Nếu cột là một phần của khoá ngoại, đổi kiểu sẽ phức tạp hơn. PostgreSQL sẽ yêu cầu tạo lại khoá ngoại.

Mẹo hữu ích

Luôn kiểm tra dữ liệu hiện tại. Dùng truy vấn kiểu SELECT DISTINCT column_name trước khi đổi kiểu để xem dữ liệu có chuyển được không.

Test trước khi đổi thật. Tạo bản sao tạm của bảng và thử đổi trên đó trước khi đổi bảng chính. Ví dụ:

CREATE TEMP TABLE temp_students AS SELECT * FROM students;

Đừng quên USING. Đây là cứu tinh khi đổi kiểu dữ liệu mạnh (ví dụ, TEXTNUMERIC).

Giờ bạn đã biết cách đổi kiểu dữ liệu cột trong PostgreSQL rồi nhé. Hy vọng lần tới cần chỉnh lại cấu trúc dữ liệu, bạn sẽ tự tin hơn. Bảng cũng thông minh lắm, nhưng đôi khi cũng cần nâng cấp mà!

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION