MySQL: Um guia detalhado para a criação de tabelas e…

Última atualização: 2026-08-26

As tabelas são as unidades básicas para armazenar dados em um banco de dados — se você projetar bem a estrutura da tabela, já estará com metade do caminho andado para um gerenciamento de dados bem-sucedido.

Nesta aula, você aprenderá a criar tabelas, definir restrições e visualizar sua estrutura.

100%
graph TB
    A[CREATE TABLE Element] --> B[Column Definition<br/>Field Name+Data Types]
    A --> C[Constraint Definition]
    C --> D[PRIMARY KEY Primary Key]
    C --> E[FOREIGN KEY Foreign Key]
    C --> F[UNIQUE The Only One]
    C --> G[NOT NULL Not empty]
    C --> H[DEFAULT Default value]
    C --> I[CHECK Inspection]
    A --> J[Table Options<br/>ENGINE/CHARSET/COMMENT]

1. O que você vai aprender


2. Uma história real sobre um sistema de comércio eletrônico

(1) Problema: Dados desorganizados

Um banco de dados de comércio eletrônico possui apenas a tabela orders, que armazena tanto as informações dos clientes quanto as dos produtos:

id_do_pedido nome_do_cliente telefone_do_cliente nome_do_produto preço_do_produto quantidade
1 Alice 13800001111 iPhone 999 2
2 Alice 13800001111 MacBook 1999 1
3 Bob 13800002222 iPhone 999 1

Pergunta:

(2) Método da solução padronizada

Divida em três tabelas e vincule-as usando chaves estrangeiras:

SQL
-- Customer Table
CREATE TABLE customers (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    phone VARCHAR(20) UNIQUE
);

-- Product List
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    price DECIMAL(10,2) NOT NULL
);

-- Orders Table
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT DEFAULT 1,
    FOREIGN KEY (customer_id) REFERENCES customers(id),
    FOREIGN KEY (product_id) REFERENCES products(id)
);

3. Sintaxe do comando CREATE TABLE

(1) Sintaxe completa

SQL
CREATE TABLE [IF NOT EXISTS] table_name (
    column1 datatype [constraints],
    column2 datatype [constraints],
    ...
    [table_constraints]
) [ENGINE=InnoDB] [DEFAULT CHARSET=utf8mb4];

▶ Exemplo: Criação de uma tabela de usuários

SQL
CREATE TABLE IF NOT EXISTS users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    age INT CHECK (age >= 0 AND age <= 150),
    status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='User Table';
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Query OK, 0 rows affected (0.02 sec)

4. Restrição de chave primária (PRIMARY KEY)

Uma chave primária é uma coluna de uma tabela que identifica cada linha de forma exclusiva; ela não pode ser duplicada nem ter valor NULL.

(1) Tipo de chave primária

Tipo Descrição Exemplo
Chave primária de coluna única Um único campo como chave primária id INT PRIMARY KEY
Chave primária composta Vários campos combinados para formar uma chave primária PRIMARY KEY (order_id, product_id)
Chave primária autoincremental Gera automaticamente um ID incremental id INT AUTO_INCREMENT PRIMARY KEY

▶ Exemplo: Uso de chaves primárias

SQL
-- Single-column primary key
CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
);

-- Composite Primary Key
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);
▶ Experimente

5. Restrições de chave estrangeira (FOREIGN KEY)

As chaves estrangeiras são utilizadas para estabelecer relações entre tabelas e garantir a integridade dos dados.

(1) Operações em cascata de chaves estrangeiras

Ação Descrição
CASCADE Quando um registro é excluído ou atualizado na tabela primária, o registro correspondente é excluído ou atualizado na tabela secundária
SET NULL Quando a tabela primária é excluída, a chave estrangeira na tabela secundária é definida como NULL
RESTRICT Proíbe a exclusão da tabela primária quando houver registros na tabela estrangeira (padrão)
SEM AÇÃO Equivalente a RESTRINGIR

▶ Exemplo: Cascata de chave estrangeira

SQL
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);

-- When deleting a customer,All orders for this customer have been automatically deleted.
DELETE FROM customers WHERE id = 1;
-- orders In the table customer_id=1 Records are automatically deleted
▶ Experimente

6. Restrição de exclusividade (UNIQUE)

Uma restrição de exclusividade garante que os valores em uma coluna sejam únicos (mas permite valores NULL).

▶ Exemplo: Restrição de exclusividade

SQL
CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE,        -- Single-row, unique
    username VARCHAR(50) UNIQUE,      -- Single-row, unique
    phone VARCHAR(20),
    UNIQUE KEY (phone)                -- Another way to write it
);

-- Composite Unique Constraint
CREATE TABLE user_roles (
    user_id INT,
    role_id INT,
    UNIQUE KEY (user_id, role_id)    -- The same role cannot be assigned to the same user more than once.
);
▶ Experimente

7. Restrição NOT NULL

As restrições “non-NULL” garantem que uma coluna não possa armazenar valores NULL.

▶ Exemplo: Restrição “Not-Null”

SQL
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,       -- Product Name (Required)
    price DECIMAL(10,2) NOT NULL,     -- Price is required
    description TEXT,                  -- The description may be left blank
    category_id INT NOT NULL
);

-- Insertion Test
INSERT INTO products (name, price) VALUES ('iPhone', 999);
-- Error:category_id Cannot be NULL
-- ERROR 1048 (23000): Column 'category_id' cannot be null
▶ Experimente

8. Restrições padrão (DEFAULT)

▶ Exemplo: Valor padrão

SQL
CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200) NOT NULL,
    status ENUM('draft', 'published', 'archived') DEFAULT 'draft',
    view_count INT DEFAULT 0,
    is_featured BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Omit fields with default values during insertion
INSERT INTO articles (title) VALUES ('My First Article');

-- Search
SELECT * FROM articles;
▶ Experimente

Saída:

TEXT 📖 Somente leitura
+----+-------------------+--------+------------+-------------+---------------------+
| id | title             | status | view_count | is_featured | created_at          |
+----+-------------------+--------+------------+-------------+---------------------+
|  1 | My First Article  | draft  |          0 |           0 | 2026-07-03 10:00:00 |
+----+-------------------+--------+------------+-------------+---------------------+

  1. Restrição CHECK (MySQL 8.0+)

As restrições CHECK garantem que os valores das colunas atendam às condições especificadas.

▶ Exemplo: Restrição CHECK

SQL
CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    age INT CHECK (age >= 18 AND age <= 65),
    salary DECIMAL(10,2) CHECK (salary > 0),
    email VARCHAR(100) CHECK (email LIKE '%@%.%')
);

-- Test
INSERT INTO employees (name, age, salary, email) VALUES ('Alice', 25, 5000, 'alice@company.com');
-- Error:age Not satisfied CHECK Conditions
INSERT INTO employees (name, age, salary, email) VALUES ('Bob', 15, 3000, 'bob@company.com');
-- ERROR 3819: Check constraint 'employees_chk_1' is violated.
▶ Experimente

10. Visualização das estruturas das tabelas

▶ Exemplo: Visualização das informações da tabela

SQL
-- View all tables in the current database
SHOW TABLES;

-- View Table Structure
DESCRIBE users;
-- Or
DESC users;

-- View the statement used to create the table
SHOW CREATE TABLE users\G

-- View the table's column information
SHOW COLUMNS FROM users;
▶ Experimente

Saída:

TEXT 📖 Somente leitura
+----------------+--------------+------+-----+-------------------+----------------+
| Field          | Type         | Null | Key | Default           | Extra          |
+----------------+--------------+------+-----+-------------------+----------------+
| id             | int          | NO   | PRI | NULL              | auto_increment |
| username       | varchar(50)  | NO   | UNI | NULL              |                |
| email          | varchar(100) | NO   |     | NULL              |                |
| password_hash  | varchar(255) | NO   |     | NULL              |                |
| age            | int          | YES  |     | NULL              |                |
| status         | enum(...)    | YES  |     | active            |                |
| created_at     | timestamp    | YES  |     | CURRENT_TIMESTAMP |                |
| updated_at     | timestamp    | YES  |     | CURRENT_TIMESTAMP |                |
+----------------+--------------+------+-----+-------------------+----------------+

❓ Perguntas Frequentes

P: A chave primária deve ser um INT autoincremental ou um UUID? R: Recomendamos um INT ou BIGINT autoincremental (para melhor desempenho e menor consumo de espaço de armazenamento). Os UUIDs são adequados para cenários distribuídos, mas podem reduzir o desempenho dos índices.

P: Uma tabela pode ter várias restrições UNIQUE? R: Sim. Uma tabela pode ter várias restrições UNIQUE, mas só pode ter uma PRIMARY KEY.

P: As chaves estrangeiras afetam o desempenho? R: Elas têm um impacto leve (as restrições precisam ser verificadas a cada gravação), mas garantem a integridade dos dados. Em cenários de alta concorrência, as verificações podem ser realizadas na camada de aplicação.

P: Qual é a diferença entre NULL e uma string vazia? R: NULL significa “sem valor”, enquanto uma string vazia '' é um valor. Não é possível comparar NULL usando o operador =; é preciso usar IS NULL.

P: Os nomes das tabelas devem estar no singular ou no plural? R: Recomendamos usar o plural (usuários, pedidos) para indicar “um conjunto de registros”. Apenas certifique-se de manter a consistência no estilo ao longo de todo o projeto.


📖 Resumo


📝 Exercícios

  1. Questão básica (Dificuldade ⭐): Crie a tabela students, contendo os campos id (chave primária autoincremental), nome (não nulo), idade (CHECK 18-100) e e-mail (único).

  2. Exercício avançado (Dificuldade: ⭐⭐): Crie a tabela courses e a tabela associada student_courses (muitos-para-muitos), defina restrições de chave estrangeira e configure o sistema para que a exclusão de registros de matrícula em disciplinas ocorra em cascata quando um aluno for excluído.

  3. Desafio (Dificuldade: ⭐⭐⭐): Projete a estrutura das tabelas para um sistema de blog (usuários, posts, comentários, tags), incluindo restrições como chaves primárias, chaves estrangeiras, restrições não nulas e valores padrão.

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%