Chaves SQL, MUL x PRI x UNI

247

Qual é a diferença entre MUL, PRIe UNIno MySQL?

Estou trabalhando em uma consulta MySQL, usando o comando:

desc mytable; 

Um dos campos é mostrado como MULchave, outros são exibidos como UNIou PRI.

Eu sei que se uma chave é PRI, apenas um registro por tabela pode ser associado a essa chave. Se uma chave for MUL, isso significa que pode haver mais de um registro associado?

Aqui está a resposta de mytable.

+-----------+---------+------+-----+---------+-------+
| Field     | Type    | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| courseid  | int(11) | YES  | MUL | NULL    |       | 
| dept      | char(3) | YES  |     | NULL    |       | 
| coursenum | char(4) | YES  |     | NULL    |       | 
+-----------+---------+------+-----+---------+-------+
O maestro
fonte

Respostas:

158

Isso significa que o campo é (parte de) um índice não exclusivo. Você pode emitir

show create table <table>;

Para ver mais informações sobre a estrutura da tabela.

Matt Healy
fonte
2
Se esse campo é (parte de) um índice não exclusivo, por que é MULexibido somente nessa coluna e também em todas as outras colunas?
Vikas Goel
1
Não há necessariamente outras colunas envolvidas. Não exclusivo significa apenas que o mesmo valor pode ocorrer mais de uma vez nessa coluna .
Pgdetz7
424
DESCRIBE <table>; 

Este é um atalho para:

SHOW COLUMNS FROM <table>;

De qualquer forma, existem três valores possíveis para o atributo "Chave":

  1. PRI
  2. UNI
  3. MUL

O significado de PRIe UNIé bastante claro:

  • PRI => chave primária
  • UNI => chave única

A terceira possibilidade, MUL(sobre a qual você perguntou) é basicamente um índice que não é uma chave primária nem uma chave exclusiva. O nome vem de "múltiplo" porque são permitidas várias ocorrências do mesmo valor. Diretamente da documentação do MySQL :

Se Keyfor MUL, a coluna é a primeira coluna de um índice não exclusivo, no qual são permitidas várias ocorrências de um determinado valor dentro da coluna.

Há também uma advertência final:

Se mais de um dos valores-chave se aplica a uma determinada coluna de uma tabela, exibirá o um com a mais alta prioridade, na ordem PRI, UNI, MUL.

Como uma observação geral, a documentação do MySQL é bastante boa. Em caso de dúvida, confira!

robguinness
fonte
3
"As chaves primárias devem conter valores exclusivos." w3schools.com/sql/sql_primarykey.asp
ktm5124
6
É possível dizer, em alguns contextos, que MUL significa que a chave é uma chave estrangeira?
Armel Larcier
4
@robguinness, a documentação do MySQL parece escrita por não-inglês. Muitas vezes eles usavam três linhas para explicar algo que poderia ser feito com uma linha.
Pacerier
12
Observe também que uma tabela com uma chave estrangeira que faz referência à chave primária de outra tabela é MUL.
Pacerier
@ pacerier, concordo com você em relação à verbosidade da documentação do MySQL. É por isso que o Stackoverflow geralmente é o primeiro lugar que eu verifico, especialmente se estou com pressa. ;-)
robguinness
86

Passo a passo sobre o que é MUL, PRI e UNI no MySQL?

Na documentação do MySQL 5.7 :

  • Se Key for PRI, a coluna é uma CHAVE PRIMÁRIA ou é uma das colunas em uma CHAVE PRIMÁRIA de várias colunas.
  • Se Key for UNI, a coluna é a primeira coluna de um índice UNIQUE. (Um índice UNIQUE permite vários valores NULL, mas você pode dizer se a coluna permite NULL verificando o campo Null.)
  • Se Key for MUL, a coluna é a primeira coluna de um índice não exclusivo, no qual são permitidas várias ocorrências de um determinado valor dentro da coluna.

Exemplos ao vivo

Grupo de controle, este exemplo não tem PRI, MUL ou UNI:

mysql> create table penguins (foo INT);
Query OK, 0 rows affected (0.01 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| foo   | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

Uma tabela com uma coluna e um índice na coluna possui um MUL:

mysql> create table penguins (foo INT, index(foo));
Query OK, 0 rows affected (0.01 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| foo   | int(11) | YES  | MUL | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

Uma tabela com uma coluna que é uma chave primária possui PRI

mysql> create table penguins (foo INT primary key);
Query OK, 0 rows affected (0.02 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| foo   | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

Uma tabela com uma coluna que é uma chave exclusiva possui UNI:

mysql> create table penguins (foo INT unique);
Query OK, 0 rows affected (0.01 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| foo   | int(11) | YES  | UNI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

Uma tabela com um índice cobrindo foo e barra tem MUL apenas em foo:

mysql> create table penguins (foo INT, bar INT, index(foo, bar));
Query OK, 0 rows affected (0.01 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| foo   | int(11) | YES  | MUL | NULL    |       |
| bar   | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

Uma tabela com dois índices separados em duas colunas possui MUL para cada uma

mysql> create table penguins (foo INT, bar int, index(foo), index(bar));
Query OK, 0 rows affected (0.01 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| foo   | int(11) | YES  | MUL | NULL    |       |
| bar   | int(11) | YES  | MUL | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

Uma tabela com um Índice abrangendo três colunas possui MUL na primeira:

mysql> create table penguins (foo INT, 
       bar INT, 
       baz INT, 
       INDEX name (foo, bar, baz));
Query OK, 0 rows affected (0.01 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| foo   | int(11) | YES  | MUL | NULL    |       |
| bar   | int(11) | YES  |     | NULL    |       |
| baz   | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)

Uma tabela com uma chave estrangeira que referencia a chave primária de outra tabela é MUL

mysql> create table penguins(id int primary key);
Query OK, 0 rows affected (0.01 sec)

mysql> create table skipper(id int, foreign key(id) references penguins(id));
Query OK, 0 rows affected (0.01 sec)

mysql> desc skipper;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  | MUL | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> desc penguins;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

Cole isso no seu neocórtex e ajuste o dial para "frappe".

Eric Leschinski
fonte
6

Para Mul, essa também foi uma documentação útil para mim - http://grokbase.com/t/mysql/mysql/9987k2ew41/key-field-mul-newbie-question

"MUL significa que a chave permite que várias linhas tenham o mesmo valor. Ou seja, não é uma chave UNIque."

Por exemplo, digamos que você tenha dois modelos, Postagem e Comentário. A postagem tem um relacionamento has_many com Comentário. Faria sentido, então, que a tabela Comment tivesse uma tecla MUL (ID da postagem) porque muitos comentários podem ser atribuídos à mesma postagem.

comprometido
fonte
4
se não é apenas uma chave ÚNICA, por que mencionar explicitamente como MUL? Por padrão, não é EXCLUSIVO, não é? Ou eu estou esquecendo de alguma coisa?
Sudip Bhandari
@SudipBhandari se você definir o índice em um campo que não seja primário nem exclusivo, o MySQL definirá o tipo de chave como MUL, além da explicação acima, esse tipo de tipo ajuda o MySQL a entender com que tipo de índice está lidando.
Adnan