O que é uma convenção de nomenclatura adequada para MySQL FKs?


Respostas:


141

No MySQL, não há necessidade de dar um nome simbólico às restrições de chave estrangeira. Se um nome não for fornecido, o InnoDB cria um nome exclusivo automaticamente.

Em qualquer caso, esta é a convenção que utilizo:

fk_[referencing table name]_[referenced table name]_[referencing field name]

Exemplo:

CREATE TABLE users(
    user_id    int,
    name       varchar(100)
);

CREATE TABLE messages(
    message_id int,
    user_id    int
);

ALTER TABLE messages ADD CONSTRAINT fk_messages_users_user_id 
    FOREIGN KEY (user_id) REFERENCES users(user_id);

Tento manter os mesmos nomes de campo nas tabelas de referência e referenciadas, como no user_idexemplo acima. Quando isso não for prático, também acrescento o nome do campo referenciado ao nome da chave estrangeira.

Essa convenção de nomenclatura me permite "adivinhar" o nome simbólico apenas olhando as definições da tabela e, além disso, também garante nomes exclusivos.


13
A razão para criar um nome simbólico é para fazer referência quando você quiser / precisar descartar a restrição. Oracle e SQL Server permitem que você desabilite restrições específicas. Se você não tiver fk no nome, você deve confirmar que a restrição é uma restrição de chave estrangeira ...
OMG Ponies

11
O que eu gosto de fazer é usar um sublinhado duplo entre o nome da tabela de referência e o nome da tabela referenciada. Isso dá a você a dupla vantagem de listar em ordem alfabética, mantendo todos os FKs de uma tabela juntos e, ao mesmo tempo, ajudando a evitar colisões / confusão de nomes quando há nomes de tabelas com várias palavras. Também omito a parte do campo do nome quando é trivial (ou seja, um único campo int faz referência à identidade PK de outra tabela).
Joel Brown de

2
E se houver mais de 1 chave estrangeira? Exemplo: member_id~> link para o membro da tabela, edited_id~> chave estrangeira para o usuário editado, também link para o membro da tabela. Como devo nomeá-los?
TomSawyer

@TomSawyer: Eu adiciono 'pk_' a todas as chaves estrangeiras, seguido pela tabela referenciada (por exemplo, 'membros'), seguido pelo uso / sentido (por exemplo, 'editor' ou 'autor'). Então, eu tenho algo como 'pk_members_author' ou 'pk_members_editor'.
Nrgyzer

28

minha escolha é diferente. na minha opinião, uma tabela deve ter um idcampo, não user_idum, porque a tabela é apenas chamada user, então:

CREATE TABLE users(
   id    int,
   name       varchar(100)
);

CREATE TABLE messages(
   id int,
   user_id    int
);

user_idna messagestabela é um campo fk, então ele deve deixar claro qual id é ( user_id).

uma convenção de nomenclatura totalmente autoexplicativa, na minha opinião, poderia ser:

fk_[referencing table name]_[referencing field name]_[referenced table name]_[referenced field name]

i.e.: `fk_messages_user_id_users_id`

Nota:

  • você pode, em alguns casos, omitir o segundo elemento ([nome do campo de referência])
  • este fk poderia ser único, porque se messages_userexistir uma tabela, o nome do campo de referência deve ser user_id(e não apenas id) e o nome fk deve ser:

    fk_messages_user_user_id_users_id

em outras palavras, uma convenção de nomenclatura de chave estrangeira garante que você tenha certeza sobre nomes exclusivos se você também usar uma convenção de nomenclatura "campo de referência / referenciado" (e você pode escolher a sua própria, é claro).


4
Os nomes têm uma maneira de persistir no código. Eventualmente, você encontrará uma $idvariável em algum lugar sem nenhuma ideia a qual tabela ela pertence. Quanto mais antiga for a sua base de código e quanto mais pessoas trabalharem nela, mais provável será.
CJ Dennis

9

Se você não se pega referenciando fk's tão frequentemente depois que eles são criados, uma opção é mantê-lo simples e deixar o MySQL dar a nomenclatura para você (como Daniel Vassallo menciona no início de sua resposta ).

Embora você não possa "adivinhar" exclusivamente os nomes das restrições com este método - você pode encontrar facilmente o nome da restrição da chave estrangeira executando uma consulta:

use information_schema;
select TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME from KEY_COLUMN_USAGE where REFERENCED_TABLE_SCHEMA = 'your_db_schema_name' ORDER BY TABLE_NAME;

Por exemplo, você pode receber o seguinte da consulta:

+------------+-------------+-----------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+-------------+-----------------+-----------------------+------------------------+
| note       | taskid      | note_ibfk_2     | task                  | id                     |
| note       | userid      | note_ibfk_1     | user                  | id                     |
| task       | userid      | task_ibfk_1     | user                  | id                     |
+------------+-------------+-----------------+-----------------------+------------------------+

Se esta etapa extra não for demais para você, você poderá encontrar facilmente o fk que está procurando.


1
fk-[referencing_table]-[referencing_field]

O motivo é a combinação de referencing_tablee referencing_fieldé único em um banco de dados. Desta forma, torna o nome da chave estrangeira fácil de ler, por exemplo:

table `user`:
    id
    name
    role

table `article`:
    id
    content
    created_user_id /* --> user.id */
    reviewed_user_id /* --> user.id */

Portanto, temos duas chaves estrangeiras:

fk-article-created_user_id
fk-article-reviewed_user_id

Adicionar o usernome da tabela ao nome da chave estrangeira é redundante.


E se o nome do banco de dados for user_role? usere roletem relacionamento muitos com muitos e user_roleé a tabela que contém todas as chaves estrangeiras. Deveria ser fk_user_role_role?
Nguyễn Đức Tâm

@ NguyễnĐứcTâm fk-user_role-role
Văn Quyết
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.