Il faut faire la distinction entre les attributs et les entités. Une entité est une chose - généralement un nom. Un attribut ressemble plus à une information descriptive. Dans le jargon des bases de données, entité =table, attribut =champ/colonne.
Avoir une table séparée pour certaines choses, prenons directeur, par exemple, s'appelle normaliser. Bien que cela puisse être bon dans certaines circonstances, cela peut être inutile dans d'autres (car cela rend généralement les requêtes plus compliquées - vous devez tout joindre - et c'est plus lent).
Dans ce cas, avoir une table d'année n'est pas nécessaire, car il n'y a pas d'autres attributs sur une année, à part l'année elle-même, que vous stockeriez. Il est préférable de dénormaliser cela et de stocker l'année dans la table de film elle-même.
Directeur, d'autre part, est différent. Vous souhaiterez peut-être stocker le prénom, le nom, la date de naissance, la date de décès (le cas échéant), etc. du réalisateur. Vous ne souhaitez évidemment pas saisir la date de naissance du réalisateur chaque fois que vous saisissez un film que cette personne dirige, il est donc logique d'avoir une entité distincte pour un directeur.
Même si vous ne vouliez pas stocker toutes ces informations sur le réalisateur (vous voulez juste son nom), avoir une table séparée pour cela (et utiliser une clé de substitution - j'y reviendrai dans une seconde) est utile car il empêche les erreurs typographiques et les doublons - si le nom de quelqu'un est mal orthographié ou saisi différemment (premier, dernier vs dernier, premier), alors si vous essayez de trouver d'autres films qu'il a réalisés, vous échouerez.
L'utilisation d'une clé de substitution (clé primaire) pour les tables est généralement une bonne idée. Faire correspondre un entier est beaucoup plus rapide que faire correspondre une chaîne. Il vous permet également de changer librement le nom, sans vous soucier des clés étrangères stockées dans d'autres tables (l'ID reste le même, vous n'avez donc rien à faire).
Vous pouvez vraiment pousser ce design assez loin, et tout est une question de savoir ce que vous voulez pouvoir y stocker.
Par exemple, plutôt que d'avoir un seul réalisateur par film, certains films ont plusieurs réalisateurs. Il y aurait donc une relation plusieurs à plusieurs entre les films et les réalisateurs, vous auriez donc besoin d'un tableau avec par exemple :
films_directors => **filmid, directorid**
Pour aller plus loin, les réalisateurs sont parfois aussi des acteurs, et vice-versa. Ainsi, plutôt que même d'avoir des tables de réalisateurs et d'acteurs, vous pourriez avoir une seule table de personne et rejoindre cette table en utilisant une table de rôles. La table des rôles contiendrait divers postes - par exemple, réalisateur, producteur, star, extra, grip, éditeur... et ressemblerait davantage à :
films => **filmid**, title, otherstuff...
people => **personid**, name, ....
roles => **roleid**, role name, ....
film_people => **filmid, personid, roleid**
genre => **genreid**, name, ...
film_genre => **genreid, filmid**
Vous pouvez également avoir un champ role_details dans la table film_people, qui peut contenir des informations supplémentaires en fonction du rôle (par exemple, le nom du rôle joué par l'acteur).
Je montre également le genre comme une relation plusieurs<>plusieurs, car il est possible qu'un film appartienne à plusieurs genres. Si vous ne le vouliez pas, alors au lieu de la table film_genre, les films contiendraient simplement un identifiant de genre.
Une fois que cela est configuré, il est facile d'interroger et de trouver tout ce qu'une personne donnée a fait, ou tout ce qu'une personne a fait en tant que réalisateur, ou tous ceux qui ont déjà réalisé un film, ou toutes les personnes impliquées dans un film spécifique. Cela peut continuer encore et encore.