8792 sujets

Développement web côté serveur, CMS

Pages :
Bonjour,

Je suis en train de coder un petit systéme pour la gestion de biens immobiliers, le problémes de biens immobiliers, c'est qu'il y a plein de données de type differentes : chambre, piscine, cuisine, wc, salle de bains etc, il y a plus de 50 champs au formulaire.

Naturellement je me suis dit je vais créer des champs a la table immo, ça fait immo_chambre, immo_piscine, etc... mais je suis en train de me demander si ce ne serait pas préférable pour les performances du systéme de regrouper les champs dans un tableau pour limiter le nombre de champs a la table, par exemple immo_specifications, immo_services. Chacun contiendrais un tableau, chambre => '3' ,cuisine => 'equipé' etc... ce qui aurait bien entendu le gros désavantage de rendre la table inutilisable proprement par excel par exemple (ce qui n'est pas dans le projet mais bon...)

La table est moins claire en elle même mais j'ai l'impression que c'est plus rapide, en même temps mon ordi commence à se faire vieux...

La question est en résumé, 50 champs sur une table c'est pas un peu beaucoup ou ça n'a pas d'importance?

Ou autrement dit vaut il mieux un traitement php sur un champs, ou que php cherche dans tout les champs de la table?
Salut,

j'aurais tendance à dire que le nombre de champs est sans importance et que la solution des tableaux, en plus de surcharger le code, te prive de la possibilité d'effectuer des filtres de recherche sur chacun des champs (ce qui semble à priori une option importante sur un site immobilier) du style :
SELECT immo_chambre, immo_piscine, ... FROM `immo` WHERE immo_chambre = 4 AND immo_piscine = 'O'...

Il faut juste penser à ne pas utiliser SELECT * FROM mais préciser les champs à récupérer pour optimiser les requêtes.

A+ Smiley cligne
Modifié par Heyoan (16 Jun 2007 - 02:17)
merci,
Je prefererais aussi que le nombre de table n'est aucune incidence sur les performances parceque comme tu dis c'est quand même bien plus pratique, même si appriorit je ne comptais pas faire des recherches sur le nombre de chambre, mais bon c'est sur que ça peut privée d'évolution possible de commencer avec une base de donnée mal faite.
Dans l'absolu
on ne créé pas non plus une table avec 50 champs
ça devient lourd à gérer

plutot on subdivise par zone
donc en différentes tables reliée entre elles par un indice (index)
l'avantage un system plus souple
l'inconvenient des requetes un peu plus poussées

pour t'aider il existe un prog gratuit qui plus est
http://fabforce.net/dbdesigner4/
alexiase a écrit :
plutot on subdivise par zone
donc en différentes tables reliée entre elles par un indice (index)

Plusieurs tables avec une cardinalité de 1 <--> 1 Smiley scared

Tu veux que Hubert Merise se retourne dans sa tombe Smiley ravi
Je comprend pas trop non plus pourquoi faire plusieurs tables, ça me semble au contraire plus lourd a gérer, parcequ'il faut faire plusieurs boucle au lieu d'une, enfin bon j'ai peu d'expérience en architecture mysql...
Bonjour

On peut faire une seule requête pour accèder à plusieurs tables en même temps, avec la commande SQL, JOIN LEFT, on prends ce que l'on à besoin dans la première table, puis on prend ce que l'on veut dans la deuxième etc etc...

Tout ça, dans une seule requête, par contre, il faut que tes différentes tables aient une relation entre elle (le même index par exemple ou le même nombre de pièce, ou la même référence etc etc ...)

Mais c'est assez lourd à comprendre, et de plus, l'erreur arrive vite (on crée un ligne dans une table, puis on la supprime et on la recrée, l'index aura un saut de chiffre, et donc le join-left ne fonctionnera plus ...

Comme la dis Heyoan, un table peut avoir pratiquement autant de champs que necessaire, par contre il faut bien construire ces requêtes sql pour éviter une surcharge.

Et si tu veux simplifier des champs, tu peux peut être créer un champs qui contiendra en réalité 4, voir 5 variables.

Je m'explique :

Tu concatène le contenu de plusieurs variables :

pour le résumé d'une maison :

Nbre de pièce : 10
Superficie : 500
Nbre de salle d'eau : 4
Prix : 2000000

Si on concatène ça avec un séparateur '_' => 10_500_4_2000000

Tu stocke ça en base de donnée.

Quand tu la récupère tu l'éclate avec explode

list($nbr_pieces, $superficie, $nbr_salle_d_eau, $prix) = explode("_", $result[0]);


Ainsi tu obtiendras 5 variables, à partir d'un champs de ta table.

Enfin, je dis çà, mais c'est peut être plus lourd qu'autre chose, j'essais juste de faire avancer le schmilblick ... Smiley biggol
Merci pour la réponse trés claire.

J'avoue que l'idée de plusieur table ne me plait pas trop... Par contre effectivement la solution de mettre plusieur variable dans un champ dans certain cas me parrait bien, par exemple pour ceux qui ont un lien entre eux:
salon:oui|entree:non|closet:oui|arriere cuisine:non et regouper le tout dans un même champs pieces par exemple. ça évitera d'avoir 4 champs textes avec oui et non... C'est peut-être même plus souple dans le sens ou si un jour j'ai besoin de rajouter panneau solaire:oui ça serat plus facile.

Bien sur comme dit Heyoan il faut éviter de le faire sur les champs sur lesquels ont veut pouvoir boucler directement comme le prix ou la superficie

Par contre je pense qu'il faut travailler ça pour que cela est un sens même en lisant tout le champs. Par exemple en separant par un virgule ou par une barre.
Modifié par matmat (20 Jun 2007 - 18:38)
Salut Smiley cligne ,

pour continuer de jouer avec le schmilblick...

on peut remplacer salon:oui|entree:non|closet:oui|arriere cuisine:non
par salon:1|entree:0|closet:1|arriere cuisine:0 --> ou 1010

Suivant la table de conversion binaire <=> hexadécimal

upload/8634-basehexa.gif

On peut voir qu’il est possible de remplacer 1010 par A.

Il ne reste plus qu’à sauvegarder A dans la table puis à effectuer l’opération inverse pour restituer les données ! Smiley langue

Non ! je déc…… ! Smiley biggol

Tout ça pour dire qu’il est toujours possible de trouver des ruses de sioux mais qu’au final le code risque de devenir vraiment lourd !

Pour reprendre l’exemple que tu prends, le jour où tu veux rajouter un champs panneau solaire, tu vas être obligé de faire un update de ta colonne « fusionnée » pour rajouter « _oui » à toutes les valeurs existantes alors que l’ajout d’une nouvelle colonne aurait pris 30 s.

Et pour finir, il ne faut pas oublier que c’est le boulot de mysql (et de toutes les bases de données) de gérer au mieux les requêtes Smiley lol

A+
Bon, de tout façon pour l'instant mes clients sont pressés donc je vais faire un nouveau champs pour chaque spécifications, et puis je vais voir comment ça tourne...
De toute façon il n'y a aucun probléme pour l'affichage des données, c'est plus au moment de l'insertion que ça réfléchie un peu plus. Ce qui n'est pas un opération qui ce fait toute les cinqs minutes.
Super_Baloo8 a écrit :
Et si tu veux simplifier des champs, tu peux peut être créer un champs qui contiendra en réalité 4, voir 5 variables.


matmat a écrit :
Par contre effectivement la solution de mettre plusieur variable dans un champ dans certain cas me parrait bien, par exemple pour ceux qui ont un lien entre eux:
salon:oui|entree:non|closet:oui|arriere cuisine:non et regouper le tout dans un même champs pieces par exemple.


Yargh ! Jamais, malheureux.

C'est la première règle de la modélisation d'une base de données (dite "première forme normale") : Un attribut d'une relation est atomique. En langage courant cela signifie qu'il faut une et une seule valeur par champ.

D'ailleurs, regrouper plusieurs valeurs dans un champ ne change rien au problème de performances, il y a toujours autant de données à rapatrier. Et rien ne t'oblige à demander tous les champs d'une table lors de ta requête. D'autre part ça va considérablement compliquer ton script et la maintenance ultérieure de ton application. Et le temps que ton script mettra à séparer les données sera à coup sûr supérieur au temps qu'il faudra au moteur de base de données pour le faire. C'est son boulot.

Pour savoir s'il faut plusieurs tables ou non, les autres formes normales sont là pour répondre à la question. Une requête sur une table est souvent plus performante qu'une requête sur plusieurs tables ou plusieurs requêtes.
Modifié par Lanza (21 Jun 2007 - 16:28)
Pour résumer : penser atomicité et unicité. Créer des entités si cardinalités diférrentes de 1.1 (donc 0.n ou 0.1) dans ton cas, une table de 50 champs n'est pas dérangeant ; de tout façon créer ces entités dans ton contexte ne représenteront rien ... Smiley cligne
Modifié par yodaswii (21 Jun 2007 - 16:28)
Pendant qu'on y est avec les performances mysql, est ce que le type de champs est à prendre en compte, par exemple j'ai un champ piscine, pour l'instant c'est juste oui ou non donc ça peut être en bigint ou double pour 1 ou 0, mais je l'ai mis en texte au cas ou cela devient equipée, non-equipée...etc

Est ce moins efficace un champ texte (TEXT) au lieu de bigint ou ça n'a pas d'importance. Chassant que dans ce cas ça ce joue sur 15 à 20 champs ou je me pose la question.
Pas d'importance, dans base de données, il y'a données. Les performances se joueront désormais sur tes scripts pour les exploiter ... Smiley cligne
matmat a écrit :
Pendant qu'on y est avec les performances mysql, est ce que le type de champs est à prendre en compte, par exemple j'ai un champ piscine, pour l'instant c'est juste oui ou non donc ça peut être en bigint ou double pour 1 ou 0, mais je l'ai mis en texte au cas ou cela devient equipée, non-equipée...etc

Est ce moins efficace un champ texte (TEXT) au lieu de bigint ou ça n'a pas d'importance. Chassant que dans ce cas ça ce joue sur 15 à 20 champs ou je me pose la question.


Si c'est un booléen, le bon type est TINYINT(1).

Le type TEXT est un peu énorme (jusqu'à 65536 caractères) pour stocker un entier et surtout il est de taille variable donc oui, mais ce n'est pas la bonne question. La bonne question c'est qu'est-ce que je veux stocker dans ce champ ?

Ne te préoccupes pas de ce que ce sera après. Si ça devient "équipé", "non-équipée" par la suite, il sera toujours temps de s'en préoccuper à ce moment là. Il faudra peut-être agrandir le champ, voire rajouter une table pour les différents types de piscines. Parce que "équipée" et "non équipée" sont des propriétés de piscine et non du bien à proprement parler et donc n'appartiennent pas à la table du bien ("immo" si j'ai bien compris).
Modifié par Lanza (21 Jun 2007 - 16:38)
Il y a pour l'instant une seul table, tout est dans la table immo: prix, chambre, piscine... Il y a au moins 50 champs le pluspart en TEXT...
a écrit :

Yargh ! Jamais, malheureux.
C'est la première règle de la modélisation d'une base de données (dite "première forme normale ") : Un attribut d'une relation est atomique. En langage courant cela signifie qu'il faut une et une seule valeur par champ.

Heu... désolé de ramener un contre exemple, mais que fais-tu si tu dois stocker un array de taille variable dans un champ ?
Si on sait qu'on utilise toujours tous les éléments du tableau quand on en a besoin, pour moi, un type text avec de l'implode/explode fonctionne très bien.
Dans un tel cas pourquoi créer une nouvelle table avec deux champs et s'embêter avec deux requêtes au lieu d'une ? ridicule je trouve.
a écrit :
Heu... désolé de ramener un contre exemple, mais que fais-tu si tu dois stocker un array de taille variable dans un champ ?
Si on sait qu'on utilise toujours tous les éléments du tableau quand on en a besoin, pour moi, un type text avec de l'implode/explode fonctionne très bien.
Dans un tel cas pourquoi créer une nouvelle table avec deux champs et s'embêter avec deux requêtes au lieu d'une ? ridicule je trouve.


Théoriquement, lors de la conception de sa base il faut s'assurer du respect des 3 formes normales. L'analyse joue pour beaucoup dans la qualité de l'application.

Pour reprendre ta phrase, il n'y aura pas deux requêtes mais une requête avec jointure (inner join, left join ou right join selon le besoin). De plus, concernant le tableau de taille variable c'est simple si un attribut dans la modélisation physique (en base quoi) n'est pas renseignable le laisser à null si il peut être renseignable mais pas utile à l'affichage ne pas faire de projection. Smiley cligne

PS : plus la requête est complexe plus le SGBD sera efficace ... arrêtez de le ménager il est là pour ça Smiley cligne
QuentinC a écrit :

Heu... désolé de ramener un contre exemple, mais que fais-tu si tu dois stocker un array de taille variable dans un champ ?
Si on sait qu'on utilise toujours tous les éléments du tableau quand on en a besoin, pour moi, un type text avec de l'implode/explode fonctionne très bien.
Dans un tel cas pourquoi créer une nouvelle table avec deux champs et s'embêter avec deux requêtes au lieu d'une ? ridicule je trouve.


C'est un très mauvais exemple. Smiley lol Ça me fait exactement le même effet que si tu m'avais dit "Pourquoi s'embêter à mettre un <h1> pour un titre alors que ça marche très bien avec un <font>? Ridicule, je trouve." Smiley biggol

La modélisation de base de données est probablement la matière la plus théorisée et formalisée en informatique. Respecter ces quelques règles, même si à priori on ne voit pas pourquoi, peut éviter de s'arracher les cheveux à postériori, le jour où on a besoin de modifier la base, ou l'application.

Je plussoie yodaswii : arrêtez de ménager le moteur de base de données, il est là pour ça.
Pages :