Como Usar Campos Multivalorados

Um erro muito comum de modelagem de banco de dados ocorre ao se usar campos multivalorados.

Para exemplificar, vamos usar um sistema de cadastro onde as pessoas informam as linguagens de programação que conhecem.

Muitas pessoas criariam uma tabela no banco de dados com esta estrutura:


Tabela pessoas

ID	Nome	Linguagens
1	Gisele	PHP,Java,Shell Script,Ruby
2	Maria	C,C++,Shell Script,Lua
3	Ana		PHP,Ruby,Lua

Essa estrutura não é aconselhável. Imagine se precisar buscar pelas pessoas que conhecem PHP. Você terá de fazer uma consulta assim (para MySQL):

SELECT id, pessoa FROM pessoas WHERE linguagens LIKE '%PHP%';

Aparentemente não é complicado, mas, para o processador, é pior fazer um Like que fazer uma comparação de igualdade.

Situação pior é a ação de editar o campo das linguagens. É necessário editar a string.

A solução é simples: criar relacionamento entre tabelas.

Criaremos trÊs tabelas: uma conterá os nomes das pessoas; outra, os nomes das linguagens; e, finalmente, a tabela que relaicionará as duas anteriores, associando a cada pessoa uma ou mais linguagens.

Tabela pessoas

ID Nome
1  Ana
2  Gisele
3  Maria

Tabela linguagens

ID Nome
1  PHP
2  C
3  Java
4  Ruby

Tabela pessoas_linguagens

ID_PESSOA ID_LINGUAGEM
1         1
1         2
2         2
2         3
3         1
3         2
3         3

Esta última tabela é a responsável por relacionar cada pessoa às linguagens que conhece. Note que o ID da pessoa pode aparecer em quantos registros forem necessários, ou seja, nessa tabela não há chave primária.

Segundo a tabela, a pessoa 1 (Ana) conhece as linguagens 1 e 2 (PHP e C). A pessoa 2 (Gisele) conhece as linguagens 2 e 3 (C e Java). A pessoa 3 (Maria) conhece as linguagens 1, 2 e 3 (PHP, C e Java).

Com uma estrutura assim, é bem mais fácil editar valores, removê-los ou buscar pessoas que detêm determinado conhecimento.

Darei um exemplo, para MySQL, de como fazer um SELECT para mostrar as linguagens que cada pessoa conhece.

Usaremos esta estrutura de tabelas:

### Tabela com os nomes das pessoas
CREATE TABLE pessoas(
 id SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
 nome VARCHAR(20) NOT NULL,
 PRIMARY KEY (id)
) TYPE InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
 
 
### Tabela com AS linguagens
CREATE TABLE linguagens(
 id SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
 nome VARCHAR(20) NOT NULL,
 PRIMARY KEY (id)
) TYPE InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
 
 
### Tabela para relacionar AS duas anteriores
CREATE TABLE pessoas_linguagens(
 id_pessoa SMALLINT(5) UNSIGNED NOT NULL,
 id_linguagem SMALLINT(5) UNSIGNED NOT NULL
) TYPE InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
 
 
INSERT INTO pessoas VALUES
(1, 'João'),
(2, 'Maria'),
(3, 'José'),
(4, 'Gisele'),
(5, 'Ana');
 
 
INSERT INTO linguagens VALUES
(1, 'PHP'),
(2, 'Java'),
(3, 'Lua'),
(4, 'C'),
(5, 'C++'),
(6, 'Shell Script'),
(7, 'Ruby');
 
 
INSERT INTO pessoas_linguagens VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 6),
(2, 1),
(2, 3),
(2, 6),
(2, 7),
(3, 1),
(3, 2),
(3, 4),
(3, 5);

A consulta SQL:

SELECT p.nome AS pessoa , l.nome AS linguagem FROM pessoas AS p JOIN pessoas_linguagens AS pl ON pl.id_pessoa = p.id JOIN linguagens AS l ON l.id = pl.id_linguagem ORDER BY p.nome ASC;

Saída:

Da para melhorar essa estrutura, fazendo, por exemplo, integridade referencial (chave estrangeira). Mas não abordarei esse tema neste post.

No meu Curso ULTIMATE PHP eu falo mais sobre banco de dados e Normalização. No capítulo final, onde montaremos uma aplicação prática, mostro como usar essa modelagem, com um exemplo passo-a-passo, usando MySQL e PDO. Clique aqui e conheça o Curso ULTIMATE PHP.

No meu Guia Gratuito de 15 Dicas e Boas Práticas de PHP falo sobre bancos de dados e outros pontos fundamentais para criar scripts PHP eficientes e com bom desempenho. Clique aqui para baixar o guia gratuito agora mesmo.

Essa e inúmeras outras dicas e técnicas eu abordo com mais detalhes no meu Curso ULTIMATE PHP. Estude PHP desde o básico, de forma 100% prática. Aprenda como se tornar um excelente programador, reconhecido e valorizado. Clique Aqui e Conheça o Curso Agora Mesmo!

 

The following two tabs change content below.
Graduado em Ciência da Computação, pela Universidade Federal do Paraná (UFPR), é desenvolvedor de software desde 2008, com foco em Desenvolvimento Web com PHP.