Pergunta

Cenário

Eu tenho 3 tabelas de banco de dados. Um é para imagens e os outros dois são People & Places. Uma vez que cada pessoa pode ter muitas imagens e cada lugar pode ter muitas imagens, eu quero ter um a relação muitos entre as pessoas e imagens, bem como lugares e imagens.

Pergunta

Será que a chave estrangeira tem que ser chamado o mesmo nome que a chave primária? Ou é possível para mim para chamar a chave estrangeira na tabela imagens algo genérico, por exemplo "PKTableID". Desta forma, eu só preciso de uma mesa de imagem.

Ajuda muito apreciada.

Saudações,

EDIT:

A razão para querer ter apenas uma única tabela de imagem, é porque cada imagem refere-se apenas a uma única outra tabela. Assim como esta, eu usei o exemplo aqui de duas tabelas, o fato de banco de dados Eu vou estar usando terá 20 mesas, então eu queria saber se ainda era possível usar uma tabela única imagem para 20 ONE-TO-muitos relacionamentos ?

Foi útil?

Solução

Editar

Se uma imagem só é possuído nunca por um dos vinte mesas, este trabalho de design força:

People (PersonId, Name)
Places (PlaceId, Name)
Dogs (DogId, Breed)
Doors (DoorId, Height, Width)
Images (ImageId, ImageBinary, OwnerId, OwnerTable)

Onde OwnerTable é o nome ou o código para a tabela que OwnerId pertence.

Isto poupar-lhe 20 FKs na tabela de imagem, ou 20 tabelas de associação. Então, na junta, você deve especificar OwnerTable, dependendo da tabela que você estão se juntando a.

Você precisaria usar tipos convertível para as identificações (por exemplo, tinyint, smallint e INT), e de preferência um tipo para todos (por exemplo, INT), e você tem que gerir a integridade referencial-se embora gatilhos ou algum outro código.

/ EDIT

Você precisa 5 mesas, não 3:

People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary)
ImagesPeople (ImageId, PersonId)
ImagesPlaces (ImageId, PlaceId)

Você pode chamar os campos que você quiser. People.Id, ImagesPeople.PersonId, etc.

Mas o que você não pode fazer é algo como isto:

People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary, PlaceOrPersonId)

Bem, você pode, mas o banco de dados não vai ajudá-lo a reforçar a relação, ou dizer-lhe qual a tabela de FK pertence. Como você saberia? Há hackish soluções alternativas como o escalonamento das incrementos id, adicionando uma coluna tipo de imagens ou usando GUIDs.

Como alternativa:

Things (ThingId PK, Type)
People (ThingId PK/FK, Name, Age)
Places (ThingId PK/FK, Name, LatLon)
Images (ImageId PK, ImageBinary, ThingId FK)

Você também pode fazer Imagens de uma "coisa". Às vezes você vê projetos como este. Ele lhe dá a integridade referencial, mas não o tipo de exclusividade. Você poderia ter o mesmo ThingId em pessoas, lugares e imagens e o banco de dados não se importaria. Você teria que código que governar a si mesmo.

Edit: por sugestão de Cylon Cat, o cenário 4:

People (PersonId, Name)
Places (PlaceId, Name)
PeopleImages (PeopleImageId, ImageBinary)
PlaceImages (PlaceImageId, ImageBinary)

Aqui, as imagens são exclusivamente propriedade de uma pessoa ou lugar. Semelhante à versão 2, mas com chaves estrangeiras declarados. Ele pode ter alguns benefícios de desempenho contra o design 5 da tabela, já que menos se junta são necessários. Você perde "Imagem" como uma entidade distinta, substituída por "PeopleImage" e "PlaceImage".

Outras dicas

Como Peter apontou que você realmente precisa de um relacionamento muitos para muitos, a menos que você quiser restringir suas imagens para fotos com apenas uma pessoa, também, um índice bom lugar irá refletir a natureza hierárquica de nomes de lugares (Montmartre, Paris, França = três possíveis nomes para um lugar).

Agora, tecnicamente você pode chamar seus índices e tabelas qualquer coisa que não é uma palavra reservada e não foi já utilizado, X, Y, Z12345 e TRÉMULO são todos nomes válidos para um índice.

Na prática, no entanto o seu melhor para seguir uma convenção de nomeação que aponta para o que está sendo armazenado e para quê. Então tabelas PEOPLE_X_IMAGES e um PLACES_X_IMAGES seria uma boa ideia no seu caso. Você realmente não precisa de nada sobre pessoas ou lugares na tabela imagens reais. Da mesma forma que você não precisa de nada sobre as imagens das pessoas e lugares tabelas.

Você pode adicionar teoricamente adicionar duas chaves estrangeiras na tabela de imagens, uma para as pessoas e um para Places. Então você poderia permitir nulos e junte-se nas colunas apropriadas ao executar uma consulta. Isso não é muito de uma solução, porque embora o que faz este olhar tabela como quando você tem 14 mesas que precisam juntar-se com ele?

Se você não está indo para GUIDs de uso, então eu digo que você configurá-lo como muitos-para-muitos, para o bem do próximo cara que tem de compreendê-lo.

Você pode usar uma mesa, mas você precisaria de vinte campos diferentes para os relacionamentos. Se você configurar uma relação de chave estrangeira, então todos os dados devem estar relacionados com a tabela pai, você não pode armazenar duas relações de chave estrangeira em uma tabela. Portanto, você deve configurar uma coluna para cada fk você quer ter.

Como cerca

Person (PersonId PK, Name, ImageId FK)
Image (ImageId PK, Name)
Place (PlaceId PK, Name, ImageId FK)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top