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.
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
- Sintaxe completa para CREATE TABLE
- Restrição de chave primária (PRIMARY KEY)
- Restrições de chave estrangeira (FOREIGN KEY)
- Restrição única (UNIQUE)
- Restrição NOT NULL
- Visualizar a estrutura da tabela
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:
- O número de telefone da Alice aparece três vezes na lista; portanto, para alterá-lo, é preciso editar três registros.
- Já salvei o preço do iPhone duas vezes; se o preço subir, terei que editar várias linhas
- É impossível rastrear “quantas unidades de um determinado produto foram vendidas”.
(2) Método da solução padronizada
Divida em três tabelas e vincule-as usando chaves estrangeiras:
-- 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
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
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';
Saída:
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
-- 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)
);
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
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
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
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.
);
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”
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
8. Restrições padrão (DEFAULT)
▶ Exemplo: Valor padrão
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;
Saída:
+----+-------------------+--------+------------+-------------+---------------------+
| id | title | status | view_count | is_featured | created_at |
+----+-------------------+--------+------------+-------------+---------------------+
| 1 | My First Article | draft | 0 | 0 | 2026-07-03 10:00:00 |
+----+-------------------+--------+------------+-------------+---------------------+
- 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
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.
10. Visualização das estruturas das tabelas
▶ Exemplo: Visualização das informações da tabela
-- 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;
Saída:
+----------------+--------------+------+-----+-------------------+----------------+
| 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
- CREATE TABLE cria uma tabela; é necessário especificar os nomes das colunas, os tipos de dados e as restrições
- CHAVE PRIMÁRIA: A chave primária identifica cada linha de forma exclusiva; recomenda-se usar um tipo INT com autoincremento.
- CHAVE ESTRANGEIRA Estabelece relações entre tabelas; suporta CASCADE, SET NULL e RESTRICT
- ÚNICO Uma restrição de exclusividade garante que os valores da coluna sejam únicos.
- NOT NULL: Uma restrição NOT NULL garante que uma coluna não armazene valores NULL.
- PADRÃO O valor padrão é preenchido automaticamente no momento da inserção
- A restrição CHECK (8.0+) garante que os valores da coluna atendam às condições
- DESCRIBE para visualizar a estrutura da tabela; SHOW CREATE TABLE para visualizar a definição completa
📝 Exercícios
-
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). -
Exercício avançado (Dificuldade: ⭐⭐): Crie a tabela
coursese a tabela associadastudent_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. -
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.