Banco de dados: Migrações
Introdução
As migrações são como o controle de versão para o seu banco de dados, permitindo que sua equipe defina e compartilhe o esquema do banco de dados da aplicação. Se você já teve que dizer a um colega de trabalho para adicionar manualmente uma coluna ao seu esquema local de banco de dados após ter puxado suas alterações do controle de versão, você já enfrentou o problema que as migrações de banco de dados resolvem.
A facade Schema
do Laravel fornece suporte de banco de dados agnóstico para criar e manipular tabelas em todos os sistemas de banco de dados suportados pelo Laravel. Normalmente, as migrações usarão esta facade para criar e modificar tabelas de banco de dados e colunas.
Gerando Migrações
Você pode usar o comando make:migration
para gerar uma migração de banco de dados. A nova migração será colocada no seu diretório database/migrations
. Cada nome de arquivo de migração contém um carimbo de data e hora que permite o Laravel determinar a ordem das migrações:
php artisan make:migration create_flights_table
O Laravel usará o nome da migração para tentar adivinhar o nome da tabela e se a migração criará ou não uma nova tabela. Se o Laravel for capaz de determinar o nome da tabela a partir do nome da migração, o Laravel preencherá previamente o arquivo de migração gerado com a tabela especificada. Caso contrário, você pode simplesmente especificar a tabela no arquivo de migração manualmente.
Se você gostaria de especificar um caminho personalizado para o arquivo gerado da migração, você pode usar a opção --path
ao executar o comando make:migration
. O caminho dado deve ser relativo ao seu caminho base da aplicação.
NOTA
Os stubs de migração podem ser personalizados usando publicação de stub.
Encolhendo as migrações
À medida que você cria sua aplicação, você pode acumular mais e mais migrações ao longo do tempo. Isso pode levar seu diretório 'database/migrations' a se encher de centenas de migrações. Se desejar, você pode "encolher" suas migrações em um único arquivo SQL. Para começar, execute o comando schema:dump
:
php artisan schema:dump
# Despeja o esquema de banco de dados atual e remover todas as migrações existentes...
php artisan schema:dump --prune
Ao executar esse comando, o Laravel irá escrever um arquivo "schema" no diretório da sua aplicação database/schema
. O nome do arquivo "schema" corresponderá à conexão do banco de dados. Agora quando você tentar migrar seu banco de dados e não houver outras migrações executadas, o Laravel executará primeiro as instruções SQL contidas no arquivo "schema" da conexão do banco de dados que você está usando. Após executar as instruções SQL do arquivo "schema", o Laravel irá executar qualquer migração restante que não faça parte do dump do esquema.
Se seus testes de aplicação utilizam uma conexão de banco de dados diferente da que você normalmente usa durante o desenvolvimento local, você deve garantir que tenha "despejado" um arquivo de esquema usando essa conexão de banco de dados para que seus testes sejam capazes de construir seu banco de dados. Você pode querer fazer isso após ter derrubado a conexão do banco de dados que você normalmente usa durante o desenvolvimento local:
php artisan schema:dump
php artisan schema:dump --database=testing --prune
Você deve enviar seu arquivo de esquema de banco de dados para o controle de origem para que outros novos desenvolvedores em sua equipe possam criar rapidamente a estrutura inicial do banco de dados do seu aplicativo.
ATENÇÃO
Encolher as migrações está disponível apenas para os bancos de dados MySQL, PostgreSQL e SQLite e utiliza o cliente de linha de comando do banco de dados.
Estrutura de Migração
Uma classe de migração contém dois métodos: up
e down
. O método up
é usado para adicionar novas tabelas, colunas ou índices ao seu banco de dados, enquanto o método down
deve reverter as operações feitas pelo método up
.
Dentro de todos os dois métodos você pode usar o construtor de esquema do Laravel para criar e modificar tabelas expressivamente. Para saber sobre todos os métodos disponíveis no construtor do esquema confira sua documentação. Por exemplo, a migração abaixo cria uma tabela de 'voos':
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Execute as migrações.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
/**
* Reverta as migrações.
*/
public function down(): void
{
Schema::drop('flights');
}
};
Configurar a conexão de migração
Se sua migração vai interagir com uma conexão de banco de dados diferente do padrão da aplicação, você precisa definir a propriedade $connection
da migração:
/**
* A conexão de banco de dados que deve ser usada pela migração.
*
* @var string
*/
protected $connection = 'pgsql';
/**
* Execute as migrações.
*/
public function up(): void
{
// ...
}
Migrando
Para executar todas as migrações pendentes, execute o comando migrate
no Artisan:
php artisan migrate
Se você quiser ver quais migrações já foram executadas até agora, pode usar o comando migrate:status
do Artisan:
php artisan migrate:status
Se você quer ver as instruções SQL que serão executadas pelas migrações sem realmente executar, você pode fornecer a bandeira --pretend
para o comando de migração:
php artisan migrate --pretend
Isolando a execução de migração
Se você está implantando seu aplicativo em vários servidores e executando migrações como parte do processo de implantação, provavelmente não deseja que dois servidores tentem migrar o banco de dados ao mesmo tempo. Para evitar isso, você pode usar a opção isolated
ao invocar o comando migrate
.
Quando a opção isolated
é fornecida, o Laravel irá adquirir um bloqueio atômico usando o driver de cache do seu aplicativo antes de tentar executar suas migrações. Todas as outras tentativas de executar o comando migrate
enquanto esse bloqueio for mantido não serão executadas; no entanto, o comando ainda sairá com um código de status de saída bem-sucedido:
php artisan migrate --isolated
ATENÇÃO
Para utilizar este recurso, sua aplicação deve estar utilizando o driver de cache memcached
, redis
, dynamodb
, database
, file
, ou array
como seu driver de cache padrão. Além disso, todos os servidores devem ser comunicados com o mesmo servidor central de cache.
Forçando migrações para serem executadas em produção
Algumas operações de migração são destrutivas, o que significa que elas podem lhe fazer perder dados. Para proteger você de executar esses comandos contra sua base de dados de produção, uma mensagem de confirmação será exibida antes dos comandos serem executados. Para forçá-los a serem executados sem mensagem, use o sinalizador --force
:
php artisan migrate --force
Reverter a Migração
Para reverter a última operação de migração, você pode utilizar o comando Artisan "rollback". Este comando reverte a último "batch" de migrações que pode incluir vários arquivos de migração:
php artisan migrate:rollback
Você pode desfazer um número limitado de migrações fornecendo a opção step
no comando rollback
. Por exemplo, o seguinte comando irá desfazer as últimas cinco migrações:
php artisan migrate:rollback --step=5
Você pode rolar para trás um "lote" específico de migração fornecendo a opção batch
para o comando rollback
, onde a opção batch
corresponde a um valor de lote dentro da tabela de banco de dados de migrations
do seu aplicativo. Por exemplo, o seguinte comando vai rolar para trás todas as migrações no lote três:
php artisan migrate:rollback --batch=3
Se você gostaria de ver as instruções SQL que serão executadas pelas migrações sem realmente executá-las, você pode fornecer a sinalização --pretend
para o comando migrate:rollback
:
php artisan migrate:rollback --pretend
O comando migrate:reset
vai fazer um rollback de todas as migrações do seu aplicativo:
php artisan migrate:reset
Reverter e migrar usando um único comando
O comando migrate:refresh
vai reverter todas as suas migrações e, em seguida, executar o comando migrate
. Este comando efetivamente recria todo o seu banco de dados.
php artisan migrate:refresh
# Atualize o banco de dados e execute todas as seeds do banco de dados...
php artisan migrate:refresh --seed
Você pode rolar de volta e migrar novamente um número limitado de migrações fornecendo o parâmetro step
para o comando refresh
. Por exemplo, o seguinte comando irá rolar de volta e migrar novamente as últimas cinco migrações:
php artisan migrate:refresh --step=5
Limpe todas as tabelas e migre
O comando migrate:fresh
vai descartar todas as tabelas do banco de dados e em seguida executar o comando migrate
:
php artisan migrate:fresh
php artisan migrate:fresh --seed
Por padrão, o comando migrate:fresh
apenas descarta as tabelas da conexão padrão de banco de dados. No entanto, você pode usar a opção --database
para especificar a conexão do banco de dados que deve ser migrada. O nome da conexão do banco de dados deve corresponder à conexão definida no seu arquivo de configuração do database
no arquivo de configuração:
php artisan migrate:fresh --database=admin
ATENÇÃO
O comando migrate:fresh
irá excluir todas as tabelas do banco de dados, independentemente do prefixo das mesmas. Esse comando deve ser usado com cautela ao desenvolver em um banco de dados que é compartilhado com outros aplicativos.
Tabelas
Criando tabelas
Para criar uma nova tabela de banco de dados, use o método create
da facade Schema
. O método create
aceita dois argumentos: o primeiro é o nome da tabela e o segundo é um closure que recebe um objeto Blueprint
que pode ser usado para definir a nova tabela:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->timestamps();
});
Ao criar a tabela, você pode utilizar qualquer um dos métodos de coluna do construtor de esquemas para definir as colunas da tabela.
Determinando a existência de tabela/coluna
Você pode determinar se uma tabela, coluna ou índice existem usando os métodos hasTable
, hasColumn
e hasIndex
:
if (Schema::hasTable('users')) {
// A tabela "users" existe...
}
if (Schema::hasColumn('users', 'email')) {
// A tabela "users" existe e tem uma coluna "email"...
}
if (Schema::hasIndex('users', ['email'], 'unique')) {
// A tabela "users" existe e tem um índice exclusivo na coluna "email"...
}
Conexão de Banco de dados e Opções de Tabela
Se você quiser executar uma operação de esquema em uma conexão de banco de dados que não seja a padrão de seu aplicativo, utilize o método connection
:
Schema::connection('sqlite')->create('users', function (Blueprint $table) {
$table->id();
});
Além disso, outras propriedades e métodos podem ser usados para definir outros aspectos de criação da tabela. A propriedade engine
pode ser usada para especificar o motor de armazenamento da tabela ao usar o MySQL:
Schema::create('users', function (Blueprint $table) {
$table->engine('InnoDB');
// ...
});
As propriedades charset
e collation
podem ser usadas para especificar a codificação de caracteres e o ordenamento para as tabelas criadas no MySQL.
Schema::create('users', function (Blueprint $table) {
$table->charset('utf8mb4');
$table->collation('utf8mb4_unicode_ci');
// ...
});
O método temporary
pode ser utilizado para indicar que a tabela deve ser "temporária". As tabelas temporais só são visíveis à sessão de banco de dados da conexão atual e são descartadas automaticamente quando a conexão é fechada.
Schema::create('calculations', function (Blueprint $table) {
$table->temporary();
// ...
});
Se quiser acrescentar um comentário em uma tabela de banco de dados, você pode invocar o método comment
na instância da tabela. Os comentários da tabela atualmente só são suportados por MySQL e PostgreSQL:
Schema::create('calculations', function (Blueprint $table) {
$table->comment('Business calculations');
// ...
});
Atualizando Tabelas
O método table
da facade Schema
pode ser usado para atualizar tabelas existentes. Como o método create
, o método table
aceita dois argumentos: o nome da tabela e uma closure que recebe uma instância de Blueprint
a qual você pode usar para adicionar colunas ou índices à tabela:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->integer('votes');
});
Renomeando / Deletando Tabelas
Para renomear uma tabela existente no banco de dados, utilize o método rename
:
use Illuminate\Support\Facades\Schema;
Schema::rename($from, $to);
Para apagar uma tabela existente você pode usar os métodos drop
ou dropIfExists
:
Schema::drop('users');
Schema::dropIfExists('users');
Renomeando tabelas com chaves estrangeiras
Antes de renomear uma tabela, você deve verificar se as restrições de chave estrangeira na tabela têm um nome explícito em seus arquivos de migração em vez de deixar o Laravel atribuir um nome baseado na convenção. Caso contrário, o nome da restrição da chave estrangeira irá se referir ao nome da antiga tabela.
Colunas
Criando Colunas
O método table
na facade Schema
pode ser usado para atualizar tabelas existentes. Assim como o método create
, o método table
aceita dois argumentos: o nome da tabela e um closure que recebe uma instância de Illuminate\Database\Schema\Blueprint
que você pode usar para adicionar colunas à tabela:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->integer('votes');
});
Tipos de Coluna disponíveis
O construtor de schema oferece um conjunto de métodos que se correlacionam com os vários tipos de colunas que você pode acrescentar nas tabelas do seu banco de dados. Cada método disponível é listado na tabela abaixo:
- bigIncrements
- bigInteger
- binary
- boolean
- char
- dateTimeTz
- dateTime
- date
- decimal
- double
- enum
- float
- foreignId
- foreignIdFor
- foreignUlid
- foreignUuid
- geography
- geometry
- id
- increments
- integer
- ipAddress
- json
- jsonb
- longText
- macAddress
- mediumIncrements
- mediumInteger
- mediumText
- morphs
- nullableMorphs
- nullableTimestamps
- nullableUlidMorphs
- nullableUuidMorphs
- rememberToken
- set
- smallIncrements
- smallInteger
- softDeletesTz
- softDeletes
- string
- text
- timeTz
- time
- timestampTz
- timestamp
- timestampsTz
- timestamps
- tinyIncrements
- tinyInteger
- tinyText
- unsignedBigInteger
- unsignedInteger
- unsignedMediumInteger
- unsignedSmallInteger
- unsignedTinyInteger
- ulidMorphs
- uuidMorphs
- ulid
- uuid
- year
bigIncrements()
O método bigIncrements
cria uma coluna equivalente a UNSIGNED BIGINT
(chave primária) com incrementos automáticos.
$table->bigIncrements('id');
bigInteger()
O método bigInteger
cria uma coluna equivalente de BIGINT
:
$table->bigInteger('votes');
binary()
O método binary
cria uma coluna equivalente a um BLOB
:
$table->binary('photo');
Ao utilizar MySQL, MariaDB ou SQL Server você pode passar os argumentos length
e fixed
para criar uma coluna equivalente a VARBINARY
ou BINARY
:
$table->binary('data', length: 16); // VARBINARY(16)
$table->binary('data', length: 16, fixed: true); // BINARY(16)
boolean()
O método boolean
cria uma coluna equivalente em BOOLEAN
:
$table->boolean('confirmed');
char()
O método char
cria uma coluna equivalente ao tipo de dados CHAR
com um determinado comprimento:
$table->char('name', length: 100);
dateTimeTz()
O método DateTimeTz
cria uma coluna equivalente de DATETIME
(com zona de horário) com precisão opcional dos segundos fracionados.
$table->dateTimeTz('created_at', precision: 0);
dateTime()
O método dateTime
cria uma coluna equivalente DATETIME
com uma precisão opcional de segundos fracionários:
$table->dateTime('created_at', precision: 0);
data()
O método date
cria uma coluna equivalente para o tipo DATE
:
$table->date('created_at');
decimal()
O método decimal cria uma coluna equivalente de DECIMAL
com o nível de precisão (números inteiros) e escala (números decimais) fornecidos:
$table->decimal('amount', total: 8, places: 2);
double()
O método double
cria uma coluna equivalente de DOUBLE
:
$table->double('amount');
enum()
O método enum
cria uma coluna equivalente ENUM
com os valores válidos fornecidos:
$table->enum('difficulty', ['easy', 'hard']);
float()
O método float
cria uma coluna equivalente de FLOAT
com a precisão dada:
$table->float('amount', precision: 53);
foreignId()
O método foreignId
cria uma coluna equivalente UNSIGNED BIGINT
:
$table->foreignId('user_id');
foreignIdFor()
O método foreignIdFor
adiciona uma coluna equivalente {column}_id
para uma classe de modelo dada. O tipo da coluna será UNSIGNED BIGINT
, CHAR(36)
ou CHAR(26)
, dependendo do tipo chave do modelo:
$table->foreignIdFor(User::class);
foreignUlid()
O método foreignUlid
cria uma coluna equivalente ao ULID
:
$table->foreignUlid('user_id');
foreignUuid()
O método foreignUuid
cria uma coluna equivalente UUID
:
$table->foreignUuid('user_id');
geography()
O método geography
cria uma coluna equivalente de GEOGRAPHY
com o tipo espacial e identificador SRID (Sistema de Referência Espacial) dado:
$table->geography('coordinates', subtype: 'point', srid: 4326);
NOTA
Suporte para tipos espaciais depende do seu driver de banco de dados. Por favor, consulte a documentação do seu banco de dados. Se seu aplicativo estiver usando um banco de dados PostgreSQL, você deve instalar a extensão PostGIS antes que o método geography
possa ser usado.
geometry()
O método geometry
cria uma coluna equivalente de GEOMETRY com o tipo espacial e o SRID (Sistema de Referência Espacial) dado:
$table->geometry('positions', subtype: 'point', srid: 0);
Nota: O suporte para tipos espaciais depende do seu driver de banco de dados. Por favor consulte a documentação do seu banco de dados. Se o seu aplicativo estiver usando um banco de dados PostgreSQL, você deve instalar a extensão PostGIS antes que o método
geometry
possa ser usado.
id()
O método id
é um alias do método bigIncrements
. Por padrão, o método irá criar uma coluna id
no entanto, você pode passar um nome de coluna caso queira atribuir um nome diferente para a coluna:
$table->id();
increments()
O método increments
cria uma coluna equivalente ao UNSIGNED INTEGER
auto-incremental como chave primária:
$table->increments('id');
integer()
O método integer
cria uma coluna equivalente para o tipo INTEGER
:
$table->integer('votes');
ipAddress()
O método ipAddress
cria uma coluna equivalente de VARCHAR
:
$table->ipAddress('visitor');
Ao usar o PostgreSQL, é criada uma coluna INET
.
json()
O método json
cria uma coluna equivalente em JSON
:
$table->json('options');
jsonb()
O método jsonb
cria uma coluna equivalente de JSONB
:
$table->jsonb('options');
longText()
O método longText
cria uma coluna equivalente LONGTEXT
:
$table->longText('description');
Ao utilizar o MySQL ou MariaDB, você pode aplicar um character set
binário para que a coluna fique equivalente ao LONGBLOB
:
$table->longText('data')->charset('binary'); // LONGBLOB
macAddress()
O método macAddress
cria uma coluna que pretende conter um endereço MAC. Alguns sistemas de banco de dados, como PostgreSQL, possuem um tipo de coluna específico para este tipo de dado. Outros sistemas de banco de dados usarão uma coluna equivalente a string:
$table->macAddress('device');
mediumIncrements()
O método mediumIncrements
cria uma coluna equivalente de UNSIGNED MEDIUMINT
auto incrementada, como chave primária:
$table->mediumIncrements('id');
mediumInteger()
A função mediumInteger
cria uma coluna equivalente de tipo MEDIUMINT
.
$table->mediumInteger('votes');
mediumText()
A mediumText
cria uma coluna equivalente de MEDIUMTEXT
:
$table->mediumText('description');
Ao utilizar MySQL ou MariaDB, você pode aplicar um conjunto de caracteres binário
à coluna para criar uma coluna equivalente MEDIUMBLOB
:
$table->mediumText('data')->charset('binary'); // MEDIUMBLOB
morphs()
O método morphs
é um método de conveniência que adiciona uma coluna equivalente a {column}_id
e uma coluna equivalente a {column}_type varchar
. O tipo de coluna para o {column}_id
será UNSIGNED BIGINT
, CHAR (36)
ou CHAR (26)
dependendo do tipo de chave do modelo.
Este método deve ser usado ao definir as colunas necessárias para um relacionamento Eloquent polimórfico. No exemplo a seguir, as colunas taggable_id
e taggable_type
seriam criadas:
$table->morphs('taggable');
nullableTimestamps()
O método nullableTimestamps
é um apelido para o método timestamps:
$table->nullableTimestamps(precision: 0);
nullableMorphs()
O método é semelhante ao método morphs; no entanto, as colunas criadas serão nullable
:
$table->nullableMorphs('taggable');
nullableUlidMorphs()
O método é semelhante ao método ulidMorphs; no entanto, as colunas criadas serão nullable
:
$table->nullableUlidMorphs('taggable');
nullableUuidMorphs()
O método é semelhante ao método uuidMorphs; no entanto, as colunas criadas serão nullable
:
$table->nullableUuidMorphs('taggable');
rememberToken()
O método rememberToken
cria uma coluna de tipo "nullable" VARCHAR(100) equivalente com o objetivo de armazenar a autenticação atual "lembra-me":
$table->rememberToken();
set()
O método set
cria uma coluna equivalente a SET
com a lista fornecida de valores válidos:
$table->set('flavors', ['strawberry', 'vanilla']);
smallIncrements()
O método smallIncrements
cria uma coluna equivalente de unsigned smallint
que incrementa automaticamente como chave primária:
$table->smallIncrements('id');
smallInteger()
O método smallInteger
cria uma coluna equivalente do tipo SMALLINT
:
$table->smallInteger('votes');
softDeletesTz()
O método softDeletesTz
adiciona uma coluna deleted_at
com timestamp (com fuso horário) e valor nulo, equivalente a um número fracionário opcional. Esta coluna é destinada a armazenar o timestamp deleted_at
necessário para a funcionalidade "soft delete" de Eloquent:
$table->softDeletesTz('deleted_at', precision: 0);
softDeletes()
O método softDeletes
adiciona uma coluna nullable
de TIMESTAMP
com um segundo fracionário opcional para armazenar a marca de tempo deleted_at
necessária para a funcionalidade "soft delete" do Eloquent. Esta coluna é destinada a armazenar o timestamp deleted_at
$table->softDeletes('deleted_at', precision: 0);
string()
O método string
cria uma coluna equivalente à VARCHAR do comprimento dado.
$table->string('name', length: 100);
text()
O método text
cria uma coluna equivalente de texto:
$table->text('description');
Ao utilizar MySQL ou MariaDB, você pode aplicar um conjunto de caracteres binários (binary
) à coluna para criar uma coluna equivalente a BLOB
:
$table->text('data')->charset('binary'); // BLOB
timeTz()
O método timeTz
cria uma coluna equivalente TIME
(com timezone) com precisão opcional em segundos fracionados:
$table->timeTz('sunrise', precision: 0);
time()
O método time
cria uma coluna equivalente de TIME
com precisão opcional de segundos fracionados:
$table->time('sunrise', precision: 0);
timestampTz()
O método timestampTz
cria uma coluna equivalente de TIMESTAMP
(com informação timeozone) com precisão opcional de segundo fracionário:
$table->timestampTz('added_at', precision: 0);
timestamp()
A função timestamp
cria uma coluna equivalente de timestamp com precisão opcional dos segundos fracionários:
$table->timestamp('added_at', precision: 0);
timestampsTz()
O método timestampsTz
cria colunas equivalentes ao tipo TIMESTAMP
(com fuso horário) para o created_at
e updated_at
com uma precisão opcional de segundos fracionários.
$table->timestampsTz(precision: 0);
timestamps()
O método timestamps
cria as colunas created_at
e updated_at
equivalentes a um TIMESTAMP
, com uma precisão opcional de milissegundos.
$table->timestamps(precision: 0);
tinyIncrements()
O método tinyIncrements
cria uma coluna equivalente a UNSIGNED TINYINT
com incrementação automática como chave primária:
$table->tinyIncrements('id');
tinyInteger()
O método tinyInteger
cria uma coluna equivalente de tinyint
:
$table->tinyInteger('votes');
tinyText()
O método tinyText
cria uma coluna equivalente de TINYTEXT
:
$table->tinyText('notes');
Ao utilizar MySQL ou MariaDB, você pode aplicar um "character set" binário à coluna para criar uma coluna equivalente TINYBLOB
:
$table->tinyText('data')->charset('binary'); // TINYBLOB
unsignedBigInteger()
O método unsignedBigInteger
cria uma coluna equivalente UNSIGNED BIGINT
:
$table->unsignedBigInteger('votes');
unsignedInteger()
O método unsignedInteger
cria uma coluna equivalente de UNSIGNED INTEGER
:
$table->unsignedInteger('votes');
unsignedMediumInteger()
O método unsignedMediumInteger
cria uma coluna equivalente de UNSIGNED MEDIUMINT
:
$table->unsignedMediumInteger('votes');
unsignedSmallInteger()
O método unsignedSmallInteger
cria uma coluna equivalente de UNSIGNED SMALLINT
:
$table->unsignedSmallInteger('votes');
unsignedTinyInteger()
O método unsignedTinyInteger
cria uma coluna equivalente de UNSIGNED TINYINT
:
$table->unsignedTinyInteger('votes');
ulidMorphs()
O método ulidMorphs
é um método de conveniência que adiciona uma coluna equivalente {column}_id
CHAR(26)
e uma coluna equivalente {column}_type
VARCHAR
.
Este método é destinado para ser usado quando definindo as colunas necessárias para uma relação Eloquent polimórfica que emprega identificadores ULID. Na seguinte amostra, as colunas taggable_id
e taggable_type
seriam criadas:
$table->ulidMorphs('taggable');
uuidMorphs()
O método uuidMorphs
é um método conveniente que adiciona uma coluna equivalente CHAR(36)
{column}_id
e uma coluna equivalente VARCHAR
{column}_type
.
Este método deve ser usado ao definir as colunas necessárias para um relacionamento Eloquent polimórfico que usa identificadores UUID. No exemplo a seguir, as colunas taggable_id
e taggable_type
seriam criadas:
$table->uuidMorphs('taggable');
ulid()
O método ulid
cria uma coluna equivalente:
$table->ulid('id');
uuid()
O método uuid
cria uma coluna equivalente UUID
:
$table->uuid('id');
year()
O método year
cria uma coluna equivalente YEAR
:
$table->year('birth_year');
Modificadores de coluna
Além dos tipos de colunas listados acima, existem vários modificadores de coluna que você pode usar ao adicionar uma coluna a uma tabela do banco de dados. Por exemplo, para tornar a coluna "nula", você pode usar o método null
:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->string('email')->nullable();
});
A tabela a seguir contém todos os modificadores de coluna disponíveis. Esta lista não inclui modificadores de índice:
Modificador | Descrição |
---|---|
->after('column') | Coloque a coluna "depois" de outra coluna (MySQL). |
->autoIncrement() | Defina colunas INTEGER como de incremento automático (chave primária). |
->charset('utf8mb4') | Especifique um conjunto de caracteres para a coluna (MySQL). |
->collation('utf8mb4_unicode_ci') | Especifique uma collation para a coluna. |
->comment('my comment') | Adicione um comentário a uma coluna (MySQL / PostgreSQL). |
->default($value) | Especifique um valor "padrão" para a coluna. |
->first() | Coloque a coluna em "primeiro" na tabela (MySQL). |
->from($integer) | Defina o valor inicial de um campo de incremento automático (MySQL / PostgreSQL). |
->invisible() | Tornar a coluna "invisível" para consultas SELECT * (MySQL). |
->nullable($value = true) | Permitir que valores NULL sejam inseridos na coluna. |
->storedAs($expression) | Crie uma coluna stored generated (MySQL / PostgreSQL / SQLite). |
->unsigned() | Defina colunas INTEGER como UNSIGNED (MySQL). |
->useCurrent() | Defina as colunas TIMESTAMP para usar CURRENT_TIMESTAMP como valor padrão. |
->useCurrentOnUpdate() | Defina as colunas TIMESTAMP para usar CURRENT_TIMESTAMP quando um registro for atualizado (MySQL). |
->virtualAs($expression) | Crie uma coluna virtual gerada (MySQL / SQLite). |
->generatedAs($expression) | Crie uma coluna de identidade com opções de sequência especificadas (PostgreSQL). |
->always() | Define a precedência de valores de sequência sobre a entrada para uma coluna de identidade (PostgreSQL). |
Expressões padrão
O modificador default
aceita um valor ou uma instância Illuminate\Database\Query\Expression
. Usando uma instância de Expression
, o Laravel não irá envolver o valor entre aspas e permitirá que você utilize funções específicas do banco de dados. Uma situação em que isso é particularmente útil é quando você precisa atribuir valores padrão a colunas JSON:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Execute as migrações.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->json('movies')->default(new Expression('(JSON_ARRAY())'));
$table->timestamps();
});
}
};
ATENÇÃO
O suporte para expressões padrão depende do seu driver de banco de dados, a versão do banco de dados e o tipo de campo. Por favor, consulte a documentação do seu banco de dados.
Ordem de Coluna
Quando usando o banco de dados MySQL, você pode usar o método after
para adicionar colunas após uma coluna existente no esquema de banco de dados.
$table->after('password', function (Blueprint $table) {
$table->string('address_line1');
$table->string('address_line2');
$table->string('city');
});
Modificando Colunas
O método change
permite que você altere o tipo e os atributos das colunas existentes. Por exemplo, você pode querer aumentar o tamanho de uma coluna string
. Para ver a ação do método change
, vamos aumentar o tamanho da coluna name
de 25 para 50. Para fazer isso, simplesmente definimos o novo estado da coluna e então chamamos o método change
:
Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->change();
});
Ao modificar uma coluna, você deve incluir explicitamente todos os modificadores que deseja manter na definição da coluna - qualquer atributo ausente será descartado. Por exemplo, para reter o atributo unsigned
, default
e comment
, você deve chamar cada modificador explicitamente ao alterar a coluna:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});
O método change
não altera os índices da coluna. Portanto, você pode usar modificadores de índice para adicionar ou remover explicitamente um índice ao modificar a coluna:
// Adicionar um índice...
$table->bigIncrements('id')->primary()->change();
// Apaga um índice...
$table->char('postal_code', 10)->unique(false)->change();
Renomear Colunas
Para renomear uma coluna você pode usar o método renameColumn
fornecido pelo construtor de esquema:
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('from', 'to');
});
Apagando Colunas
Para descartar uma coluna, você pode usar o método dropColumn
no construtor de esquema:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('votes');
});
Você pode excluir múltiplas colunas de uma tabela passando um array de nomes de colunas para o método dropColumn
:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});
Aliases de comando disponíveis
Laravel fornece vários métodos convenientes relacionados a remoção de tipos comuns de colunas. Cada um desses métodos é descrito na tabela abaixo:
Comando | Descrição |
---|---|
$table->dropMorphs('morphable'); | Remova as colunas morphable_id e morphable_type . |
$table->dropRememberToken(); | Remova a coluna remember_token . |
$table->dropSoftDeletes(); | Remova a coluna deleted_at . |
$table->dropSoftDeletesTz(); | Alias do método dropSoftDeletes() . |
$table->dropTimestamps(); | Remova as colunas created_at e updated_at . |
$table->dropTimestampsTz(); | Alias do método dropTimestamps() . |
Índices
Criando índices
O construtor de esquemas do Laravel suporta vários tipos de índices. O exemplo seguinte cria uma nova coluna email
e especifica que os valores dela devem ser únicos. Para criar o índice, podemos encadear o método unique
na definição da coluna:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique();
});
Alternativamente, você pode criar o índice depois de definir a coluna. Para isso, você deve chamar o método "único" no esboço do construtor de esquema. Este método aceita o nome da coluna que deve receber um índice exclusivo:
$table->unique('email');
Você pode passar até mesmo uma matriz de colunas para um método de índice para criar um índice composto:
$table->index(['account_id', 'created_at']);
Ao criar um índice, o Laravel irá gerar automaticamente um nome de índice baseado na tabela, nos nomes da coluna e no tipo do índice. Mas você pode passar um segundo argumento ao método para especificar o nome do índice por conta própria:
$table->unique('email', 'unique_email');
Tipos de índice disponíveis
A classe blueprint de construtor de esquemas do Laravel fornece métodos para criar cada tipo de índice suportado pelo Laravel. Cada método de índice aceita um segundo argumento opcional para especificar o nome do índice. Se omitido, o nome será derivado dos nomes da tabela e da coluna(s) usadas para o índice, bem como do tipo de índice.
Comando | Descrição |
---|---|
$table->primary('id'); | Adiciona uma chave primária. |
$table->primary(['id', 'parent_id']); | Adiciona chaves compostas. |
$table->unique('email'); | Adiciona um índice exclusivo. |
$table->index('state'); | Adiciona um índice. |
$table->fullText('body'); | Adiciona um índice de texto completo (MySQL / PostgreSQL). |
$table->fullText('body')->language('english'); | Adiciona um índice de texto completo do idioma especificado (PostgreSQL). |
$table->spatialIndex('location'); | Adiciona um índice espacial (exceto SQLite). |
Renomeando índices
Para renomear um índice, você pode usar o método renameIndex
fornecido pelo blueprint do construtor de esquemas. Este método aceita o nome atual do índice como seu primeiro argumento e o nome desejado como segundo argumento:
$table->renameIndex('from', 'to')
Removendo Índices
Para criar um índice você deve especificar o nome do índice. Por padrão, Laravel atribui automaticamente o nome do índice com base na tabela, na coluna e no tipo de índice. Aqui estão alguns exemplos:
Comando | Descrição |
---|---|
$table->dropPrimary('users_id_primary'); | Remova uma chave primária da tabela "users". |
$table->dropUnique('users_email_unique'); | Remova um índice exclusivo da tabela "users". |
$table->dropIndex('geo_state_index'); | Remova um índice básico da tabela "geo". |
$table->dropFullText('posts_body_fulltext'); | Remova um índice de texto completo da tabela "posts". |
$table->dropSpatialIndex('geo_location_spatialindex'); | Remova um índice espacial da tabela "geo" (exceto SQLite). |
Se você passar uma matriz de colunas em um método que remove índices, o nome do índice convencional será gerado com base no nome da tabela, das colunas e do tipo de índice.
Schema::table('geo', function (Blueprint $table) {
$table->dropIndex(['state']); // Remove o indice 'geo_state_index'
});
Restrições de Chave Estrangeira
O Laravel também fornece suporte para criar restrições de chave estrangeira, que são usadas para forçar a integridade referencial no nível do banco de dados. Por exemplo, vamos definir uma coluna user_id
na tabela posts
que referencia a coluna id
em uma tabela users
:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
Como essa sintaxe é um pouco verbosa, o Laravel fornece métodos adicionais mais curtos que utilizam convenções para proporcionar uma melhor experiência ao programador. Quando usando o método foreignId
para criar sua coluna, o exemplo acima pode ser reescrito assim:
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
});
O método foreignId
cria uma coluna equivalente de tipo UNSIGNED BIGINT
, ao passo que o método constrained
utiliza convenções para determinar a tabela e a coluna sendo referenciada. Caso seu nome de tabela não corresponda às convenções do Laravel, você pode fornecer manualmente ao método constrained
. Além disso, você também pode especificar o nome da coluna gerada:
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained(
table: 'users', indexName: 'posts_user_id'
);
});
Você também pode especificar a ação desejada para as propriedades "on delete" e "on update" de uma restrição:
$table->foreignId('user_id')
->constrained()
->onUpdate('cascade')
->onDelete('cascade');
Uma sintaxe alternativa e expressiva também está disponível para estas ações:
Método | Descrição |
---|---|
$table->cascadeOnUpdate(); | As atualizações devem ocorrer em cascata. |
$table->restrictOnUpdate(); | As atualizações devem ser restritas. |
$table->noActionOnUpdate(); | Nenhuma ação sobre atualizações. |
$table->cascadeOnDelete(); | As exclusões devem ocorrer em cascata. |
$table->restrictOnDelete(); | Exclusões devem ser restritas. |
$table->nullOnDelete(); | As exclusões devem definir o valor da chave estrangeira como nulo. |
Todos os modificadores de coluna adicionais devem ser chamados antes do método constrain
:
$table->foreignId('user_id')
->nullable()
->constrained();
Removendo Chaves Estrangeiras
Para eliminar uma chave estrangeira, você pode utilizar o método dropForeign
, passando como argumento o nome da restrição de chave estrangeira que pretende eliminar. As restrições de chaves estrangeiras seguem o mesmo esquema de nomenclatura dos índices: ou seja, o nome da restrição de chave estrangeira é baseado no nome da tabela e colunas na restrição, seguido pelo sufixo \_foreign
:
$table->dropForeign('posts_user_id_foreign');
Alternativamente, você pode passar uma matriz contendo o nome da coluna que contém a chave estrangeira para o método dropForeign
. A matriz será convertida em um nome de restrição estrangeira usando as convenções de nomenclatura do Laravel:
$table->dropForeign(['user_id']);
Alternando Restrições de Chave Estrangeira
Você pode habilitar ou desabilitar restrições de chave estrangeira dentro de suas migrações usando os seguintes métodos:
Schema::enableForeignKeyConstraints();
Schema::disableForeignKeyConstraints();
Schema::withoutForeignKeyConstraints(function () {
// Restrições desabilitadas dentro deste *closure*...
});
ALERTA
O SQLite desabilita restrições de chave estrangeira por padrão. Ao usar o SQLite, certifique-se de ativar suporte de chaves estrangeiras na sua configuração do banco de dados antes de tentar criá-las em suas migrações. Além disso, o SQLite só suporta chaves estrangeiras ao criar a tabela e não quando as tabelas são alteradas [https://www.sqlite.org/omitted.html].
Eventos
Para conveniência, cada operação de migração enviará um evento. Todos os seguintes eventos estendem a classe base Illuminate\Database\Events\MigrationEvent
:
Classe | Descrição |
---|---|
Illuminate\Database\Events\MigrationsStarted | Um lote de migrações está prestes a ser executado. |
Illuminate\Database\Events\MigrationsEnded | Um lote de migrações terminou de ser executado. |
Illuminate\Database\Events\MigrationStarted | Uma única migração está prestes a ser executada. |
Illuminate\Database\Events\MigrationEnded | Uma única migração terminou de ser executada. |
Illuminate\Database\Events\NoPendingMigrations | Um comando de migração não encontrou migrações pendentes. |
Illuminate\Database\Events\SchemaDumped | Um dump de esquema de banco de dados foi concluído. |
Illuminate\Database\Events\SchemaLoaded | Um dump de esquema de banco de dados existente foi carregado. |