什么是将数据数组保存到单个mysql字段的好方法?
另外,一旦我在mysql表中查询该数组,有什么好方法可以将其恢复为数组形式?
是序列化和反序列化答案吗?
Answers:
没有好的方法可以将数组存储到单个字段中。
您需要检查您的关系数据并对模式进行适当的更改。请参阅下面的示例以获取对此方法的参考。
如果必须将数组保存到单个字段中,则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;
}
通常,是的,序列化和反序列化是可行的方法。
但是,如果您的数据很简单,则另存为逗号分隔的字符串可能会更好地存储空间。例如,如果您知道数组只是数字列表,则应使用爆破/爆炸。1,2,3
和之间的区别a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}
。
如果不是,则在所有情况下都对工作进行序列化和反序列化。
序列化/反序列化阵列以存储在数据库中
前往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']);
如前所述-如果您不需要在数组中搜索数据,则可以使用序列化-但这是“仅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或其他类型,然后序列化数组中的项。不是最好的事情,但肯定比序列化整个数组更好,对吧?
无论哪种方式,这些方法中的任何一个都有明显的优势,即能够访问序列中的任意元素,并且您不必担心序列化数组和类似的事情。
至于找回来。好吧,通过查询获取适当的行/行序列,然后使用循环..对吗?
您可以将数组另存为json。
有关于json数据类型的文档:https : //dev.mysql.com/doc/refman/5.7/en/json.html
我认为这是最好的解决方案,它将通过避免疯狂的功能来帮助您保持代码的可读性。
我希望这对您有帮助。
我建议对您知道不会在任何单个数组项中包含的字符使用爆破/爆炸。然后将其作为字符串存储在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) . ';');
}
我认为这是保存数据的更好方法!