Esquema de nomeação de chave estrangeira

152

Estou começando a trabalhar com chaves estrangeiras pela primeira vez e estou imaginando se existe um esquema de nomenclatura padrão a ser usado para elas.

Dadas estas tabelas:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

Onde as Tarefas têm Notas, elas pertencem a Usuários, e os Usuários criam Notas.

Como as três chaves estrangeiras seriam nomeadas nessa situação? Ou, alternativamente, isso importa mesmo ?

Atualização : Esta pergunta é sobre nomes de chaves estrangeiras, não nomes de campos!

nickf
fonte
6
Nota para os leitores: Muitas das práticas recomendadas listadas abaixo não funcionam no Oracle devido ao seu limite de 30 caracteres. Um nome de tabela ou nome de coluna já pode ter perto de 30 caracteres; portanto, uma convenção que combine os dois em um único nome exige um padrão de truncamento ou outros truques.
Charles Burns
Possível duplicado de Naming de colunas ID em tabelas de banco de dados
philipxy

Respostas:

179

A convenção padrão no SQL Server é:

FK_ForeignKeyTable_PrimaryKeyTable

Assim, por exemplo, a chave entre notas e tarefas seria:

FK_note_task

E a chave entre tarefas e usuários seria:

FK_task_user

Isso fornece uma visão rápida de quais tabelas estão envolvidas na chave, facilitando a visualização de quais tabelas uma em particular (a primeira nomeada) depende (a segunda nomeada). Nesse cenário, o conjunto completo de chaves seria:

FK_task_user
FK_note_task
FK_note_user

Assim, você pode ver que as tarefas dependem dos usuários e as notas dependem das tarefas e dos usuários.

Greg Beech
fonte
1
Se a chave estrangeira apontar para uma chave candidata na segunda tabela, em vez de uma chave primária, você provavelmente usaria um terceiro segmento para o nome para qualificar isso. É uma situação incomum, e não aquela em que você normalmente desenharia do zero, por isso não incluí isso na resposta.
Greg Beech
4
Você inclui o nome da tabela atual na chave para mantê-lo distinto. Os nomes de FK estão no espaço de nomes global no SQL Server, portanto você não pode ter dois FKs chamados FK_PrimaryKeyTable anexados a duas tabelas de chaves estrangeiras diferentes. As regras podem ser diferentes para outros servidores de banco de dados.
Greg Beech
Ok ... Eu tenho namespaces diferentes para cada tabela no Oracle, então não preciso da auto-referência.
9788 Steve Moyer
29
Esse parece ser o uso comum, mas o que as pessoas fazem quando há duas chaves estrangeiras apontando para a mesma tabela. ou seja, a messagetabela tem um from_user_ide to_user_idambos se tornariam fk_message_user. Parece-me melhor usar fk_tablename_columnname(fk_message_from_user_id no meu exemplo) por esse motivo e, em seguida, tente manter os nomes das colunas claros sobre a tabela de destino (por exemplo, to_user_id está claramente se referindo à tabela de usuários)
Code Commander
e se a tabela em si tiver sublinhados por ex. user_role e user_addresses? fk_user_addresses_user_role não é confuso?
Govi S
38

Eu uso dois caracteres sublinhados como delimitador ou seja

fk__ForeignKeyTable__PrimaryKeyTable 

Isso ocorre porque os nomes das tabelas ocasionalmente conterão caracteres de sublinhado. Isso segue a convenção de nomenclatura para restrições geralmente porque os nomes dos elementos de dados freqüentemente contêm caracteres sublinhados, por exemplo

CREATE TABLE NaturalPersons (
   ...
   person_death_date DATETIME, 
   person_death_reason VARCHAR(30) 
      CONSTRAINT person_death_reason__not_zero_length
         CHECK (DATALENGTH(person_death_reason) > 0), 
   CONSTRAINT person_death_date__person_death_reason__interaction
      CHECK ((person_death_date IS NULL AND person_death_reason IS NULL)
              OR (person_death_date IS NOT NULL AND person_death_reason IS NOT NULL))
        ...
um dia quando
fonte
3
Esta é absolutamente a melhor resposta.
Frederik Krautwald
1
Acabei de criar o Derby DB com uma convenção de nomenclatura muito específica e essa aqui é a mais legível e rastreável. Obrigado
Anddo
17

Que tal FK_TABLENAME_COLUMNNAME?

K eep I t S exe S tupid sempre que possível.

EvilTeach
fonte
20
Porque quando você tem um banco de dados enorme com muitas chaves e tabelas e recebe um erro durante uma atualização de esquema em seu software, é muito difícil encontrar onde a chave estrangeira é definida mesmo sem fazer uma pesquisa em um script de criação de banco de dados.
JohnC
1
@JohnC Se os nomes das colunas do FK tiverem o outro nome da tabela no nome da coluna, não será fácil saber? Ele mostra as duas tabelas e o nome da coluna em que está definido. Ex:FK_Animals_OwnerID -Animais e mesa de Proprietários, definidos na coluna OwnerID
David Sherret
10

Uma observação da Microsoft sobre o SQL Server:

Uma restrição FOREIGN KEY não precisa ser vinculada apenas a uma restrição PRIMARY KEY em outra tabela; também pode ser definido para referenciar as colunas de uma restrição UNIQUE em outra tabela.

portanto, usarei termos que descrevem dependência em vez dos termos convencionais de relacionamento primário / externo.

Ao fazer referência à PRIMARY KEY da tabela independente (pai) pelas colunas com nomes semelhantes na tabela dependente (filho) , omito o (s) nome (s) da coluna:

FK_ChildTable_ParentTable

Ao fazer referência a outras colunas, ou os nomes das colunas variam entre as duas tabelas, ou apenas para ser explícito:

FK_ChildTable_childColumn_ParentTable_parentColumn
bvj
fonte
9

Normalmente, apenas deixo meu ID nomeado PK e concateno o nome da tabela e o nome da coluna-chave ao nomear FKs em outras tabelas. Eu nunca me importo com o revestimento de camelo, porque alguns bancos de dados descartam a distinção entre maiúsculas e minúsculas e simplesmente retornam todos os nomes em maiúsculas ou minúsculas de qualquer maneira. De qualquer forma, veja como seria minha versão de suas tabelas:

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

Observe que eu também nomeio minhas tabelas no singular, porque uma linha representa um dos objetos que estou persistindo. Muitas dessas convenções são de preferência pessoal. Eu sugiro que é mais importante escolher uma convenção e sempre usá-la, do que adotar a convenção de outra pessoa.

Steve Moyer
fonte
heh - esse é o estilo exato que estou usando (mas com o camelCase) - pensei em adicionar um pouco de descrição extra aos nomes com o objetivo de ilustrar suas ligações.
nickf
Então, pelo menos, podemos ler os esquemas um do outro;) ... o que é embaraçoso é não poder ler o seu depois de alguns anos de ausência. Usamos o ERWin para diagramar nossos esquemas, mas geralmente é conveniente ter uma versão em texto e ter uma convenção, permitindo que você encontre tabelas e campos facilmente.
Steve Moyer
5

Provavelmente isso é exagero, mas funciona para mim. Isso me ajuda bastante quando estou lidando especialmente com VLDBs. Eu uso o seguinte:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Obviamente, se por algum motivo você não estiver fazendo referência a uma chave primária, deverá fazer referência a uma coluna contida em uma restrição exclusiva, neste caso:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

Pode demorar, sim. Isso ajudou a manter as informações claras para os relatórios ou me deu um pulo rápido em que o possível problema ocorre durante um alerta de prod 100% adoraria saber o que as pessoas pensam sobre esta convenção de nomenclatura.

SSISPissesMeOff
fonte
1

Minha abordagem usual é

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

Ou em outros termos

FK_ChildColumnName_ParentTableName_ParentColumnName

Dessa forma eu posso citar duas chaves estrangeiras que fazem referência à mesma mesa como um history_info tablecom column actionBy and actionTode users_infomesa

Será como

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Observe que:

Não incluí o nome da tabela filho porque parece bom senso para mim; estou na mesa da criança para poder assumir facilmente o nome da tabela da criança. O caráter total dele é 26 e se encaixa bem no limite de 30 caracteres do oracle, que foi declarado por Charles Burns em um comentário aqui

Nota para os leitores: Muitas das práticas recomendadas listadas abaixo não funcionam no Oracle devido ao seu limite de 30 caracteres. Um nome de tabela ou nome de coluna já pode ter perto de 30 caracteres, portanto, uma convenção combinando os dois em um único nome requer um padrão de truncamento ou outros truques. - Charles Burns

Cary Bondoc
fonte
O ONE não se você tem 3 tabela têm o ponto FK para ParentTableName_ParentColumnName mesma mesa por duplicado FK_Name
Tony Dong
0

Com base nas respostas e comentários aqui, uma convenção de nomenclatura que inclui a tabela FK, o campo FK e a tabela PK (FK_FKTbl_FKCol_PKTbl) deve evitar colisões de nomes de restrições FK.

Portanto, para as tabelas fornecidas aqui:

fk_task_userid_user
fk_note_userid_user

Portanto, se você adicionar uma coluna para rastrear quem modificou pela última vez uma tarefa ou uma nota ...

fk_task_modifiedby_user
fk_note_modifiedby_user
Chad Kieffer
fonte
-2

Se você não está referenciando seus FKs com tanta frequência e usando o MySQL (e o InnoDB), pode deixar o MySQL nomear o FK para você.

Posteriormente, você poderá encontrar o nome FK necessário executando uma consulta .

user12345
fonte
4
Só posso explicar meu voto negativo. Praticamente todos os sistemas de banco de dados permitem que o sistema nomeie restrições. Você pode imaginar voltar atrás e tentar descobrir rapidamente durante um problema de produção com um banco de dados de 100 tabelas, tentando decifrar a que relação FK__123ee456ff se relaciona? É simples e simplesmente coloca uma prática HORRÍVEL. Quando você cria um índice nesse FK, e daí? nomes de sistema que também? portanto, quando o índice IX_007e373f5963 estiver 98% fragmentado, como você saberá onde procurar para descobrir por quê? Isso simplesmente não deveria ser feito.
SSISPissesMeOff
-3

Tente usar o UUID da versão 4 de caixa alta com o primeiro octeto substituído por FK e '_' (sublinhado) em vez de '-' (traço).

Por exemplo

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

A justificativa é a seguinte

  • Algoritmo de geração estrita => nomes uniformes ;
  • O comprimento da chave tem menos de 30 caracteres , que está nomeando limitação de comprimento no Oracle (antes de 12c);
  • Se o nome da sua entidade mudar, você não precisará renomear seu FK como na abordagem baseada no nome da entidade (se o DB suportar o operador de renomeação de tabelas);
  • Raramente se usaria o nome da restrição de chave estrangeira. Por exemplo, a ferramenta DB geralmente mostra a que a restrição se aplica. Não é preciso ter medo da aparência enigmática, porque você pode evitar usá-la para "descriptografia".
frieza
fonte