J'ai une base de données MS SQL 2008 qui stocke des données pour créer un graphe pondéré non orienté. Les données sont stockées dans des tables avec la structure suivante:Instruction SQL avec noms de tables dynamiques ou redesign?
[id1] [int] NOT NULL,
[id2] [int] NOT NULL,
[weight] [float] NOT NULL
où [id1] et [ID2] représente les deux noeuds connectés et [poids] le poids de l'arête qui relie ces noeuds.
Il existe plusieurs algorithmes différents qui créent le graphique à partir de certaines données de base. Pour chaque algorithme, je veux stocker les données graphiques dans un tableau séparé. Ces tables ont toutes la même structure (comme montré ci-dessus) et utilisent un préfixe spécifié (similarityALB, similaritybyArticle, similaritybyCategory, ...) pour que je puisse les identifier comme des tables de graphes.
Le programme client peut sélectionner, quelle table (c'est-à-dire par quel algorithme le graphique est créé) à utiliser pour les opérations ultérieures.
L'accès aux données est effectué par des procédures stockées. Comme je l'ai tables différentes, je besoin d'utiliser un tablename variables .: par exemple
SELECT id1, id2, weight FROM @tableName
Cela ne fonctionne pas parce que SQL ne supporte pas les noms de tables variables dans la déclaration. Je l'ai cherché sur le web et toutes les solutions à ce problème utilisez l'instruction dynamique EXEC SQL() par exemple:
EXEC('SELECT id1, id2, weight FROM ' + @tableName)
Comme la plupart d'entre eux ont mentionné, cela fait la déclaration sujette à injection SQL, que je voudrais éviter. Une idée simple de refonte serait de mettre tous les différents graphiques dans un tableau et d'ajouter une colonne pour identifier les différents graphiques.
[graphId] [int] NOT NULL,
[id1] [int] NOT NULL,
[id2] [int] NOT NULL,
[weight] [float] NOT NULL
Mon problème avec cette solution est que les graphiques peuvent être très importantes en fonction de l'algorithme utilisé (jusqu'à 500 millions d'entrées). J'ai besoin d'indexer la table sur (id1, id2) et (id2, id1). Maintenant les mettre tous dans une grande table rendrait la table encore plus lourde (et demande plus lentement). L'ajout d'un nouveau graphique entraînerait de mauvaises performances, à cause des indices actifs. La suppression d'un graphique ne peut pas être fait par TRUNCATE plus, je besoin d'utiliser
DELETE * FROM myTable WHERE [email protected]
qui fonctionne très mal avec de grandes tables et crée un fichier journal très grand (qui dépasse mon espace disque lorsque le graphique est assez grand) . Donc, je voudrais garder les tables indépendantes pour chaque graphique.
Des suggestions comment résoudre ce problème soit trouver un moyen de paramétrer le nom de table ou de re-concevoir la structure de la base de données tout en évitant les problèmes mentionnés ci-dessus?
J'aime la table n Ame vérifier plus, pense que je vais aller de cette façon. J'ai jeté un coup d'oeil aux tables partitionnées - un problème serait que je ne peux pas utiliser truncate pour supprimer des graphes entiers (comme IronGoofy mentionné). De plus, j'examinerai comment utiliser sp_executesql, car il supporte la substitution de paramètres et les plans d'exécution (pour les réutiliser). – Aaginor
Dans Oracle, vous pouvez tronquer une partition unique dans une table partitionnée (ALTER TABLE foo TRUNCATE PARTITION;). Dans SQL-Server, vous devez déplacer les données de la partition dans une nouvelle table, que vous pouvez ensuite supprimer ... bizarre ... –