通过数据库级​​别的查询进行反序列化

Ang*_*dar 38 mysql

我有一个列值存储在数据库中:

一:2:{I:0; S:2: "US"; I:1; S:2: "19";}

我想在mysql查询期间反序列化它,而不是unserialize在获取数据后使用php 函数.我想这样做,所以我可以使用序列化值加入另一个表.这将避免在使用php反序列化后执行单独的查询,仅用于连接的数据.

Pen*_*m10 56

MySQL不知道PHP序列化是什么.你不能这样做.

  • 此外,如果您需要对其进行反序列化以执行"JOIN"操作,您应该*真的*重新考虑您的数据库设计.这需要进一步[规范化](http://en.wikipedia.org/wiki/Database_normalization). (4认同)
  • 我认为"你不能做到这一点"部分会更好地改变,因为它很难实现,而且可能不是最好的方法.如果你能想出解决问题的替代方案,那就更好了. (4认同)
  • 是的,解决方案是标准化,但这是一个外国数据库。我没有任何权利修改它。我正在利用这些数据 (2认同)

Ram*_*hom 32

您可以使用SUBSTRING_INDEX

例如,如果您有这样的记录:

a:5:{s:9:"invoiceid";s:1:"8";s:8:"balance";i:5;s:14:"broughtforward";i:3;s:6:"userid";s:5:"13908";s:10:"customerid";s:1:"3";}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下SELECT语句:

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',1),':',-1) AS fieldname1,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',2),':',-1) AS fieldvalue1,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',3),':',-1) AS fieldname2,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',4),':',-1) AS fieldvalue2,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',5),':',-1) AS fieldname3,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',6),':',-1) AS fieldvalue3,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',7),':',-1) AS fieldname4,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',8),':',-1) AS fieldvalue4,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',9),':',-1) AS fieldname5,
SUBSTRING_INDEX(SUBSTRING_INDEX(old_data,';',10),':',-1) AS fieldvalue5
FROM table;
Run Code Online (Sandbox Code Playgroud)

检查此参考:如何使用mysql反序列化数据而不使用php

  • 如果您的某些序列化数据包含冒号或分号,则此解决方案可能会出现问题. (6认同)
  • 对我来说很好用——虽然 +1 Kyle 确实对分号有一点看法——但这并不意味着你的帖子没有帮助。 (2认同)

nam*_*nam 14

这个怎么样?这是一个嵌入了php的MySQL用户定义函数:

CREATE FUNCTION unserialize_php RETURNS STRING SONAME 'unserialize_php.so';
Run Code Online (Sandbox Code Playgroud)

用法示例:

SELECT unserialize_php('O:8:"stdClass":2:{s:1:"a";s:4:"aaaa";s:1:"b";s:4:"bbbb";}', "$obj->a") 
AS 'unserialized';
Run Code Online (Sandbox Code Playgroud)
+--------------+
| unserialized |
+--------------+
| aaaa         |
+--------------+
1 row in set (0.00 sec)
drop function unserialize_php;
Run Code Online (Sandbox Code Playgroud)

资料来源:https://github.com/junamai2000/mysql_unserialize_php

您可以创建一个MySQL用户定义的函数并zend_eval_string在函数内部调用,以便您可以将PHP变量带回MySQL结果.我实施了一个示例程序.你可以尝试一下.


小智 9

来自http://www.blastar.biz/2013/11/28/how-to-use-mysql-to-search-in-php-serialized-fields/

标准阵列

SELECT * FROM table WHERE your_field_here REGEXP '.*;s:[0-9]+:"your_value_here".*'
Run Code Online (Sandbox Code Playgroud)

关联数组

SELECT * FROM table WHERE your_field_here REGEXP '.*"array_key_here";s [0-9]+:"your_value_here".*'
Run Code Online (Sandbox Code Playgroud)


Ami*_*ara 8

将编程语言相关结构添加到数据库是一种非常糟糕的做法.如果你这样做,你总是要依赖那种语言.

最好的方法是使用规范化的表结构(不同的字段或表).

下一种方法是将数据保存为分隔字符串(例如:) 0,US,1,19.然后你可以使用MySQL SUBSTRING()或使用标准的序列化机制,如JSON编码.


Str*_*ger 6

正如kchteam所提到的,MySQLToolBox库可以方便地使用getPhpSerializedArrayValueByKey这里提供的自定义MySQL函数https://github.com/KredytyChwilowki/MySQLToolBox/blob/master/getPhpSerializedArrayValueByKey.sql.

添加此函数后,您可以使用以下语法检索序列化数组中的任何值,

SELECT getPhpSerializedArrayValueByKey(column_name, 'array_key') AS deseializedArrayValue FROM table_name
Run Code Online (Sandbox Code Playgroud)

给定的数组可以是非序列化的,如,

SELECT getPhpSerializedArrayValueByKey('a:2:{i:0;s:2:"US";i:1;s:2:"19";}
', 'key_to_retrieve') AS key_to_retrieve
Run Code Online (Sandbox Code Playgroud)