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
- Qual é a diferença entre SQLite e um servidor de banco de dados?
- Como o SQLite lida com escritas simultâneas?
- Como um servidor de banco lida com concorrência?
- Vários servidores podem compartilhar um arquivo SQLite?
- Até que tamanho o SQLite chega?
- Quando migrar do SQLite para um servidor de banco?
- Como migrar do SQLite para o PostgreSQL?
- Como fazer isso na Square Cloud
- Perguntas frequentes
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.
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:
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:
- 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.
- Escritas colidem. Os logs mostram
database is lockedou as escritas demoram mais conforme o tráfego cresce, mesmo com WAL e timeout. - Você precisa de roles e permissões. Serviços ou pessoas diferentes devem ver tabelas diferentes.
- Você quer recursos de servidor. Extensões, replicação, tipos de índice avançados ou tipos de dados especializados.
- 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?#
- Isole as consultas. Coloque o SQL atrás de uma pequena camada de dados ou de um ORM, para que só essa camada mude.
- 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. - Reescreva as diferenças de SQL. Placeholders (
?vira$1em muitos drivers),AUTOINCREMENTviraGENERATED ... AS IDENTITY, e algumas funções mudam. - Crie o schema com migrations. Veja migrations de banco de dados no deploy.
- Copie os dados, compare a contagem de linhas e então aponte a aplicação para o banco novo.
- 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
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.
Mais em Bancos de dados
Ver todos os 24 artigos- Como hospedar um banco de dados (e conectar sua aplicação)Para hospedar um banco de dados, escolha o motor, crie a instância, guarde a string de conexão em variável de ambiente e teste a conexão. Veja o passo a passo.
- O que é Redis e para que serveRedis é um banco de dados em memória que guarda pares chave-valor e estruturas de dados. Veja como funciona, para que serve e quando não usar.
- Como fazer backup do banco de dados (MySQL, PostgreSQL, MongoDB)Faça backup de MySQL, PostgreSQL e MongoDB com mysqldump, pg_dump e mongodump, e restaure o dump. Veja os comandos, como verificar e os erros comuns.
- O que é PostgreSQL e para que servePostgreSQL é um banco de dados relacional open source que usa SQL e garante transações ACID. Veja como funciona, para que serve e quando escolher outro banco.