Como usar a chave Exclusiva por meio de combinações de campos da tabela?

9

Dê uma olhada no seguinte sqlfiddle: http://sqlfiddle.com/#!2/dacb5/1

CREATE TABLE contacts 
    (
     id int auto_increment primary key, 
     name varchar(20), 
     network_id int,
     network_contact_id int
    );

INSERT INTO contacts
(name, network_id, network_contact_id)
VALUES
('John', 4, 10),
('Alex', 4, 11),
('Bob', 4, 12),
('Jeff', 4, 45),
('Bill', 7, 11),
('Walter', 7, 45),
('Jessie', 7, 360) ;

Eu tenho uma tabela básica de contatos. Os campos network_ide network_contact_idcontêm números de identificação vinculados a outras tabelas.

Quero poder executar INSERT IGNOREconsultas nessa tabela, mas quero usar a combinação de network_ide network_contact_idcomo a chave exclusiva para comparar.

Por exemplo, se eu tentasse inserir um contato que tivesse network_id = 4e network_contact_id = 12, a INSERT IGNOREconsulta veria que a entrada já existe e ignoraria qualquer erro que fosse lançado.

Então, basicamente, network_idnão é único. network_contact_idnão é único. Mas a combinação dos dois é única. Como faço para configurar isso? Eu precisaria ter um único outro campo com os valores concatenados dos outros dois campos? Ou existe uma maneira de configurar as chaves desta tabela para que ela faça o que eu preciso?

Jake Wilson
fonte

Respostas:

9

Você tentou

CREATE TABLE contacts (
 id int auto_increment primary key, 
 name varchar(20), 
 network_id int,
 network_contact_id int, 
 UNIQUE KEY (`network_id`, `network_contact_id`)
);
Derek Downey
fonte
2
OMG Tanto a sua resposta como a @ ypercube têm timestamps idênticos. +1 para vocês dois.
RolandoMySQLDBA
11
Existe algum motivo para manter o idcampo como chave primária se esse unique keyitem já estiver definido?
Jake Wilson
11
Aqui está uma pergunta relacionada à questão de manter o campo id.
Derek Downey #
11
@Rolando: Na verdade dtest foi mais rápido em 1 segundo :)
ypercubeᵀᴹ
6

Altere a definição da tabela adicionando uma UNIQUE KEYrestrição na combinação das duas colunas:

CREATE TABLE contacts 
    (
     id int auto_increment primary key, 
     name varchar(20), 
     network_id int,
     network_contact_id int,
     CONSTRAINT network_id_contact_id_UNIQUE
       UNIQUE KEY (network_id, network_contact_id)
    );

Você também deve verificar esta resposta por Bill Karwin sobre as diferenças entre INSERT IGNORE, REPLACEeINSERT ... ON DUPLICATE KEY UPDATE

ypercubeᵀᴹ
fonte
11
Por que sua definição tem restrição lá quando o DTest não? Qual é a diferença?
Jake Wilson
4
Isso está fornecendo apenas um nome para a restrição. Se bem me lembro, com a resposta do DTest, a restrição será nomeada automaticamente pelo MySQL.
ypercubeᵀᴹ