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.

100%
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


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:

SQL
-- 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

SQL
-- 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

SQL
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);
▶ Experimente
💡 Dica: Escolha o menor tipo de dados que atenda às suas necessidades para economizar espaço de armazenamento. Use 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

SQL
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;
▶ Experimente

Saída:

TEXT 📖 Somente leitura
+----+-------------+--------+----------+
| 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

SQL
-- 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

SQL
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;
▶ Experimente

Saída:

TEXT 📖 Somente leitura
+---------+-----------+
| 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

SQL
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;
▶ Experimente

Saída:

TEXT 📖 Somente leitura
+----+----------------+------------+------------+---------------------+---------------------+
| 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

SQL
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"');
▶ Experimente

Saída:

TEXT 📖 Somente leitura
+--------+-------+---------+
| 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
E-mail 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


📝 Exercícios

  1. Questão básica (Dificuldade ⭐): Crie a tabela products para 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.

  2. Exercício avançado (Dificuldade ⭐⭐): Crie uma tabela chamada user_profiles que contenha um campo chamado preferences do tipo JSON e pratique a extração e a consulta de valores JSON.

  3. Desafio (Dificuldade: ⭐⭐⭐): Compare as diferenças de precisão entre DECIMAL(10,2) e FLOAT ao armazenar valores e utilize experimentos para demonstrar a precisão de DECIMAL.

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%