Optimisation des requêtes SQL pour les tables avec des valeurs de colonnes séparées par des virgules
Lorsque vous traitez des tables où une colonne contient des valeurs séparées par des virgules, exécutez des les requêtes peuvent être difficiles. Un scénario courant consiste à récupérer toutes les données associées lors de la recherche de valeurs spécifiques dans la colonne séparée par des virgules.
Problème :
Vous devez récupérer tous les noms d'utilisateur associés à un élément particulier. valeur dans une colonne séparée par des virgules. Par exemple, à partir de la structure des tableaux ci-dessous, vous souhaitez trouver tous les noms d'utilisateur lorsque vous recherchez "new1".
Tables :
CREATE TABLE tblA ( id int NOT NULL AUTO_INCREMENT , user varchar(255), category int(255), PRIMARY KEY (id) ); CREATE TABLE tblB ( id int NOT NULL AUTO_INCREMENT , username varchar(255), userid int(255), PRIMARY KEY (id) ); CREATE TABLE tblC ( id int NOT NULL AUTO_INCREMENT , nname varchar(255), userids varchar(255), PRIMARY KEY (id) ); INSERT INTO tblA (user, category ) VALUES ('1', '1'), ('1', '2'), ('1', '3'), ('1', '1'), ('2', '1'), ('2', '1'), ('2', '1'), ('2', '1'), ('3', '1'), ('2', '1'), ('4', '1'), ('4', '1'), ('2', '1'); INSERT INTO tblB (userid, username ) VALUES ('1', 'A'), ('2', 'B'), ('3', 'C'), ('4', 'D'), ('5', 'E'); INSERT INTO tblC (id, nname,userids ) VALUES ('1', 'new1','1,2'), ('2', 'new2','1,3'), ('3', 'new3','1,4'), ('4', 'new4','3,2'), ('5', 'new5','5,2');
Requête :
select * where nname="new1" from tblC CROSS JOIN tblB ON tblB.userid=(SELECT userids FROM substr(tblC.userids,','))
Limitations :
Cette requête s'appuie sur SUBSTR et les fonctions FIND_IN_SET, qui peuvent être inefficaces pour les grands ensembles de données. De plus, il ne suppose qu'une seule valeur séparée par des virgules par ligne, ce qui n'est pas toujours le cas.
Solution recommandée :
Normalisation de la base de données :
Normalisez votre schéma de base de données en créant une table distincte pour les valeurs séparées par des virgules. Cela élimine l'inefficacité de la recherche dans les chaînes et simplifie les requêtes.
Exemple de schéma :
CREATE TABLE tblC ( id int NOT NULL AUTO_INCREMENT , nname varchar(255), PRIMARY KEY (id) ); CREATE TABLE tblC_user ( c_id int NOT NULL, userid int NOT NULL ); INSERT INTO tblC (id, nname) VALUES ('1', 'new1'), ('2', 'new2'), ('3', 'new3'), ('4', 'new4'), ('5', 'new5'); INSERT INTO tblC_user (c_id, userid) VALUES ('1','1'), ('1','2'), ('2','1'), ('2','3'), ('3','1'), ('3','4'), ('4','3'), ('4','2'), ('5','5'), ('5','2');
Optimisé Requête :
select * from tblC c join tblC_user cu on(c.id = cu.c_id) join tblB b on (b.userid = cu.userid) where c.nname="new1"
Avantages :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!