2010-01-01 5 views
1

Ceci est un de ces moments "oh mon dieu".Recherche à partir d'une valeur séparée par des virgules

Le précédent programmeur de notre société a laissé derrière lui une application mal codée utilisant PHP et MySQL. Un exemple est qu'il a stocké des options pour chaque client en tant que valeur séparée par des virgules dans MySQL. L'application entière est NOT basée sur la POO et donc il y a des références et des requêtes répétées dans presque chaque page des 500+ pages de PHP. Il n'est donc pas facile de changer les schémas et les logiques de stockage de données.

Pour ajuster le système pour une période de six mois, je cherche un moyen d'effectuer une recherche sur ces valeurs séparées par des virgules. Est-ce que quelqu'un a eu une idée de la recherche d'un tel CSV sans beaucoup d'impact sur les performances? Je sais que ça ne va pas être le meilleur, mais au moins, je pourrais pousser l'application pendant encore six mois avant que la nouvelle application ne soit prête.

Merci pour toute aide

+2

Le système peut être ou ne pas être mal codé, mais cela est complètement lié à son OOP-ness. Un bon code n'entraîne pas nécessairement de POO, et la POO n'entraîne pas nécessairement un bon code. – cletus

+0

Je suis d'accord avec vous. Mais je ne souligne pas particulièrement l'OOP-ness pour sa mauvaise structure. Bien sûr, j'ai vu beaucoup de bons codes qui étaient structurés avant PHP 5. Mais ce n'est pas le cas dans ce que j'ai en main.Je m'attendrais au moins à des fonctions qui traitent des requêtes de base de données. Et pas un ensemble de requêtes dans chaque point du programme où ils sont nécessaires. – Nirmal

Répondre

2

Qu'en est-il créer une table qui casse correctement la colonne CSV dans plusieurs colonnes (ou plusieurs enregistrements) une fois comme un processus de traitement par lots et bricolant ensuite ensemble un déclencheur de mise à jour sur l'ancienne table actualiser l'entrée (ou les entrées) pour cet utilisateur? Vous pouvez ensuite écrire des requêtes correctes sans avoir à recoder la logique du setter.

+0

C'est une excellente idée! Cela rend même la vie plus facile d'écrire des codes temporaires et de maintenir l'atomicité dans la nouvelle table. – Nirmal

0

est ici une idée pour la manipulation sans changer le schéma ou la représentation:

<?php 
function checkoption ($user, $option) 
{ 
    global $db; 
    $rs = mysql_query ("select option_field_name from customer where user = '$user'", $db); 
    if ($rs) 
    { 
     // enclose result in commas to remove edge cases for next test 
     $opts = ",," . $rs ['option_field_name'] . ","; 
     return strpos ($opts, ",$option,") != false; 
    } 
    return false; 
} 
?> 

Il cherche ,option, dans le domaine de l'utilisateur, et protège contre les cas de pointe en manipulant toutes les références avec une paire supplémentaire de ses environs des virgules. Pour éviter le problème zéro par rapport à Null, une virgule supplémentaire est ajoutée au début de la chaîne db.

0

Donc vous dites que vous voulez une requête qui retourne toutes les lignes où un utilisateur a une option spécifique?

Eh bien, ugh ... D'accord, ce n'est pas jolie, mais vous savez déjà que, si:

select * from user_table 
    where concat(',',option_field,',') like "%,option_you_want,%" 

Je ne peux pas parler à l'impact de la performance - il est probablement pas agréable, mais Je pense que votre autre option consiste à diviser la rangée en une table distincte, mais vous dites que ce n'est pas réalisable pour vous.

4

Vous pouvez utiliser FIND_IN_SET pour récupérer les lignes qui correspondent à vos critères:

SELECT * FROM your_table WHERE FIND_IN_SET('value', field_with_comma_sep_values) > 0; 

Fondamentalement, FIND_IN_SET renvoie l'index de l'élément trouvé. Cette requête trouve donc toutes les lignes où elle trouve le mot correspondant dans le "set" de valeurs séparées par des virgules.

Crédit: Je savais qu'il y avait quelque chose comme ça, mais this post est l'endroit où j'ai trouvé la réponse et l'instruction SELECT.

+0

Merci! J'ai essayé 'WHERE 'val' IN (csv_field)' mais il ne retourne que des enregistrements avec une valeur (ne sais pas pourquoi). FIND_IN_SET fonctionne bien pour moi, et c'est très rapide dans une table avec 20k lignes :) – Peter

1
$a = '123,456,789'; 
$a_array = explode(",",trim($a)); 
if(in_array('456',$a_array)) 
{ 
    echo 'exist'; 
} else echo 'not exist'; 
Questions connexes