SQLite ou servidor de banco de dados: quando migrar

Fique no SQLite enquanto uma aplicação numa só máquina for dona dos dados e as escritas não forem constantes. Migre para um servidor de banco quando várias máquinas precisarem dos dados ou muitas escritas colidirem.

Atualizado em 7 min de leitura

Objetivos de aprendizado

Depois de ler este artigo, você vai conseguir:

  • Entender como um banco embutido difere de um servidor de banco de dados
  • Reconhecer os sinais de que o SQLite já não basta
  • Planejar uma migração segura para PostgreSQL ou MySQL
Nesta página

O SQLite é um banco de dados que vive num único arquivo e roda dentro da sua aplicação. PostgreSQL e MySQL são servidores de banco: processos separados com os quais a sua aplicação conversa por uma conexão de rede. Os dois falam SQL, mas resolvem problemas diferentes, e a escolha errada cobra a conta mais tarde: escritas lentas, arquivo travado ou uma migração dolorosa.

A comparação abaixo parte do caso mais comum: um bot, uma API ou um site que começou pequeno e pode crescer. Se você ainda está escolhendo a família de banco, leia antes como escolher um banco de dados para o seu projeto.

SQLiteuma bibliotecamesma máquinaAplicação+ SQLite embutidolê e escreveapp.dbum escritor por vezredeOutra máquinaPostgreSQL, MySQLApp 1App 2App 3redeProcesso do servidorlock por linhaArquivos de dadosacesso só pelo servidor
O SQLite é um arquivo dentro de uma máquina; um servidor de banco atende várias instâncias pela rede.

Qual é a diferença entre SQLite e um servidor de banco de dados?#

O SQLite é uma biblioteca. A sua aplicação abre um arquivo, como app.db, e lê e escreve nele diretamente. Não há nada para instalar, nem porta, nem senha, nem processo separado. Por isso ele vem embutido em celulares, navegadores e muitos aplicativos de desktop.

Um servidor de banco de dados (PostgreSQL, MySQL) é um processo de longa duração que é dono dos arquivos de dados. A sua aplicação conecta por TCP, se autentica e envia consultas. O servidor coordena todos os clientes, então muitas aplicações e máquinas podem compartilhar um banco com segurança. Veja o que é PostgreSQL e o que é MySQL.

Critério SQLite Servidor de banco (PostgreSQL, MySQL)
Roda como Biblioteca dentro da aplicação Processo de servidor separado
Configuração Nenhuma, só um caminho de arquivo Instalar ou hospedar, criar usuários, definir credenciais
Leitores simultâneos Muitos Muitos
Escritores simultâneos Um por vez Muitos, com bloqueio por linha
Acesso de várias máquinas Não suportado por sistema de arquivos de rede Feito para isso
Latência típica Sem salto de rede Uma ida e volta de rede por consulta
Tipagem Flexível por padrão, tabelas STRICT opcionais Rígida por padrão
Tamanho máximo Até cerca de 281 TB na teoria Limitado pelo disco e pelo seu plano
Usuários e permissões Nenhum, só permissões do arquivo Roles e permissões por tabela

Como o SQLite lida com escritas simultâneas?#

O SQLite deixa muitas conexões lerem ao mesmo tempo, mas só uma escrever por vez. No modo padrão (rollback journal), quem escreve também pode bloquear leitores enquanto confirma a transação. Trocar para o modo WAL (write-ahead log) deixa leitores e um escritor rodarem juntos, embora continue existindo só um escritor.

Basta ativar uma vez por banco, porque a configuração fica gravada no arquivo e vale para todas as conexões:

python
import sqlite3

con = sqlite3.connect("app.db", timeout=10)  # um escritor bloqueado espera até 10 s
print(con.execute("PRAGMA journal_mode=WAL").fetchone())  # ('wal',)
con.execute("PRAGMA foreign_keys=ON")  # desligado por padrão, ative em toda conexão
con.execute("CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, total REAL NOT NULL)")
with con:
    con.execute("INSERT INTO orders (total) VALUES (?)", (19.9,))
print(con.execute("SELECT COUNT(*) FROM orders").fetchone())
con.close()

Se o pragma não consegue trocar de modo, ele devolve o modo anterior, então confira o valor impresso. Mesmo no modo WAL, uma consulta pode devolver SQLITE_BUSY em casos raros: trate esse erro no código que escreve com frequência.

Para um bot que salva configurações algumas vezes por minuto, um escritor por vez passa despercebido. Para uma API que recebe centenas de escritas por segundo, cada escrita entra na fila atrás da anterior.

Como um servidor de banco lida com concorrência?#

O PostgreSQL usa controle de concorrência multiversão (MVCC). Cada consulta enxerga uma fotografia consistente dos dados, então ler nunca bloqueia escrever e escrever nunca bloqueia ler. Escritores só esperam uns pelos outros quando mexem na mesma linha. Duas requisições que atualizam linhas diferentes rodam em paralelo.

Esse bloqueio por linha é o principal ganho de ir para um servidor. É também o motivo de um servidor exigir mais cuidado: limite de conexões, tamanho de pool e credenciais passam a ser problema seu. Se você bater nesses limites, veja o erro de too many connections.

Vários servidores podem compartilhar um arquivo SQLite?#

Não com segurança. A documentação do SQLite explica que os locks de escrita dele se comportam mal em alguns sistemas de arquivos de rede, o que pode corromper o banco. O modo WAL nem funciona em sistema de arquivos de rede, porque todos os processos precisam estar na mesma máquina.

Esse é o motivo mais comum para migrar. Quando você sobe uma segunda instância da aplicação, para balanceamento de carga ou como worker separado em outra máquina, cada instância precisa alcançar os mesmos dados pela rede. É para isso que existe um servidor de banco.

Até que tamanho o SQLite chega?#

Maior do que a maioria dos projetos vai precisar. O máximo teórico é de cerca de 281 TB com o maior tamanho de página, e cerca de 17,5 TB com a página padrão de 4096 bytes. Uma única string ou blob tem limite de 1.000.000.000 bytes por padrão.

Tamanho raramente é o motivo para sair do SQLite. A equipe do SQLite sugere um motor cliente/servidor quando os dados podem chegar à escala de terabytes, principalmente porque um arquivo único é difícil de distribuir, copiar e ajustar nesse tamanho.

Quando migrar do SQLite para um servidor de banco?#

Migre quando uma ou mais destas situações for verdade:

  1. Mais de uma máquina precisa dos dados. Uma segunda instância da aplicação, um worker separado ou um esquema com balanceamento de carga.
  2. Escritas colidem. Os logs mostram database is locked ou as escritas demoram mais conforme o tráfego cresce, mesmo com WAL e timeout.
  3. Você precisa de roles e permissões. Serviços ou pessoas diferentes devem ver tabelas diferentes.
  4. Você quer recursos de servidor. Extensões, replicação, tipos de índice avançados ou tipos de dados especializados.
  5. Os dados estão crescendo rumo aos terabytes.

Fique no SQLite quando um processo é dono dos dados, as escritas são moderadas e você valoriza configuração zero. Isso cobre muitos bots, ferramentas internas, protótipos e sites de tráfego baixo a médio. Se você só precisa de dados temporários rápidos, o Redis pode servir melhor que os dois.

Como migrar do SQLite para o PostgreSQL?#

  1. Isole as consultas. Coloque o SQL atrás de uma pequena camada de dados ou de um ORM, para que só essa camada mude.
  2. Corrija os tipos. O SQLite aceita quase qualquer valor em qualquer coluna, a menos que a tabela seja STRICT. O PostgreSQL rejeita dado errado, então confira antes datas, booleanos e números.
  3. Reescreva as diferenças de SQL. Placeholders (? vira $1 em muitos drivers), AUTOINCREMENT vira GENERATED ... AS IDENTITY, e algumas funções mudam.
  4. Crie o schema com migrations. Veja migrations de banco de dados no deploy.
  5. Copie os dados, compare a contagem de linhas e então aponte a aplicação para o banco novo.
  6. Guarde o arquivo antigo até verificar o banco novo e ter um backup.

Escolha o servidor pelo formato dos dados. Para dados relacionais, PostgreSQL ou MySQL mostra os prós e contras.

Como fazer isso na Square Cloud#

O SQLite não precisa de hospedagem de banco: é um arquivo que a sua aplicação abre sozinha. O disco de uma aplicação persiste entre restarts e deploys, então o arquivo sobrevive. Um deploy (um ZIP novo ou um push) sobrescreve só os arquivos enviados, então deixe o .db fora do envio, ou ele substitui os seus dados em produção. Cada aplicação tem o próprio disco, e aplicações atrás de um load balancer não compartilham arquivos. Por isso o SQLite continua sendo uma escolha de instância única.

Quando o SQLite ficar pequeno para o projeto, a Square Cloud oferece hospedagem de PostgreSQL, MySQL, MongoDB e Redis a partir do plano Standard. Você cria o banco no painel, e ele é provisionado em segundos no mesmo datacenter das suas aplicações, com cerca de 1 ms de latência média e TLS obrigatório. O painel entrega a URL de conexão completa e um certificado para baixar. Copie a URL para as variáveis de ambiente da aplicação e rode você mesmo a migração.

Você tira snapshots manuais quando quiser, e todo plano com bancos inclui também um snapshot automático diário. Dá para restaurar um snapshot no mesmo banco, em outro do mesmo motor ou num banco novo. Compare as opções na página de bancos de dados.

Hospedagem de bancos

MongoDB, PostgreSQL, MySQL e Redis no mesmo datacenter do app

Saiba mais

Perguntas frequentes

O SQLite serve para produção?

Sim, para a carga certa. A documentação do SQLite diz que a maioria dos sites de tráfego baixo a médio cabe nele e chama 100 mil acessos por dia de estimativa conservadora. O limite são escritas simultâneas e acesso pela rede, não confiabilidade.

Quantos usuários o SQLite aguenta?

Não existe um número de usuários, porque o SQLite não tem conexões com um servidor. Ele permite muitos leitores ao mesmo tempo, mas um escritor por vez, então o que importa é com que frequência você escreve e quanto cada escrita demora.

Duas aplicações podem usar o mesmo arquivo SQLite?

Na mesma máquina, sim, com o modo WAL e um busy timeout. Entre máquinas, por um sistema de arquivos de rede, não. A documentação do SQLite avisa que o travamento de arquivos pode falhar nesse cenário e corromper o banco.

O SQLite é mais rápido que o PostgreSQL?

Para consultas simples vindas de um processo, muitas vezes é, porque não há salto de rede nem processo de servidor. Com muitos escritores simultâneos, um servidor de banco escala melhor.

Dá para migrar do SQLite para o PostgreSQL depois?

Dá. Prepare-se para tipos diferentes, tipagem mais rígida e diferenças de SQL, e depois mova os dados com uma exportação e uma importação. Manter as consultas atrás de uma pequena camada de dados deixa a troca bem mais barata.

Próximo artigoQuanto custa um banco de dados na nuvem?Um banco de dados na nuvem custa de zero a centenas de dólares por mês. Veja o que define o preço: instância, disco, tráfego, snapshots e como estimar o seu.

Mais em Bancos de dados

Ver todos os 24 artigos