【发布时间】:2010-12-31 00:14:02
【问题描述】:
将数据数组保存到单个 mysql 字段的好方法是什么?
此外,一旦我在 mysql 表中查询该数组,有什么好方法可以将其恢复为数组形式?
是序列化和反序列化的答案吗?
【问题讨论】:
将数据数组保存到单个 mysql 字段的好方法是什么?
此外,一旦我在 mysql 表中查询该数组,有什么好方法可以将其恢复为数组形式?
是序列化和反序列化的答案吗?
【问题讨论】:
没有好的方法可以将数组存储到单个字段中。
您需要检查关系数据并对架构进行适当的更改。有关此方法的参考,请参见下面的示例。
如果您必须将数组保存到单个字段中,那么serialize() 和unserialize() 函数就可以解决问题。但是您不能对实际内容执行查询。
作为序列化函数的替代方案,还有json_encode() 和json_decode()。
考虑以下数组
$a = array(
1 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
2 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
);
要将其保存在数据库中,您需要创建一个这样的表
$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
$r = mysql_query(
'DROP TABLE IF EXISTS test');
$r = mysql_query(
'CREATE TABLE test (
id INTEGER UNSIGNED NOT NULL,
a INTEGER UNSIGNED NOT NULL,
b INTEGER UNSIGNED NOT NULL,
c INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (id)
)');
要处理记录,您可以执行诸如此类的查询(是的,这是一个示例,请注意!)
function getTest() {
$ret = array();
$c = connect();
$query = 'SELECT * FROM test';
$r = mysql_query($query,$c);
while ($o = mysql_fetch_array($r,MYSQL_ASSOC)) {
$ret[array_shift($o)] = $o;
}
mysql_close($c);
return $ret;
}
function putTest($t) {
$c = connect();
foreach ($t as $k => $v) {
$query = "INSERT INTO test (id,".
implode(',',array_keys($v)).
") VALUES ($k,".
implode(',',$v).
")";
$r = mysql_query($query,$c);
}
mysql_close($c);
}
putTest($a);
$b = getTest();
connect()函数返回一个mysql连接资源
function connect() {
$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
return $c;
}
【讨论】:
一般来说,是的,序列化和反序列化是要走的路。
但是,如果您的数据很简单,那么保存为逗号分隔的字符串可能会更适合存储空间。例如,如果您知道您的数组只是一个数字列表,那么您应该使用 implode/explode。这就是1,2,3 和a:3:{i:0;i:1;i:1;i:2;i:2;i:3;} 的区别。
如果不是,则对所有情况进行序列化和反序列化工作。
【讨论】:
只需使用序列化 PHP 函数:
<?php
$myArray = array('1', '2');
$seralizedArray = serialize($myArray);
?>
但是,如果您使用这样的简单数组,不妨使用 implode 和 explode。使用空白数组而不是 new。
【讨论】:
序列化/反序列化数组以存储在数据库中
访问http://php.net/manual/en/function.serialize.php
来自 PHP 手册:
在页面的“返回”下查看
返回一个字符串,其中包含可以存储在任何地方的值的字节流表示形式。
请注意,这是一个可能包含空字节的二进制字符串,需要按原样存储和处理。例如,serialize() 输出通常应存储在数据库中的 BLOB 字段中,而不是 CHAR 或 TEXT 字段中。
注意:如果要将 html 存储到 blob 中,请务必对其进行 base64 编码,否则可能会破坏序列化功能。
示例编码:
$YourSerializedData = base64_encode(serialize($theHTML));
$YourSerializedData 现在可以存储在 blob 中了。
从 blob 获取数据后,您需要 base64_decode 然后反序列化 解码示例:
$theHTML = unserialize(base64_decode($YourSerializedData));
【讨论】:
我发现自己最好的方法是将数组保存为带有分隔符的数据字符串
$array = array("value1", "value2", "value3", "...", "valuen");
$array_data = implode("array_separator", $array);
$query = "INSERT INTO my_tbl_name (id, array_data) VALUES(NULL,'" . $array_data . "');";
然后您可以通过简单的查询搜索存储在数组中的数据
$query = "SELECT * FROM my_tbl_name WHERE array_data LIKE '%value3%'";
使用explode()函数将“array_data”字符串转换为数组
$array = explode("array_separator", $array_data);
请注意,这不适用于多维数组,并确保您的“array_separator”是唯一的并且不存在于数组值中。
小心!!!如果您只是将表单数据放入数据库中,那么您将陷入困境,因为表单数据不是 SQL 安全的!你必须处理你的表单值 使用 mysql_real_escape_string 或者如果您使用 MySQLi mysqli::real_escape_string 或者如果值是整数或布尔类型转换 (int) (boolean)
$number = (int)$_POST['number'];
$checked = (boolean) $_POST['checked'];
$name = mysql_real_escape_string($db_pt, $_POST['name']);
$email = mysqli_obj->real_escape_string($_POST['email']);
【讨论】:
序列化和反序列化是很常见的。您还可以通过 json_encode 和 json_decode 使用 JSON,以获得较少的 PHP 特定格式。
【讨论】:
如前所述 - 如果您不需要在数组中搜索数据,您可以使用序列化 - 但这是“仅限 php”。所以我建议使用json_decode / json_encode - 不仅是为了性能,也是为了可读性和可移植性(其他语言,如 javascript 可以处理 json_encoded 数据)。
【讨论】:
呃,不知道为什么大家都建议序列化数组。
我说,最好的方法是将它实际放入您的数据库架构中。我不知道(你也没有提供任何线索)关于数组中数据的实际语义含义,但通常有两种存储序列的方法
create table mydata (
id int not null auto_increment primary key,
field1 int not null,
field2 int not null,
...
fieldN int not null
)
这样您将数组存储在一行中。
create table mydata (
id int not null auto_increment primary key,
...
)
create table myotherdata (
id int not null auto_increment primary key,
mydata_id int not null,
sequence int not null,
data int not null
)
显然,第一种方法的缺点是,如果数组中有很多项,则使用该表将不是最优雅的事情。使用可变长度的序列也是不切实际的(可能,但也很不雅 - 只是使列可以为空)。
对于第二种方法,您可以拥有任意长度的序列,但只能是一种类型。当然,您可以制作一种类型 varchar 或其他类型并序列化数组中的项目。不是最好的做法,但肯定比序列化整个数组更好,对吧?
无论哪种方式,这些方法中的任何一个都具有明显的优势,即能够访问序列的任意元素,并且您不必担心序列化数组和诸如此类的丑陋事情。
至于拿回来。好吧,通过查询获取适当的行/行序列,然后,使用 loop.. 对吗?
【讨论】:
您可以将数组保存为 json。
有 json 数据类型的文档:https://dev.mysql.com/doc/refman/5.7/en/json.html
我认为这是最好的解决方案,并且会通过避免疯狂的函数来帮助您保持代码更具可读性。
我希望这对你有帮助。
【讨论】:
是的,序列化/反序列化是我在许多开源项目中看到最多的。
【讨论】:
我建议将 implode/explode 与您知道不会包含在任何单个数组项中的字符一起使用。然后将其作为字符串存储在 SQL 中。
【讨论】:
查看 implode 函数,因为值在数组中,所以您希望将数组的值放入 mysql 查询中,该查询将值插入表中。
$query = "INSERT INto hardware (specifications) VALUES (".implode(",",$specifications).")";
如果数组中的值是文本值,则需要加引号
$query = "INSERT INto hardware (specifications) VALUES ("'.implode("','",$specifications)."')";
mysql_query($query);
另外,如果您不想重复值,请将“INto”切换为“IGNORE”,这样只会将唯一值插入到表中。
【讨论】:
您可以将序列化对象(数组)插入 mysql,例如serialize($object),您可以取消序列化对象例如unserialize($object)
【讨论】:
不要将其保存到数据库中,而是将其保存到文件中,然后再调用它。
许多 php 应用程序(如 Sugarcrm)所做的只是使用 var_export 将数组的所有数据回显到文件中。 这是我用来保存配置数据的:
private function saveConfig() {
file_put_contents($this->_data['pathtocompileddata'],'<?php' . PHP_EOL . '$acs_confdata = ' . var_export($this->_data,true) . ';');
}
我认为这是保存数据的更好方法!
【讨论】: