Coloque os dados onde eles pertencem
Também em 28 idiomas
English · Español · 日本語 · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

Módulo 4 de 6 do capítulo Modelar dados pelo significado, capítulo 2 do curso Data Architect. Cada módulo se sustenta sozinho. Anterior: Construa o modelo lógico · Próximo: Projete até a terceira forma normal, depois recue
A pergunta que este módulo responde: Como a normalização me ajuda a descobrir onde os dados realmente pertencem?
Temos um modelo lógico: entidades, relacionamentos, atributos e chaves. Agora quero fazer uma das perguntas mais importantes da modelagem de dados: este dado realmente pertence a este lugar?
Parece simples. Não é. Já vi muitos sistemas em que cada campo fazia sentido quando alguém o criou. O problema não era que os campos fossem ridículos; era que os fatos estavam armazenados no lugar errado. Uma entrega guarda informação que na verdade descreve um centro de distribuição. O mesmo endereço aparece em centenas de registros. Um campo guarda três valores separados por vírgulas. Uma mudança num fato de negócio significa atualizar 10 mil registros. Esse é o problema que a normalização nos ajuda a resolver, e antes de nos enterrarmos em terminologia de banco de dados, eis a ideia inteira: coloque um fato onde ele pertence. Todo o resto deste módulo nos ajuda a fazer isso de forma mais sistemática.
O que é normalização?
Seção intitulada “O que é normalização? ”Normalização é organizar os dados para que cada fato seja armazenado uma vez, no lugar a que pertence. Quando uma tabela está fazendo trabalhos demais, nós a dividimos em tabelas que descrevem uma coisa cada, e as ligamos com chaves.
Por que se dar ao trabalho? Porque um fato armazenado uma vez é um fato que mudamos uma vez. A normalização evita a redundância, o mesmo fato copiado em muitos registros, e com ela as inconsistências que aparecem quando uma cópia é atualizada e as outras não. É por isso que ela combina com sistemas transacionais como o Salesforce, em que registros são criados e atualizados o dia inteiro.
Normalizamos em passos chamados formas normais, e cada uma faz uma única pergunta:
- Primeira forma normal (1FN): um valor por campo, e algo que identifique de forma única cada linha.
- Segunda forma normal (2FN): cada fato descreve o todo do que identifica a linha, não só uma parte.
- Terceira forma normal (3FN): cada fato descreve esta coisa, não outra coisa com que ela se relaciona.
Há mais formas além da terceira. Vou falar um pouco delas mais adiante, e de por que normalmente paramos na terceira. Primeiro, vamos ver os três passos acontecerem.
Por que normalizamos?
Seção intitulada “Por que normalizamos? ”Quando ensino isto ao vivo, não começo com entregas. Começo com cachorros. Todo mundo entende de cachorros, então ninguém se distrai com o negócio, e podemos ver os dados tentando encontrar sua casa. Depois levamos os mesmos movimentos para a Steve Trucking.
Senta, fica, modelo
Seção intitulada “Senta, fica, modelo ”Início: a planilha crua. Coloco alguns cachorros na tela, e depois a sala acrescenta os seus. Em poucos minutos temos uma lista grande: o cachorro, o ano em que nasceu, quem é o dono, onde o dono mora, a raça, quem o criou e os truques que ele sabe.
| Cachorro | Nasceu | Dono | CEP | Cidade | Raça | Criador | Truques |
|---|---|---|---|---|---|---|---|
| Bella | 2017 | Marcus | 80202 | Denver | Labrador | Maple Ridge | Senta, Fica, Dá a pata |
| Milo | 2019 | Marcus | 80202 | Denver | Poodle | Golden Meadow | Senta, Rola |
| Max | 2022 | Ana | 64105 | Kansas City | Vira-lata | Senta, Finge de morto | |
| Luna | 2020 | Kenji | 98101 | Seattle | Husky | Cascade | Senta, Fica, Gira |
| Rocky | 2024 | Priya | 30301 | Atlanta | Beagle | Maple Ridge | Senta |
| Coco | 2014 | Ana | 64105 | Kansas City | Chihuahua | Little Paws | Dá a pata, Gira |
Funciona. Toda planilha funciona no primeiro dia. Mas olhe o que já está errado. Como encontro todo cachorro que sabe Dá a pata? O CEP da Ana está em duas linhas, e o do Marcus também: o que acontece se alguém atualizar uma e não a outra? Maple Ridge aparece duas vezes, e Kansas City também. E o Max veio do canil municipal, então não há criador nenhum.
Passo 1: primeira forma normal. Duas regras. Cada campo guarda um único valor, então a lista de truques separada por vírgulas tem que sair. E cada linha precisa de algo que a identifique de forma única. Não o nome do cachorro; há muitos cachorros chamados Max. Um ID: um ID gerado automaticamente ou um GUID. Os truques saem para linhas próprias, uma linha para cada cachorro e cada truque. E, quando um truque tem sua própria linha, há espaço para o que nunca conseguiríamos dizer numa lista com vírgulas: o quão difícil é o truque, o quão bem este cachorro o faz, e quando o aprendeu.
Cachorro (identificado pelo ID do cachorro)
| ID do cachorro | Nome | Nasceu | Dono | CEP | Cidade | Raça | Criador |
|---|---|---|---|---|---|---|---|
| D-001 | Bella | 2017 | Marcus | 80202 | Denver | Labrador | Maple Ridge |
| D-002 | Milo | 2019 | Marcus | 80202 | Denver | Poodle | Golden Meadow |
| D-003 | Max | 2022 | Ana | 64105 | Kansas City | Vira-lata | |
| D-004 | Luna | 2020 | Kenji | 98101 | Seattle | Husky | Cascade |
| D-005 | Rocky | 2024 | Priya | 30301 | Atlanta | Beagle | Maple Ridge |
| D-006 | Coco | 2014 | Ana | 64105 | Kansas City | Chihuahua | Little Paws |
Truque do cachorro (identificado por ID do cachorro + Truque)
| ID do cachorro | Truque | Dificuldade | Nível de habilidade | Aprendeu em |
|---|---|---|---|---|
| D-001 | Senta | Fácil | Especialista | 2017-11 |
| D-001 | Fica | Fácil | Especialista | 2018-01 |
| D-001 | Dá a pata | Média | Bom | 2018-06 |
| D-002 | Senta | Fácil | Especialista | 2020-02 |
| D-002 | Rola | Difícil | Aprendendo | 2023-05 |
| D-003 | Senta | Fácil | Bom | 2022-06 |
| D-003 | Finge de morto | Difícil | Aprendendo | 2024-03 |
| D-004 | Senta | Fácil | Especialista | 2020-11 |
| D-004 | Fica | Fácil | Bom | 2021-01 |
| D-004 | Gira | Média | Especialista | 2021-06 |
| D-005 | Senta | Fácil | Aprendendo | 2025-02 |
| D-006 | Dá a pata | Média | Especialista | 2015-06 |
| D-006 | Gira | Média | Aprendendo | 2025-04 |
Agora “todo cachorro que sabe Dá a pata” é uma pergunta simples. Mas repare no que identifica o Truque do cachorro: não uma coisa, duas coisas juntas, o cachorro e o truque. Guarde isso.
Passo 2: segunda forma normal. A segunda forma normal só importa quando uma linha é identificada por uma combinação, e o Truque do cachorro é. Então pergunto a cada coluna: ela descreve a combinação inteira, ou só parte dela? O nível de habilidade descreve este cachorro fazendo este truque: a Bella é especialista no Senta, o Rocky ainda está aprendendo. A data em que aprendeu, a mesma coisa. Mas a dificuldade? O Senta é fácil, não importa qual cachorro o faça. Ela descreve o truque, só parte da chave, e é por isso que “Fácil” se repete em toda linha do Senta. Então o truque ganha sua própria tabela, e o que sobra é o par.
Truque
| ID do truque | Truque | Dificuldade |
|---|---|---|
| T-01 | Senta | Fácil |
| T-02 | Fica | Fácil |
| T-03 | Dá a pata | Média |
| T-04 | Rola | Difícil |
| T-05 | Finge de morto | Difícil |
| T-06 | Gira | Média |
Truque do cachorro (ID do cachorro + ID do truque)
| ID do cachorro | ID do truque | Nível de habilidade | Aprendeu em |
|---|---|---|---|
| D-001 | T-01 | Especialista | 2017-11 |
| D-001 | T-02 | Especialista | 2018-01 |
| D-001 | T-03 | Bom | 2018-06 |
| D-002 | T-01 | Especialista | 2020-02 |
| D-002 | T-04 | Aprendendo | 2023-05 |
| D-003 | T-01 | Bom | 2022-06 |
| D-003 | T-05 | Aprendendo | 2024-03 |
| D-004 | T-01 | Especialista | 2020-11 |
| D-004 | T-02 | Bom | 2021-01 |
| D-004 | T-06 | Especialista | 2021-06 |
| D-005 | T-01 | Aprendendo | 2025-02 |
| D-006 | T-03 | Especialista | 2015-06 |
| D-006 | T-06 | Aprendendo | 2025-04 |
Essa tabela Truque do cachorro é a mesma que encontramos no módulo 2, e ela tem um nome na modelagem de dados: uma junção, ou, como eu chamo, um objeto de junção lógico. Um cachorro sabe muitos truques; um truque é conhecido por muitos cachorros. A junção fica entre eles, e não é encanamento vazio: ela guarda os fatos que pertencem ao próprio relacionamento, o nível de habilidade e a data. Vamos encontrá-la de novo no módulo 6, e no capítulo 3 veremos que o Salesforce usa “objeto de junção” num sentido mais estreito: um objeto de junção do Salesforce (Salesforce Junction Object) é um objeto personalizado com dois relacionamentos mestre-detalhes (capítulo 3, módulo 7).
Passo 3: terceira forma normal. Agora de volta à tabela Cachorro. Tudo nela é identificado pelo ID do cachorro, então a segunda forma normal não tem nada a dizer. A terceira forma normal faz uma pergunta diferente: este fato descreve o cachorro, ou outra coisa com que o cachorro se relaciona? A raça é uma coisa própria: um labrador é um labrador, qualquer que seja o cachorro, e os fatos sobre ela, como o porte, pertencem à raça, não à Bella. O CEP e a cidade descrevem o dono, não o cachorro: é onde a Ana mora, qualquer que seja o cachorro dela que estamos olhando. Os dados do criador descrevem o criador. Cada um desses é um fato sobre outro fato, então cada um vai para sua própria tabela, e o cachorro aponta para ela com uma chave estrangeira:
- Cachorro: ID do cachorro, Nome, Nasceu, ID do dono, ID da raça, ID do criador
- Dono: ID do dono, Nome, CEP, Cidade
- Raça: ID da raça, Raça, Porte
- Criador: ID do criador, Nome, Cidade
- Truque e Truque do cachorro, do passo 2
Agora a Ana é armazenada uma vez, com os dois cachorros dela apontando para ela. Maple Ridge é armazenado uma vez, e a tabela Raça nos dá um lugar para os fatos sobre cada raça, como o porte, que a planilha não tinha onde colocar. Uma chave estrangeira pode ficar em branco: o Max não tem ID do criador, e essa é uma resposta honesta, não uma lacuna. Aí faço uma pergunta capciosa para a sala: a data em que o dono pegou o cachorro, onde ela vai? No cachorro. Neste modelo, um cachorro tem um dono de cada vez, então essa data descreve o relacionamento do cachorro com o dono.
Daria para ir um passo além e separar a cidade do CEP; os livros fazem isso. Na prática, um endereço fica junto, e Kansas City fica em dois estados, de qualquer forma: um bom lembrete de que o mundo real não lê os nossos livros.
Essa é a progressão: uma planilha, depois três perguntas, e cada fato acaba num lugar só. Dê um passo atrás e olhe o que construímos. Uma lista bagunçada virou seis tabelas, cada uma descrevendo uma coisa, ligadas por chaves:
Ninguém precisou de uma única palavra do Salesforce para acompanhar isso. São só os cachorros, as pessoas em volta deles e o que eles sabem.
Agora vamos aplicar isso à Steve Trucking
Seção intitulada “Agora vamos aplicar isso à Steve Trucking ”Os cachorros deixam os movimentos fáceis de ver. Um negócio de verdade faz com que eles importem, porque os mesmos erros custam dinheiro de verdade em escala. Então vamos levar as mesmas três perguntas à Steve Trucking. Imagine que ela guarda suas entregas assim:
| Entrega | Parceiro varejista | Centro de distribuição | Cidade do CD | Equipe | Caminhão |
|---|---|---|---|---|---|
| 1001 | Keystone | CD Keystone Phoenix | Phoenix | Equipe 12 | 117 |
| 1002 | Keystone | CD Keystone Phoenix | Phoenix | Equipe 8 | 122 |
| 1003 | Keystone | CD Keystone Phoenix | Phoenix | Equipe 12 | 117 |
À primeira vista, nada aqui é complicado. Mas olhe o centro de distribuição. Repetimos “CD Keystone Phoenix, Phoenix” em cada entrega que sai dele: a Steve Trucking faz umas 3.300 entregas por dia em nove CDs, então algumas centenas por dia de cada um. O que acontece se esse CD se mudar? Quantos registros alteramos, e o que acontece se um ficar para trás? Agora os dados dizem que o CD está em duas cidades ao mesmo tempo. Isso é uma anomalia de atualização. E se quisermos cadastrar um novo CD antes da sua primeira entrega? E se excluirmos a última entrega de um CD: acabamos de excluir o único lugar onde guardávamos alguma coisa sobre ele?
Esses são sintomas diferentes do mesmo problema: misturamos fatos sobre coisas diferentes. Fatos do centro de distribuição pertencem ao centro de distribuição. Fatos da entrega pertencem à entrega. Fatos da equipe pertencem à equipe. Isso é normalização em termos práticos.
Primeira forma normal: não esconda estruturas que se repetem
Seção intitulada “Primeira forma normal: não esconda estruturas que se repetem ”Vamos começar pela primeira forma normal, ou 1FN, onde as pessoas às vezes tornam a normalização mais difícil do que precisa ser.
Suponha que uma entrega tenha um campo chamado Itens: “Geladeira, kit de máquina de gelo, recolhimento.” Colocamos três informações num campo só. Parece conveniente, até alguém perguntar: “Quantos recolhimentos fizemos no mês passado?” Ou imagine campos chamados Item 1, Item 2 e Item 3. Funciona, até a entrega com quatro itens. O problema não é termos escolhido o número errado de campos Item. O problema é não termos reconhecido a estrutura que se repete. Uma entrega pode ter vários itens. Isso é dado que devemos modelar: o Item de entrega que encontramos no módulo 2.
A lição prática da 1FN: não esconda estruturas que se repetem dentro de campos. Se o negócio lhe diz que algo pode acontecer muitas vezes, escute. Pode haver outra entidade tentando sair.
Você vai ver isso em orgs reais o tempo todo. Alguém precisa de uma descrição em vários idiomas, então cria um campo chamado Description_English, depois Description_French, depois Description_German. Ou uma aprovação precisa de algumas pessoas, e ganhamos Aprovador 1, Aprovador 2, Aprovador 3. Quando encontro isso numa revisão, é um tapinha na mão: conserte seu modelo de dados. Um ou dois, talvez, se o negócio realmente só tiver um ou dois. Qualquer coisa além disso deve ser um objeto filho: uma Tradução com um idioma, uma Etapa de aprovação com um aprovador. O próximo idioma, ou o quarto aprovador, vira um novo registro, não um novo campo e um deploy.
Segunda forma normal: descreva a coisa inteira
Seção intitulada “Segunda forma normal: descreva a coisa inteira ”A segunda forma normal, ou 2FN, importa quando um registro é identificado por uma combinação de coisas. Pegue o Item de entrega. Ele tem seu próprio ID de registro, mas cada um é único por Entrega + Produto. Suponha que guardamos a entrega, o produto, a quantidade e a descrição do produto.
A quantidade faz sentido aqui: ela descreve este produto nesta entrega. Mas a descrição do produto não descreve a combinação; descreve o produto. Coloque-a em cada Item de entrega e a repetimos toda vez que aquele modelo de geladeira sai em outro caminhão. Essa é a pista de que o fato pertence a outro lugar.
Então a pergunta da 2FN é: este atributo descreve a coisa inteira que estou identificando, ou só parte dela? Se ele descreve só o produto, vai com o Produto. Se descreve o lugar do produto nesta entrega específica (a quantidade, se será instalado), pertence ao Item de entrega. Muitos administradores nunca vão dizer conscientemente: “Agora estou aplicando a segunda forma normal.” Tudo bem. Me importa muito mais que você aprenda a perguntar: o que este fato realmente descreve?
Terceira forma normal: não guarde fatos sobre outros fatos
Seção intitulada “Terceira forma normal: não guarde fatos sobre outros fatos ”Agora a que mais me importa na modelagem do dia a dia: a terceira forma normal, ou 3FN.
Cada centro de distribuição tem um gerente do lado do Parceiro varejista, alguém que usa o portal do parceiro. Suponha que colocamos o nome do gerente do CD diretamente em cada entrega. O que acontece quando o CD ganha um novo gerente? Atualizamos cada entrega daquele CD. É o mesmo cheiro de novo: estamos repetindo um fato que pertence a outro lugar. A entrega sai de um CD; o CD tem um gerente. São dois relacionamentos, e o nome do gerente pertence ao CD.
A versão clássica dos livros é o endereço: CEP, cidade e estado guardados juntos em cada registro, quando a cidade e o estado normalmente decorrem do CEP. Mesma forma, mesma pergunta.
A pergunta prática da 3FN é: este fato descreve esta coisa, ou outra coisa com que esta se relaciona? Quero que você a faça o tempo todo.
Agora dê um passo atrás, do mesmo jeito que fizemos com os cachorros. A tabela de entregas com que começamos virou cinco coisas, cada uma guardando seus próprios fatos: o Item de entrega saiu na primeira forma normal, o Produto na segunda, e a cidade e o gerente do Centro de distribuição foram para o Centro de distribuição na terceira.
Mesmas três perguntas, mesmo resultado: cada fato num lugar só.
Uma forma simples de pensar em 1FN, 2FN e 3FN
Seção intitulada “Uma forma simples de pensar em 1FN, 2FN e 3FN ”Dá para passar um curso inteiro de banco de dados em normalização. Não vamos fazer isso. Para este curso, quero que você tenha o entendimento prático de um arquiteto:
- 1FN: estou escondendo vários valores ou estruturas que se repetem dentro de um campo ou de um registro?
- 2FN: este fato descreve a coisa inteira que estou identificando?
- 3FN: este fato realmente descreve esta entidade, ou algo relacionado a ela?
Essas não são definições para um livro de banco de dados. São perguntas que consigo usar de verdade enquanto projeto.
Sim, a normalização vai além: a forma normal de Boyce-Codd (FNBC) aperta as regras em torno da 3FN para modelos com chaves mais complicadas, e há a quarta, a quinta e até a sexta forma normal. Elas tratam de tipos mais raros de repetição, do tipo que vem de estruturas de chave incomuns mais do que de registros de negócio do dia a dia. Muita teoria e, na minha experiência, não vale a dor de cabeça para o tipo de sistema que construímos no Salesforce. Em sistemas de negócio, a pressão costuma ir na direção oposta: é muito mais provável recuarmos da terceira forma normal, por causa de usuários, relatórios e desempenho, do que irmos além dela. Esse é o próximo módulo. Saiba que as outras formas existem, mas para a maior parte do que fazemos, da 1FN à 3FN temos as ferramentas de raciocínio de que precisamos.
Projete até a terceira forma normal
Seção intitulada “Projete até a terceira forma normal ”Eis minha posição. Quando estou tentando entender um negócio e projetar seu modelo lógico, quero começar limpo: fatos da entrega com a entrega, fatos do centro de distribuição com o CD, fatos do caminhão com o caminhão, conceitos que se repetem modelados como conceitos. Não quero um fato de negócio copiado pelo modelo todo só porque isso pode facilitar uma tela ou um relatório. Ainda não.
Mas a normalização não é uma religião. O objetivo não é o modelo academicamente mais puro possível. Já vi arquitetos tão focados na pureza que o modelo vira um sofrimento para todos que precisam usá-lo. Não estamos tentando ganhar um concurso de normalização; estamos construindo um sistema, e esse sistema tem usuários, relatórios, integrações, necessidades de desempenho, escala e, cada vez mais, IA lendo os dados. Eles podem querer os dados em formatos diferentes.
Então meu ponto de partida é projetar até a terceira forma normal onde for viável, e depois recuar quando necessário: entender primeiro onde cada fato pertence. Depois, se vamos nos afastar disso, quero saber por quê. Se a resposta é “porque eu não sabia onde mais colocar o campo”, não basta. Se a resposta é “copiamos este valor de propósito porque ele simplifica o scorecard do parceiro, e temos uma forma confiável de mantê-lo sincronizado”, agora estamos tendo uma conversa de arquitetura.
O que um arquiteto decide aqui
Seção intitulada “O que um arquiteto decide aqui ”Quando estou normalizando um modelo lógico, procuro:
- Valores ou estruturas que se repetem e que deveriam ser modelados separadamente.
- Atributos que descrevem uma entidade diferente daquela em que estão armazenados.
- Fatos duplicados sem necessidade em muitos registros, e as dependências que os deixam inconsistentes.
- Conceitos de negócio escondidos dentro de campos.
- Um modelo limpo que representa a verdade antes de qualquer concessão da implementação.
Não porque todo sistema físico precise continuar perfeitamente normalizado. Muito pelo contrário. No próximo módulo vamos nos afastar do modelo limpo de propósito, por causa de usuários, relatórios, escala, análise e IA, e vamos fazer isso sabendo exatamente do que estamos abrindo mão.
