11-02-2010, 05:42 PM
La première forme proposé, avec des colonnes bâtiment1, bâtiment2, etc. est à proscrire. Ce serait envisageable s'il s'agissait de deux ou trois bâtiments, mais là c'est clairement une relation 1, n qu'il convient de traiter comme telle, avec une table de liaison. C'est une question de modélisation.
Avec ta solution, tu es amené à changer ton schéma régulièrement. Autant adopter l'approche souple et économique de la relation 1, n.
Et une modélisation de relation 1, n, ça passe par une table par ressource (en l'occurrence tes villes et tes modèles de bâtiments) et une table de liaison qui contient des paires (city_id; building_model_id) d'id pour chaque bâtiment dans la ville. Ainsi, chaque ligne dans cette table de relation représente une instance.
Autre avantage capital de la modélisation 1, n : les associations riches. Exemple :
Image que tu développes un jeu comme Pokémon. Avec ta méthode, les 6 Pokémons actifs de l'équipe d'un joueur sont directement inscrits dans la ligne du joueur via des colonnes pokemon_1, pokemon_2, etc.)
Si dans la table des Pokémons disponibles (pokemon_models) on a Salamèche (d'id 7) et que les joueurs A et B ont un Salamèche dans leur équipe ? Ils auront tous les deux le nombre 7 dans une des colonnes pokemon_n. Le problème ? Tu ne peux pas différencier les Pokémons du joueur A de celui du joueur B, leur niveau de PV, etc. A moins de faire une table supplémentaire qui contient toutes les instances de Pokémons (avec une colonne pokemon_model_id, par exemple), ce qui au final revient à faire du 1, n.
Alors qu'avec une modélisation 1, n, tu as directement une table pokemons qui contient des lignes avec des colonnes player_id, pokemon_type_id, nickname, health, etc. Chaque ligne de cette table modélisant une instance de Pokémon (d'où le nommage de la table).
Voilà donc pourquoi il est préférable de faire du 1, n : pouvoir faire des associations riches. Et quand bien même tu n'aurais besoin que d'associations simples, ta table de liaison ne contiendra qu'une paire d'id : pas de champs "custom". Dans ce cas d'associations simples, un bon nommage de la table est players_pokemon_models : le nom de chaque tables (des pluriels) dans un ordre précis (alphabétique, en l'occurrence) concaténé par des underscores. Ce genre de convention est capital quand on utilise un ORM, car la classe associée prendra généralement le nom de la table mis au singulier (Player, PokemonModel).
Et concernant le stockage des coûts en dur, c'est horrible. Si on suit le raisonnement, il y a beaucoup de choses qu'on peut stocker en dur dans des variables... Et pourtant, la base de données est faîte pour ça... Séparer les sources de données (ah ça c'est en DB, ça c'est en fichier, ça c'est donné par un web service, etc.), c'est mélanger les torchons et les serviettes : c'est mal et dangereux.
J'espère avoir été convaincant.
Sephi-Chan
Avec ta solution, tu es amené à changer ton schéma régulièrement. Autant adopter l'approche souple et économique de la relation 1, n.
Et une modélisation de relation 1, n, ça passe par une table par ressource (en l'occurrence tes villes et tes modèles de bâtiments) et une table de liaison qui contient des paires (city_id; building_model_id) d'id pour chaque bâtiment dans la ville. Ainsi, chaque ligne dans cette table de relation représente une instance.
Autre avantage capital de la modélisation 1, n : les associations riches. Exemple :
Image que tu développes un jeu comme Pokémon. Avec ta méthode, les 6 Pokémons actifs de l'équipe d'un joueur sont directement inscrits dans la ligne du joueur via des colonnes pokemon_1, pokemon_2, etc.)
Si dans la table des Pokémons disponibles (pokemon_models) on a Salamèche (d'id 7) et que les joueurs A et B ont un Salamèche dans leur équipe ? Ils auront tous les deux le nombre 7 dans une des colonnes pokemon_n. Le problème ? Tu ne peux pas différencier les Pokémons du joueur A de celui du joueur B, leur niveau de PV, etc. A moins de faire une table supplémentaire qui contient toutes les instances de Pokémons (avec une colonne pokemon_model_id, par exemple), ce qui au final revient à faire du 1, n.
Alors qu'avec une modélisation 1, n, tu as directement une table pokemons qui contient des lignes avec des colonnes player_id, pokemon_type_id, nickname, health, etc. Chaque ligne de cette table modélisant une instance de Pokémon (d'où le nommage de la table).
Voilà donc pourquoi il est préférable de faire du 1, n : pouvoir faire des associations riches. Et quand bien même tu n'aurais besoin que d'associations simples, ta table de liaison ne contiendra qu'une paire d'id : pas de champs "custom". Dans ce cas d'associations simples, un bon nommage de la table est players_pokemon_models : le nom de chaque tables (des pluriels) dans un ordre précis (alphabétique, en l'occurrence) concaténé par des underscores. Ce genre de convention est capital quand on utilise un ORM, car la classe associée prendra généralement le nom de la table mis au singulier (Player, PokemonModel).
Et concernant le stockage des coûts en dur, c'est horrible. Si on suit le raisonnement, il y a beaucoup de choses qu'on peut stocker en dur dans des variables... Et pourtant, la base de données est faîte pour ça... Séparer les sources de données (ah ça c'est en DB, ça c'est en fichier, ça c'est donné par un web service, etc.), c'est mélanger les torchons et les serviettes : c'est mal et dangereux.
J'espère avoir été convaincant.
Sephi-Chan