Pergunta

Eu estou olhando para os docs MySQL aqui e tentar resolver a distinção entre ESTRANGEIROS chaves e restrições. Eu pensei que uma FK foi uma restrição, mas os docs parecem falar sobre eles como se fossem coisas separadas.

A sintaxe para criar uma FK é (em parte) ...

[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)

Assim, a cláusula de "coerção" é opcional. Por que você incluí-lo ou não incluí-lo? Se você deixá-lo fora o MySQL criar uma chave estrangeira, mas não uma restrição? Ou é mais como um "CONSTRAINT" não é nada mais do que um nome para você FK, por isso, se você não especificá-lo você ter uma FK anônimo?

Qualquer esclarecimento seria muito apreciada.

Obrigado,

Ethan

Foi útil?

Solução

Sim, uma chave estrangeira é um tipo de restrição. MySQL tem suporte desigual para restrições:

  • PRIMARY KEY: Sim. Como restrição de tabela e restrição de coluna
  • FOREIGN KEY: sim como restrição de tabela, mas apenas com mecanismos de armazenamento InnoDB e BDB; caso contrário analisadas mas ignoradas.
  • CHECK:. Analisado, mas ignorado em todos os mecanismos de armazenamento
  • UNIQUE: Sim. Como restrição de tabela e restrição de coluna
  • NOT NULL: Sim. Como restrição de coluna
  • DEFERRABLE e outra restrição atributos: não há suporte.

A cláusula CONSTRAINT permite nomear a restrição explícita, seja para fazer metadados mais legível ou então usar o nome quando você quer deixar cair a restrição. O padrão SQL requer que a cláusula CONSTRAINT é opcional. Se você deixá-lo fora, o RDBMS cria um nome automaticamente, eo nome é até a implementação.

Outras dicas

Em geral (não MySQL necessário), chaves estrangeiras são restrições, mas as restrições não são sempre as chaves estrangeiras. Pense restrições de chave primária, restrições exclusivas etc.

Voltando à pergunta específica, você está correto, omitindo CONSTRAINT parte [símbolo] vai criar uma FK com um nome gerado automaticamente.

A partir de agora, os nossos CRIAR DDLs tabela são deste formato - aviso a sintaxe definição UNIQUE KEY e FOREIGN KEY temos usado.

CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY,
    account_nbr INT NOT NULL,
    account_name VARCHAR(50) NOT NULL,
    active_flg CHAR(1) NOT NULL DEFAULT 'Y',
    vendor_nbr INT NOT NULL,
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp,
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp,
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    UNIQUE KEY uk1_my_table(account_nbr, account_name),
    FOREIGN KEY fk1_my_table(vendor_nbr) REFERENCES vendor(vendor_nbr)
    );

Neste formato, o MySQL é a criação de índice de es com os nomes uk1_my_table e fk1_my_table automaticamente; mas o nome do objeto FK é algo diferente - my_table_ibfk_1 (ie tablename_ibfk_N -. sistema definido). Então ALTER TABLE my_table DROP FOREIGN KEY fk1_my_table não trabalho (e, portanto, frustrando e levantando alarmes), como não há nenhum objeto db FK por esse nome.

Aqui está um formato DDL alternativa wrt os constarints (Ref: https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html ): -

CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY,
    account_nbr INT NOT NULL,
    account_name VARCHAR(50) NOT NULL,
    active_flg CHAR(1) NOT NULL DEFAULT 'Y',
    vendor_nbr INT NOT NULL,
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp,
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp,
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    CONSTRAINT uk1_my_table UNIQUE KEY (account_nbr, account_name),
    CONSTRAINT fk1_my_table FOREIGN KEY (vendor_nbr) REFERENCES vendor(vendor_nbr)
    );

Neste formato, o MySQL está ainda a criação de índice de es com os nomes uk1_my_table e fk1_my_table automaticamente, mas o nome do objeto FK não é algo diferente - é fk1_my_table como mencionado no DDL. Então obras ALTER TABLE my_table DROP FOREIGN KEY fk1_my_table, mas deixa para trás o INDEX xará.

E, nota que ALTER TABLE my_table DROP INDEX fk1_my_table não funcionará inicialmente (quando o FK ainda não é descartado), com uma mensagem de erro que ele está sendo usado em uma FK! Se o comando DROP FK foi executado com sucesso, só então o DROP INDEX funciona.

Espero que isso explica e ajuda a resolver a confusão.

Não é possível responder para o MySQL, mas FK são restrições. Tudo o que obriga seus dados em uma determinada condição é uma restrição. Existem vários tipos de restrições, único, chave primária, Cheque e chaves estrangeiras são todas as restrições. Talvez MySQL tem outros.

Às vezes as palavras são permitidas em comandos, mas não exigida sheerly para facilitar a leitura como o DA na instrução DELETE.

Se não estou errado, as restrições precisa índices, então quando você criar, por exemplo, um MySQL restrição de chave estrangeira cria automaticamente um índice também.

Este é provavelmente o tema mais confuso no MySQL.

Muitas pessoas dizem que, por exemplo, a 'chave primária', a 'chave estrangeira', e a tecla 'UNIQUE' são realmente índices! (Documentação oficial do MySQL é incluído aqui)

Muitos outros, por outro lado, dizer que eles são em vez restrições (que faz sentido, porque quando você usá-los, você está realmente impor restrições sobre as colunas afetadas).

Se eles realmente são índices, então qual é o ponto em usar o clausule restrição a fim de dar-lhe um nome, uma vez que você deveria ser capaz de usar o nome desse índice ao criá-la?

Exemplo:

... index_name FOREIGN KEY (nome_coluna1, nome_coluna2, ...)

Se FOREIGN KEY é um índice, então devemos ser capazes de usar o index_name para lidar com isso. No entanto, não podemos.

Mas se eles não são índices, mas contraints reais que fazer índices usar para trabalhar, então isso faz sentido.

Em qualquer caso, nós não sabemos. Na verdade, ninguém parece saber.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top