Pergunta

Eu estou tentando obter minha cabeça em volta desta incompreensível coisas que eles chamam de banco de dados design sem muito sucesso, por isso vou tentar ilustrar o meu problema com um exemplo.

Eu estou usando MySQL e aqui está a minha pergunta:

Digamos que eu queira criar um banco de dados para armazenar minha coleção de DVD. Eu tenho a seguinte informação que eu quero incluir:

  1. Título de filme
  2. Atores
  3. Tempo corrente
  4. Gênero
  5. Descrição
  6. Ano
  7. Director

Eu gostaria de criar relações entre estes para torná-lo mais eficiente, mas não sei como.

Aqui está o que eu estou pensando para o projeto de banco de dados:

tabela filmes => filmId, filmtitle, runningtime, Descrição

Tabela Ano => ano

Gênero Table => gênero

Director Tabela => diretor

Atores Tabela => actor_name

Mas, como eu iria sobre a criação de relações entre essas tabelas?

Além disso, eu criei uma identificação única para a Mesa Films com uma chave primária que automaticamente incrementos, que eu preciso para criar uma identificação única para cada tabela?

E, finalmente, se eu fosse para atualizar um novo filme no banco de dados através de um formulário PHP, como eu inserir todos esses dados em (com os relacionamentos e todos?)

Obrigado por qualquer ajuda que você pode dar, Keith

Foi útil?

Solução

Você tem que fazer uma distinção entre atributos e entidades. Uma entidade é uma coisa - geralmente um substantivo. Um atributo é mais como um pedaço de descrever informações. No jargão de banco de dados, entidade = mesa, atributo = campo / coluna.

Tendo uma tabela separada para certas coisas, diretor uso do let, como um exemplo, é chamado de normalização. Embora possa ser bom em algumas circunstâncias, pode ser desnecessária em outros (como geralmente faz consultas mais complicadas - você tem que juntar tudo - e é mais lento).

Neste caso, ter uma tabela de ano é desnecessário, já que não há outros atributos cerca de um ano, além do próprio ano, que você iria armazenar. É melhor desnormalizar isso e armazenar o ano em própria tabela de filme.

Diretor, por outro lado, é diferente. Talvez você deseja armazenar o primeiro nome do diretor, último nome, data de nascimento, data da morte (se aplicável), etc. Você, obviamente, não quer entrar data de nascimento do diretor cada vez que você entra em um filme que esta pessoa dirige, por isso faz sentido ter uma entidade separada para um diretor.

Mesmo se você não quiser armazenar todas essas informações sobre o diretor (você só quer o seu nome), ter uma tabela separada para ele (e usando uma chave substituta - Eu vou chegar a isso em um segundo) é útil, pois evita erros tipográficos e duplicatas - se você tem o nome escrito errado de alguém ou entrou de forma diferente (primeiro, último vs passado, em primeiro lugar), então se você tentar encontrar outros filmes que eles dirigidas, você vai falhar.

Usando uma chave substituta (chave primária) para tabelas é geralmente uma boa idéia. Combinando um inteiro é muito mais rápido do que combinando uma corda. Ele também permite alterar livremente o nome, sem se preocupar com as chaves estrangeiras armazenadas em outras tabelas (as estadias de identificação do mesmo, para que você não precisa fazer nada).


Você pode realmente ter este projeto muito longe, e é tudo uma questão de descobrir o que você quer ser capaz de armazenar nele.

Por exemplo, ao invés de ter um diretor único por filme, alguns filmes têm vários diretores .. então não haveria um relacionamento muitos-para-muitos entre filmes e diretores, assim que você precisa de uma tabela com, por exemplo:

films_directors => **filmid, directorid**

Tendo-se um passo adicional, por vezes, são também agentes directores, e vice-versa. Então ao invés de até têm mesas diretor e ator, você poderia ter uma tabela única pessoa, e junte-se que a tabela em usar uma mesa papel. A tabela papel iria realizar várias posições - por exemplo, diretor, produtor, estrela, extra, aderência, editor .. e ele ficaria mais parecido com:

films => **filmid**, title, otherstuff...
people => **personid**, name, ....
roles => **roleid**, role name, ....
film_people => **filmid, personid, roleid**
genre => **genreid**, name, ...
film_genre => **genreid, filmid**

Você também pode ter um campo role_details na tabela de film_people, que poderia conter informação extra dependendo da função (por exemplo, o nome da peça, o ator está jogando).

Eu também estou mostrando gênero como muitos relação muitos <>, porque o filme uma possível está em vários gêneros. Se você não quer isso, então em vez de mesa de film_genre, filmes só iria conter uma genreid.

Uma vez que este está configurado, é fácil consulta e encontrar tudo o que uma determinada pessoa tenha feito, ou tudo o que uma pessoa fez como diretor, ou todos que já dirigiu um filme, ou todas as pessoas envolvidas com um específico filme .. pode continuar e continuar.

Outras dicas

O que se segue não é código MySQL real. Parece que o que você precisa é de mais de um início conceitual aqui. Então aqui está um modelo do que seu banco de dados deve ser parecida.

mesa Ator

  • id (chave primária)
  • Nome
  • último nome
  • etc. (Quaisquer colunas adicionais que deseja armazenar em um ator)

Director tabela

  • id
  • Nome
  • último nome
  • etc.

Gênero tabela

  • id
  • nome
  • etc.

mesa Film

  • id
  • título
  • description
  • tempo de execução
  • data de lançamento
  • id diretor - esta é uma chave estrangeira que se refere ao id (chave primária) do diretor que dirigiu o filme
  • id gênero - como o ID de diretor, este refere-se à ID do gênero do filme pertence

tabela de índice Ator de filme

  • id filme - esta é uma chave estrangeira que se refere ao id do filme
  • id ator -. Esta é uma chave estrangeira que se refere ao id de um actor no filme

Para cada ator no filme, você iria adicionar uma linha com o Índice Ator-Film. Então, se os atores 5 e 13 (as chaves primárias para os atores) estrelou o filme 4 (novamente, a chave primária para que o filme), você teria duas linhas que refletem esse facto no seu índice: Um com filme id = 4, e id ator = 5, e outra com a película id = 4, e id actor = 13.

Espero que ajude.

Além disso, isso pressupõe que cada filme tem exatamente um diretor. Se qualquer filme em sua biblioteca tem dois diretores (como Slumdog Millionaire), você iria querer separar o id diretor da tabela do filme, e criar um índice de Director-Film como o Índice de Ator-Film como acima.

Estas são as tabelas que eu usaria:

films (_id_, title, runningtime, description)
genres (_id_, name)
people (_id_, name, birthdate, etc...)
roles (_roleid_, rolename)
filmgenres (_filmid_, _genreid_)
castandcrew (_filmid_, _roleid_, _personid_)

Em vez de ter uma mesa de diretores e atores, só tem uma mesa de pessoas. Isso também pode incluir membros da tripulação (no caso de você querer controlar quem foi o 2º aperto Júnior Assistente Dolly). Cada filme pode ser qualquer número de gêneros (comédia e horror, por exemplo). Além disso, as pessoas podem tomar qualquer número de papéis em cada filme -. Há um grande número de atores / diretores lá fora

A tabela Roles não significa necessariamente que o personagem que o ator está jogando, mas poderia. Poderia ser "Diretor", "Produtor", "Ator" ... ou mesmo "Luke Skywalker" se você queria ter que finamente granulado ... Eu acredito IMDB faz isso.

Esperamos que os nomes dos campos acima deve sugerir as chaves estrangeiras, e eu coloquei _underscores_ em torno das chaves primárias que eu usaria.

A sua mesa Films também precisa de links para o gênero, diretor e atores tabelas. Uma vez que os atores, pelo menos vai ser muitos para muitos (um filme irá listar mais de um ator, um ator vai estar em mais de um filme), você vai precisar de uma tabela para ligá-los.

Films Table => filmid, filmtitle, runningtime, description, genreid, directorid
Genre Table => genreid, genre
Director Table => directorid, director
Actors Table => actorid,actor_name
FilmActor link table => actorid, filmid (with a record linking each actor to each film)

Qualquer tabela que pode ser muitos para muitos necessidades uma tabela de ligação.

Eu criei uma identificação única para a Mesa Films com uma chave primária que automaticamente incrementos, que eu preciso para criar uma identificação única para cada tabela?

Sim, cada tabela deve tem uma identificação única. Mas, isso não é necessariamente o auto chave primária incrementando - é o que faz que determinada instância única. Por exemplo, para filmes, eu acho que é comum a ser título + ano de lançamento - embora você gostaria de verificar com um cinéfilo (a especialista de domínio) para ter certeza disso. O incremento auto é um fallback -. Basicamente, quando você realmente não tem mais nada para uniqueify on

Você pode usar uma chave auto incremento para facilidade de uso em junta e tal, mas você deve ter uma restrição exclusiva sobre os campos singularidade de qualquer maneira.

Como para o projeto real, eu sugiro algo como:

Films => Primary Key(filmid), Unique Constraint(filmtitle, year), 
         runningtime, description, 
         Foreign Key(Genre), Foreign Key(DirectorId)

Genre Table => Primary Key(Genre)

Director Table => Primary Key(DirectorId), DirectorName

Actors Table => Primary Key(ActorId), ActorName

Films_Actors => Primary Key(Foreign Key(ActorId), Foreign Key(FilmId))

Para a inserção, bem - francamente, é uma PITA. Você precisa inserir na ordem inversa (e este é o lugar onde as chaves auto incremento pode ser um PITA ainda maior - se você pode adicionar a data de nascimento ou algo na tabela de atores e diretores, em seguida, uma restrição exclusiva pode torná-lo mais fácil).

Então, você iria inserir Ator (s), Diretor, Filme, e depois Films_Actors. Idealmente, tudo em uma única transação. Além disso, eu assumo Gênero já está preenchido, e é uma lista de seleção - por isso não precisa ser inserido

.

Você pode baixar esquema Imdb aqui .

Eu percebo a sua pergunta já foi respondida, porém eu queria apontar-lhe:
http://www.imdb.com/interfaces

IMDB fornece arquivos de texto plano de seu banco de dados (menos chaves primárias). Você pode encontrar este útil para preencher o banco de dados uma vez que você começar, ou você pode usá-lo em seu programa / website para permitir que você simplesmente procurar um título filmes para adicionar à sua "Coleção DVD", e ter o resto da informação puxada a partir destes.

Às vezes, os atores são diretores e vice-versa, talvez você quer uma tabela "pessoas"?

Você não realmente precisa de um YearTable, e tudo que você precisa é de um genre_id, director_id e colunas actor_id em sua tabela filmes.

Além disso, seu gênero, diretor e mesas ator precisam de seus próprios IDs únicos.

Editar: Isto é, claro, supondo que você só vai ter um gênero, diretor, e ator para cada filme. Que provavelmente não é o caso.

Para ter muitos atores pertencentes a muitos filmes, você vai precisar de uma mesa relações separado. Você poderia chamá-lo de "moviesActors" (ou actorsMovies) e cada linha terá um actor_id e uma movie_id dizer esse ator estava em este filme .

Cada tabela deve ter uma chave primária que é único.

Você deve ler em normalização de dados .

A tabela de ano é provavelmente desnecessário.

Se é ano de lançamento, digamos, em seguida, o ano pode ser armazenado no filme.

Se houver vários directores de um filme, então você teria uma tabela separada que detêm a chave primária da tabela de cinema e mesa o diretor. Da mesma forma para qualquer uma das restrições de chave estrangeira que são muitos-para-um ou muitos-para-muitos. Em particular, eu acredito que isso se aplica ao ator.

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