Php 序列化数组中的mysql select查询
我在数据库的一个字段中以序列化数组存储一个项目列表(我使用的是PHP/MySQL) 我想要一个查询,它将选择数组中包含这些项中特定项的所有记录 大概是这样的:Php 序列化数组中的mysql select查询,php,mysql,arrays,Php,Mysql,Arrays,我在数据库的一个字段中以序列化数组存储一个项目列表(我使用的是PHP/MySQL) 我想要一个查询,它将选择数组中包含这些项中特定项的所有记录 大概是这样的: select * from table WHERE (an item in my array) = '$n' SELECT * FROM table_name WHERE some_field REGEXP '.*"item_key";s:[0-9]+:"item_value".*' 希望这是有道理的 任何想法都将不胜感激 谢谢正如G
select * from table WHERE (an item in my array) = '$n'
SELECT * FROM table_name WHERE some_field REGEXP '.*"item_key";s:[0-9]+:"item_value".*'
希望这是有道理的
任何想法都将不胜感激
谢谢正如GWW在评论中所说的,如果您需要以这种方式查询数据,您确实应该考虑将这些数据存储为大ole字符串以外的内容(这就是序列化数组) 如果这是不可能的(或者您只是懒惰),您可以使用序列化数组只是一个大ole字符串的事实,并找出一个LIKE子句来查找匹配的记录。PHP序列化数据的方式非常容易理解(提示:这些数字表示事物的长度) 现在,如果您的序列化数组相当复杂,那么它将很快崩溃。但如果它是平面阵列,您应该能够做到这一点 当然,您将使用“%”之类的标记,因此您将无法从任何标记中获得帮助,并且性能将非常差
这就是为什么人们建议您以某种规范化的方式存储数据,如果您需要在其中查询。您可能正在寻找SQL in语句 不过,您必须先稍微分解一下阵列。你不能仅仅把一个数组交给MySQL,然后期望它知道如何处理它。为此,您可以尝试使用PHP的explode将其序列化
那么您的意思是使用MySQL在已使用命令序列化并存储在数据库字段中的PHP数组中进行搜索?我的第一反应是:天哪。我的第二个反应是:为什么?明智的做法是:
当然,如果你真的想,你可以尝试使用
子字符串或另一个MySQL函数来操作这个字段,但我不明白你为什么要这么做。它很笨重,而且是一个不必要的丑陋的黑客。另一方面,这是一个谜题,这里的人往往喜欢谜题,所以如果你真的想发布你领域的内容,我们可以试一试 将要搜索的值序列化怎么样
$sql = sprintf("select * from tbl WHERE serialized_col like '%%%s%%'", serialize($n));
或
您可以这样做:
select * from table WHERE (an item in my array) = '$n'
SELECT * FROM table_name WHERE some_field REGEXP '.*"item_key";s:[0-9]+:"item_value".*'
但是无论如何,你应该考虑将数据存储在一个单独的表中。
< P>如果你对数据模型有控制,在数据库中填充序列化的数据将从长远角度对你产生影响。然而,人们通常无法控制数据模型,例如在使用某些开源内容管理系统时。Drupal将大量序列化数据粘贴在转储程序列中,以代替适当的模型。例如,ubercart的所有订单都有一个“数据”列。贡献的模块需要将数据附加到主订单实体,因此为了方便起见,它们将数据附加到序列化的blob上。作为这方面的第三方,我仍然需要一种方法来获取其中的一些数据,以回答一些问题
a:4:{s:7:"cc_data";s:112:"6"CrIPY2IsMS1?blpMkwRj[XwCosb]gl<Dw_L(,Tq[xE)~(!$C"9Wn]bKYlAnS{[Kv[&Cq$xN-Jkr1qq<z](td]ve+{Xi!G0x:.O-"=yy*2KP0@z";s:7:"cc_txns";a:1:{s:10:"references";a:1:{i:0;a:2:{s:4:"card";s:4:"3092";s:7:"created";i:1296325512;}}}s:13:"recurring_fee";b:1;s:12:"old_order_id";s:2:"25";}
最里面的子字符串索引给出了所有超过旧的顺序id的内容,而最外面的两个则清除了剩余部分
这种复杂的黑客行为并不是你想要在代码中运行不止一次的东西,更像是一种工具,可以在不需要编写php脚本的情况下从表中获取数据
注意,这可以简化为
SELECT uo.*,
SUBSTRING_INDEX(
SUBSTRING_INDEX( uo.data, '";}' , 1 ),
'"',-1)
AS `old order id`
FROM `uc_orders` AS `uo`
HAVING `old order id` = 25
但这只在这个特定的情况下有效(我想要的值在数据块的末尾)好吧,我也有同样的问题,显然这是小菜一碟,但可能需要更多的测试
只需使用IN语句,但将字段本身作为数组!
例如:
SELECT id, title, page FROM pages WHERE 2 IN (child_of)
~其中“2”是我在字段“child_of”中查找的值,该字段是一个序列化数组
这个序列化数组是必要的,因为我不能复制记录,而仅仅是为了存储它们是哪个id的子项
干杯foreach($result as$value){
$hour=未序列化($value->meta_值);
如果($hour['date']<$data['from']){
$sum=$sum+$hour['hours'];
}
}
处理php序列化数据显然相当难看,但我有一系列MySQL函数,有助于解决这一问题:
select REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(searchColumn, 'fieldNameToExtract', -1), ';', 2), ':', -1), '"', '') AS extractedFieldName
from tableName as t
having extractedFieldName = 'expressionFilter';
希望这能有所帮助 如果日志表中有属性_dump字段,并且其中一行中的值
a:69:{s:9:"status_id";s:1:"2";s:2:"id";s:5:"10215"}
如果我想获取状态_id等于2的所有行,那么查询将是
SELECT * FROM log WHERE attribute_dump REGEXP '.*"status_id";s:[0-9]+:"2".*'
上面有一个很好的正则表达式答案,但它假设一个键
和值
实现。如果序列化数组中只有值
,这对我很有用:
仅限值
从您的_字段在此处REGEXP.*所在的表中选择*;s:[0-9]+:“你的价值在这里”。*”
关键和价值
SELECT*从您的_字段_hereregexp.*“数组_key _here”所在的表中;s:[0-9]+:“此处为您的值”。*”
便于方法使用:
column_field_name LIKE %VALUE_TO_BE_SEARCHED_FOR%
在MySQL查询中除非您的项具有非常独特的标识方式,否则最好将序列化数据存储为表或其他形式。哪种数组?整数?串?混合的?您能提供一些示例记录吗?永远不要存储要搜索的序列化数据…从table where table_字段(如“%”中选择*输入您的_值“%”是的,看起来我最好的选择是忘记数组并将其存储在自己的表中。谢谢!>天哪,我的第二反应是:为什么?明智的做法是:“多么居高临下。”。通常情况下,当使用诸如Drupal和WordPress之类的CMS系统时,您无法控制其他一些无意识程序员使用的格式
a:69:{s:9:"status_id";s:1:"2";s:2:"id";s:5:"10215"}
SELECT * FROM log WHERE attribute_dump REGEXP '.*"status_id";s:[0-9]+:"2".*'
column_field_name LIKE %VALUE_TO_BE_SEARCHED_FOR%