简体   繁体   English

从逗号分隔值中搜索

[英]Searching from comma separated value

This is one of those 'oh my god' moments. 这是那些“哦,我的天哪”的时刻之一。

The previous programmer in our company has left behind a badly-coded application using PHP and MySQL. 我们公司以前的程序员留下了使用PHP和MySQL编写错误代码的应用程序。

One example is that he has stored options for each customer as a comma separated value in MySQL. 一个示例是他在MySQL中将每个客户的选项存储为逗号分隔的值。 The entire application is NOT OOP based and so there are repeated references and queries in almost every page of the 500+ pages of PHP. 整个应用程序不是基于OOP的,因此PHP的500多个页面中的几乎每个页面都有重复的引用和查询。 So it's not an easy job now to change the schema and data storage logics. 因此,现在更改架构和数据存储逻辑并非易事。

To adjust the system for a matter of six months, I am looking for a way to perform a search on those comma-separates values. 为了将系统调整大约六个月,我正在寻找一种方法来搜索这些逗号分隔的值。 Has someone got any idea about searching such CSV without much performance impact? 有人对搜索这样的CSV有任何想法,但对性能没有太大影响吗? I know it's not going to be the best, but at least I could push the application to go for another six months before the new application is ready. 我知道这不是最好的,但是至少在新应用程序准备就绪之前,我可以将应用程序再推六个月。

Thank you for any help 感谢您的任何帮助

You could use FIND_IN_SET to retrieve rows that match your criteria: 您可以使用FIND_IN_SET检索符合条件的行:

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

Basically, FIND_IN_SET returns the index of the found item. 基本上, FIND_IN_SET返回找到的项目的索引。 So this query finds all rows where it finds the matching word in the "set" of comma separated values. 因此,此查询将找到所有行,并在逗号分隔值的“集合”中找到匹配的单词。

Credit: I knew there was something like this, but this post is where I found the answer and the SELECT statement. 信用:我知道有这样的事情,但是这篇文章是我找到答案和SELECT语句的地方。

What about creating a table that correctly breaks the CSV column into multiple columns (or multiple records) once as a batch process, and then cobbling together an update trigger on the old table to refresh the entry (or entries) for that user? 如何创建一个表,将它作为批处理过程一次正确地将CSV列分为多个列(或多个记录),然后将旧表上的更新触发器组合在一起以刷新该用户的一个(或多个)条目? Then you could write decent queries across it without having to re-code the setter logic. 然后,您可以在整个代码上编写体面的查询,而不必重新编码设置程序逻辑。

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

Here's one idea for handling it without changing the schema or representation: 这是在不更改架构或表示形式的情况下进行处理的一个想法:

<?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;
}
?>

It looks for ,option, in the field for the user, and guards against edge cases by handling all references with an extra pair of surrounding commas. 它在用户的字段中查找,option,并通过使用一对额外的逗号对所有引用进行处理,以防止出现极端情况。 To avoid the zero versus Null problem, an extra comma is added to the front of the db string. 为避免零与空问题,在数据库字符串的前面添加了一个逗号。

So you're saying you want a query that returns all rows where a user has a specific option? 因此,您是说要查询返回用户具有特定选项的所有行?

Well, ugh...okay, this isn't pretty, but you already know that, so: 好吧,嗯...好吧,这并不漂亮,但是您已经知道了,所以:

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

I can't speak to the performance impact--it's likely not pleasant, but I think your other option is to break out the row into a separate table, but you're saying that's not realistically available to you. 我无法谈谈对性能的影响-可能不太令人满意,但是我认为您的另一选择是将行分成单独的表,但是您说的对您实际上不可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM