Oui, je suis conscient que la normalisation des données devrait être ma priorité (telle quelle).
- J'ai une table avec 65 colonnes stockant des données du véhicule avec des colonnes:
used_vehicle
,color
,doors
,mileage
,price
et ainsi de suite, en 65 au total. - Maintenant, je peux diviser cela et avoir une
Vehicle
table,VehicleInterior
,VehicleExterior
,VehicleTechnical
,VehicleExtra
(tous les un à un avec les principauxVehicle
tableau).
Supposons que j'aurai environ 5 millions de lignes (véhicules).
On SELECT
avec une WHERE
clause: les performances seront-elles mieux recherchées (les deux cas indexés au moins surIDs
):
Vehicle
table avec 65 colonnes ouVehicle
table avecJOINS
sur quatre autres tables (toutes avec 5 millions de lignes) pour retourner toutes les données liées àVehicle
?
(Selon le moteur de base de données, pensez à PostgreSQL et / ou MySQL).
Vous appréciez vraiment les informations détaillées que vous pourriez avoir de votre expérience précédente?
VehicleInterior
, d' autres requêtes qui traitent avec des colonnes de seulementVehicleTechnical
, etc. Ou s'il y a beaucoup de lignes / véhicules qui ne sont absolument pas d' info au sujet (par exemple)VehicleExtra
si au lieu de plusieurs lignes avec beaucoup de valeurs nulles dans la même table, vous avez des lignes dans le reste des tables et aucune ligne dansVehicleExtra
Réponses:
En supposant que nous parlons de relations 1: 1 entre toutes les tables.
Le stockage global est pratiquement toujours (substantiellement) moins cher avec une seule table au lieu de plusieurs tables dans une relation 1: 1. Chaque ligne a 28 octets de surcharge, plus généralement quelques octets supplémentaires pour un remplissage supplémentaire. Et vous devez stocker la colonne PK avec chaque table. Et avoir un index séparé (redondant) sur chacune de ces colonnes ... La taille est importante pour les performances.
Cela est même vrai si de nombreuses colonnes sont NULL dans la plupart des lignes car le stockage NULL est très bon marché :
Lors de la récupération de toutes les colonnes, une seule table est sensiblement plus rapide que 5 tables réunies. C'est aussi beaucoup plus simple . Cinq tables peuvent être difficiles à joindre si toutes les lignes ne sont pas présentes dans toutes les tables. Avec des
WHERE
conditions ciblant une seule table, il est assez facile d'ajouter d'autres tables avecLEFT JOIN
. Pas aussi banal si vous avez des prédicats sur plusieurs tables ...Le partitionnement vertical peut encore améliorer les performances de certaines requêtes. Par exemple, si 90% de vos requêtes récupèrent les mêmes 5 colonnes sur les 65 disponibles, ce serait plus rapide avec une table contenant uniquement ces 5 colonnes.
OTOH, vous pourriez être en mesure de répondre à de telles requêtes sur quelques colonnes sélectionnées avec un index «couvrant» permettant des analyses d'index uniquement .
Un autre candidat pour le partitionnement vertical: si vous avez beaucoup de mises à jour sur seulement quelques colonnes, alors que le reste ne change presque jamais. Dans un tel cas, il pourrait être considérablement moins coûteux de diviser des lignes, car Postgres écrit une nouvelle version de ligne pour chaque mise à jour. Il existe des exceptions pour les grandes valeurs stockées hors ligne ("TOASTed"). Plus de détails:
Cela dépend vraiment de la situation complète. En cas de doute, optez pour la solution simple d'avoir une seule table, surtout si elle représente bien la réalité: dans votre exemple, ce sont tous des attributs d'une voiture et ont du sens ensemble.
la source
Une sélection sur une seule table devrait toujours être plus rapide. Dès que vous avez trouvé votre véhicule, vous avez déjà tous les détails.
Cependant, vous perdez l'efficacité de la normalisation. Par exemple, si 1 voiture avait de nombreux modèles avec différentes options.
Est-ce un db de référence de toutes les voitures? Ou une liste de véhicules d'occasion? Y aurait-il de nombreux exemples de la même marque / modèle avec les mêmes options?
Edit: je devrais qualifier ma réponse comme étant des rdbms génériques plutôt que des postgres spécifiques. Je m'en remets à la réponse détaillée de @ Erwin spécifique aux postgres
la source