MySQL: Uma explicação detalhada e um guia de seleção para…
Última atualização: 2026-08-26
Os tipos de dados determinam como os dados são armazenados, quanto espaço ocupam e quais operações podem ser realizadas sobre eles — escolher o tipo errado pode ter consequências graves.
Esta aula oferece uma visão geral sistemática de todos os tipos de dados do MySQL e das estratégias para selecioná-los.
graph TB
A[MySQL Data Types] --> B[Integer Types]
A --> C[Floating-point/Fixed-point type]
A --> D[String Type]
A --> E[Date and Time Type]
A --> F[JSON Type]
B --> B1[TINYINT]
B --> B2[SMALLINT]
B --> B3[INT]
B --> B4[BIGINT]
C --> C1[FLOAT]
C --> C2[DOUBLE]
C --> C3[DECIMAL]
D --> D1[CHAR]
D --> D2[VARCHAR]
D --> D3[TEXT]
D --> D4[ENUM]
E --> E1[DATE]
E --> E2[DATETIME]
E --> E3[TIMESTAMP]
1. O que você vai aprender
- Tipos inteiros (de TINYINT a BIGINT)
- Tipos de ponto flutuante e ponto fixo (FLOAT/DOUBLE/DECIMAL)
- Tipos de cadeia de caracteres (CHAR/VARCHAR/TEXT/ENUM)
- Tipos de data e hora (DATE/DATETIME/TIMESTAMP)
- Tipo JSON (MySQL 8.0+)
2. Uma história real sobre uma questão de precisão
(1) Problema: O valor foi calculado incorretamente
Um sistema de comércio eletrônico armazena os preços dos produtos como FLOAT:
-- Demonstration of Floating-Point Precision Loss
SELECT 0.1 + 0.2; -- Results: 0.300000004(approximate value,Inaccurate)
-- It becomes more apparent after it is entered into the table
CREATE TABLE float_demo (price FLOAT);
INSERT INTO float_demo VALUES (199.99);
SELECT price FROM float_demo; -- Results: 199.99(The display is correct, but there is a slight error in the internal storage.)
SELECT price + 0.01 FROM float_demo; -- Cumulative errors may become apparent during calculations
Após 1.000 transações, o erro de precisão acumulado causou uma discrepância de alguns yuans na reconciliação financeira.
(2) Solução para DECIMAL
-- DECIMAL Precise Storage,No error
CREATE TABLE decimal_demo (price DECIMAL(10,2));
INSERT INTO decimal_demo VALUES (199.99);
SELECT price + 0.01 FROM decimal_demo; -- Results: 200.00(Accurate)
Resultado: price = 200.00, preciso, sem erros.
| Tipo | Precisão | Cenários aplicáveis |
|---|---|---|
| FLOAT | Aproximado (6–7 dígitos) | Cálculos científicos; não é necessária precisão |
| DOUBLE | Aproximado (15–16 bits) | Computação científica |
| DECIMAL | Precisão | Valores, dados financeiros |
3. Tipos inteiros
| Tipo | Bytes | Intervalo com sinal | Intervalo sem sinal |
|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2 | -32.768 ~ 32.767 | 0 ~ 65.535 |
| MEDIUMINT | 3 | -8.388.608 ~ 8.388.607 | 0 ~ 16.777.215 |
| Entrada | 4 | -2.147.483.648 ~ 2.147.483.647 | 0 ~ 4.294.967.295 |
| BIGINT | 8 | -9.223.372.036.854.775.808 ~ 9.223.372.036.854.775.807 | 0 ~ 18.446.744.073.709.551.615 |
▶ Exemplo: Tipos inteiros
CREATE TABLE user_stats (
id INT PRIMARY KEY AUTO_INCREMENT,
age TINYINT UNSIGNED, -- Age 0-255 Enough
view_count INT UNSIGNED, -- Number of views
total_orders BIGINT UNSIGNED -- Total Number of Orders(It's very likely)
);
-- UNSIGNED Indicates unsigned(Only positive numbers)
INSERT INTO user_stats (age, view_count, total_orders)
VALUES (25, 1000000, 9999999999);
TINYINT para a idade e BIGINT para o ID do usuário.
4. Tipos de ponto flutuante e ponto fixo
| Tipo | Bytes | Precisão | Casos de uso |
|---|---|---|---|
| FLOAT | 4 | 6–7 dígitos | Computação científica |
| DUPLO | 8 | 15–16 bits | Computação Científica |
| DECIMAL(M,D) | Variável | Exato | Valores, Finanças |
M = número total de dígitos, D = número de casas decimais.
DECIMAL(10,2)indica até 10 dígitos inteiros + 2 casas decimais.
▶ Exemplo: Como usar DECIMAL
CREATE TABLE financials (
id INT PRIMARY KEY,
amount DECIMAL(12,2), -- Amount,Maximum 9999999999.99
rate DECIMAL(5,4), -- Ratio,Maximum 9.9999
quantity DECIMAL(8,0) -- Number of integers
);
INSERT INTO financials VALUES (1, 1234567.89, 0.0850, 1000);
SELECT * FROM financials;
Saída:
+----+-------------+--------+----------+
| id | amount | rate | quantity |
+----+-------------+--------+----------+
| 1 | 1234567.89 | 0.0850 | 1000 |
+----+-------------+--------+----------+
5. Tipo String
| Tipo | Comprimento máximo | Características | Casos de uso |
|---|---|---|---|
| CHAR(N) | 255 bytes | Comprimento fixo, rápido | Números de celular, números de identificação, MD5 |
| VARCHAR(N) | 65.535 bytes | Comprimento variável, economiza espaço | Nome de usuário, e-mail, cargo |
| TINYTEXT | 255 bytes | Texto | Texto curto |
| TEXTO | 65.535 bytes | Texto | Conteúdo do artigo |
| MEDIUMTEXT | 16M | Texto | Artigo longo |
| TEXTO LONGO | 4G | Texto | Texto extralongo |
| ENUM | 65.535 valores | Enumeração | Status, Tipo |
| CONJUNTO | 64 valores | Conjunto | Rótulos de seleção múltipla |
(1) CHAR vs VARCHAR
-- CHAR(10) Fixed length, storing 'abc' uses 10 bytes
-- VARCHAR(10) Variable length, storing 'abc' uses 4 bytes (3 + 1 length prefix)
CREATE TABLE phones (
-- Mobile Number (Fixed 11 digits), use CHAR for faster lookup
mobile CHAR(11),
-- Username length varies, use VARCHAR to save space
username VARCHAR(50)
);
▶ Exemplo: Tipo de enumeração ENUM
CREATE TABLE orders (
id INT PRIMARY KEY,
status ENUM('pending', 'paid', 'shipped', 'completed', 'cancelled') DEFAULT 'pending'
);
INSERT INTO orders (id, status) VALUES (1, 'paid');
INSERT INTO orders (id) VALUES (2); -- Default 'pending'
-- ENUM stores numerical indexes (1,2,3...), not strings
SELECT status, status + 0 AS index_num FROM orders;
Saída:
+---------+-----------+
| status | index_num |
+---------+-----------+
| paid | 2 |
| pending | 1 |
+---------+-----------+
6. Tipos de data e hora
| Tipo | Formato | Intervalo | Bytes |
|---|---|---|---|
| DATA | AAAA-MM-DD | 1º de janeiro de 1000 ~ 31 de dezembro de 9999 | 3 |
| HORA | HH:MM:SS | -838:59:59 ~ 838:59:59 | 3 |
| DATETIME | AAAA-MM-DD HH:MM:SS | 1000-01-01 ~ 9999-12-31 | 8 |
| CARIMBO DE DATA/HORA | AAAA-MM-DD HH:MM:SS | 01/01/1970 ~ 19/01/2038 | 4 |
| Ano | AAAA | 1901 ~ 2155 | 1 |
(1) DATETIME x TIMESTAMP
| Dimensão | DATETIME | TIMESTAMP |
|---|---|---|
| Intervalo | 1000–9999 | 1970–2038 |
| Armazenamento | 8 bytes | 4 bytes |
| Fuso horário | Não converter | Converter automaticamente para UTC |
| Recomendação | Data | Hora de criação/modificação do registro |
▶ Exemplo: Como usar datas e horários
CREATE TABLE events (
id INT PRIMARY KEY AUTO_INCREMENT,
event_name VARCHAR(100),
event_date DATE,
start_time TIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
INSERT INTO events (event_name, event_date, start_time)
VALUES ('Tech Conference', '2026-09-15', '09:00:00');
SELECT * FROM events;
Saída:
+----+----------------+------------+------------+---------------------+---------------------+
| id | event_name | event_date | start_time | created_at | updated_at |
+----+----------------+------------+------------+---------------------+---------------------+
| 1 | Tech Conference| 2026-09-15 | 09:00:00 | 2026-07-03 10:00:00 | 2026-07-03 10:00:00 |
+----+----------------+------------+------------+---------------------+---------------------+
7. Tipo de dados JSON (MySQL 8.0+)
▶ Exemplo: Trabalhando com JSON
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
attributes JSON
);
INSERT INTO products (name, attributes) VALUES
('iPhone', '{"color": "black", "storage": 128, "tags": ["phone", "apple"]}');
-- Extract JSON value
SELECT
name,
attributes->>'$.color' AS color,
attributes->>'$.storage' AS storage
FROM products;
-- JSON Array Lookup
SELECT * FROM products WHERE JSON_CONTAINS(attributes->'$.tags', '"apple"');
Saída:
+--------+-------+---------+
| name | color | storage |
+--------+-------+---------+
| iPhone | black | 128 |
+--------+-------+---------+
8. Melhores práticas para a escolha de tipos de dados
| Cenário | Tipo recomendado | Motivo |
|---|---|---|
| Chave primária ID | BIGINT AUTO_INCREMENT | Ampla faixa, bom desempenho |
| Nome de usuário | VARCHAR(50) | Comprimento variável, economiza espaço |
| VARCHAR(100) | Comprimento variável | |
| Número de telefone | CHAR(11) | Comprimento fixo, consultas rápidas |
| Hash da senha | CHAR(60) | bcrypt fixado em 60 caracteres |
| Valor | DECIMAL(10,2) | Cálculo preciso |
| Status | ENUM ou TINYINT | Opções finitas |
| Conteúdo do artigo | TEXTO | Texto completo |
| Hora de criação | TIMESTAMP | Gerenciado automaticamente, 4 bytes |
| Dados JSON | JSON | Suporta índices e funções |
❓ Perguntas Frequentes
P: Qual é a diferença entre VARCHAR(255) e VARCHAR(256)? R: Para comprimentos de VARCHAR ≤255, é utilizado 1 byte para armazenar o comprimento; para comprimentos >255, são utilizados 2 bytes. Não há diferença fundamental no desempenho, mas 255 é um limite comumente utilizado.
P: O que devo fazer em relação ao problema do TIMESTAMP 2038? R: Já está prevista uma correção para o MySQL 8.0. Se você estiver preocupado, use DATETIME em vez disso.
P: Um único campo pode armazenar vários valores? R: Você pode usar o tipo de dados SET ou um array JSON, mas recomenda-se dividi-los em tabelas relacionadas (o que é uma prática mais comum).
P: O campo TEXT pode ser indexado? R: Sim, mas só é possível criar índices de prefixo (
INDEX(col(100))). Se você precisar de um índice completo, considere usar VARCHAR.
📖 Resumo
- Selecione tipos inteiros por intervalo: TINYINT → SMALLINT → INT → BIGINT
- Valores devem ser armazenados como DECIMAL; não é permitido usar FLOAT ou DOUBLE.
- CHAR de comprimento fixo (número de telefone), VARCHAR de comprimento variável (nome de usuário)
- ENUM é adequado para um conjunto finito de opções (estados, tipos)
- TIMESTAMP é adequado para registrar a hora, enquanto DATETIME é adequado para datas comerciais
- O tipo JSON suporta dados flexíveis e semiestruturados
📝 Exercícios
-
Questão básica (Dificuldade ⭐): Crie a tabela
productspara um sistema de comércio eletrônico e selecione os tipos de dados adequados para armazenar o nome, o preço, o estoque, o status e a descrição. -
Exercício avançado (Dificuldade ⭐⭐): Crie uma tabela chamada
user_profilesque contenha um campo chamadopreferencesdo tipo JSON e pratique a extração e a consulta de valores JSON. -
Desafio (Dificuldade: ⭐⭐⭐): Compare as diferenças de precisão entre
DECIMAL(10,2)eFLOATao armazenar valores e utilize experimentos para demonstrar a precisão deDECIMAL.