将PHP数组数据保存到mysql表的最佳方法

将PHP数组数据保存到mysql表的最佳方法

问题描述:

我的问题是什么是将大型php数组保存到mysql表的最好和最有效的方法。我知道有很多方法可以做到这一点,我尝试了其中的一些方法,但我仍然没有找到一种我真正感觉舒适的方法。大多数人推荐的主要方法是serialize()和unserialize()php函数。由于某种原因,这不适合我,我似乎已经尝试了各种方法来解决这个问题,但idk。将PHP数组数据保存到mysql表的最佳方法

这里是我的代码:

// unserialize songs, add new song to end of array, and then re-serialize to add to db 
    $cereal = unserialize($dbsongs); 
    $pushed = array_push($cereal, $_GET['song']); 
    $songs = serialize($pushed); 

    //update playlists table 
    $stmt = $dbh->prepare("UPDATE playlists SET songs=:songs WHERE title=:title AND user=:user"); 
    $stmt->bindParam(':user', $_SESSION['username'], PDO::PARAM_STR); 
    $stmt->bindParam(':title', $_GET['title'], PDO::PARAM_STR); 
    $stmt->bindParam(':songs', $songs, PDO::PARAM_STR); 
    $stmt->execute(); 

所以首先我反序列化 $ dbsongs这是串行数据从一个MySQL表的空白列表。然后我将 $ _GET ['song'] array_push()。然后我序列化并将其存储到数据库。出于某种原因,这不起作用,但我也想知道是否有更好的方法。

我应该尝试拆分php数组,并将每个项目保存到一个表格中,并用逗号分隔项目,并且当我从数据库中检索它时打破该字符串?

或者我应该修复这个方法吗?或甚至添加 base64_decode() base64_encode()?这些方法似乎是从一些我看过的东西有点老... http://www.evolt.org/node/60222

我已经看到了使用 .implode的方法,但我无法弄清楚如何使用它... Link 1Link 2。这看起来像我见过的最现代的方法。这是我应该进一步研究的吗?

不知道这个方法是什么,但它提到CakePHP,我想是一个PHP库。这是一个好方法吗? Link 1

我将在这些列表中存储大量项目(如定期超过1k个项目),所以我甚至不确定是否将这些项目保存到一个表格字段是适当的。只是为这些项目制作表格是最好的方法,因为列表将会变得很大(为每个新项目添加一个新的数据库条目,并制作一个“标题”字段以将它们链接在一起)?我从来没有尝试过这样的事情,因为我永远无法找到足够的信息,说明mysql可以在不出现问题的情况下保存多少数据。

我知道这里有很多问题,但任何答案将不胜感激!提前致谢!

-BAH

+1

您是否反对将*歌曲*存储在另一个表中并创建一个桥表格(* playlist_songs *)来处理关系?这是使用关系数据库(如MySQL)的传统方式。 – 2011-12-31 05:15:44

首先,我要说的是serialize()是去,如果你想存储PHP数组在DB的方式。

您的问题是您误用了array_push()。如果正确使用它,则serialize()方法将起作用。我将立即解决如何为此目的修复您的代码。

使用序列化并将序列化歌曲名存储在单个TEXT字段中实际上是理想的,因为它使得FULLTEXT索引搜索非常简单(我假设MySQL)。例如,当您将序列化数组存储在单个字段中时,可以轻松找到包含单词“awesome”的歌曲标题的所有列表。

另一种方法是创建三个表:一个列表,一个歌曲和一个歌曲和列表之间的联系。然后,您可以使用LEFT JOIN查询将歌曲与列表进行匹配。在你的情况下,我会选择前一种选择。

的储存方法完全取决于您打算如何访问数据。如果您需要能够快速匹配特定歌曲名称并且经常列表,则第二个提到的规范化数据库表单可能会更好。

为什么SERIALIZE工作不适合你现在...

array_push()返回一个整数,它接收到的第一个参数是按引用传递。这意味着行:

$pushed = array_push($cereal, $_GET['song']);

实际上是设置$pushed等于$cereal阵列加一个中的元素的数量。

您可以纠正你的问题,像这样:

$serial = unserialize($dbsongs); 
$song_count_in_pushed_array = array_push($serial, $_GET['song']); 
$songs = serialize($serial); 

UPDATE

在回答您的有关编码序列化的数据的base64评论,这里是你如何做到这一点,以防止数据数据损坏这不是8位清洁:

// For safe serializing 
$encoded_and_serialized = base64_encode(serialize($array)); 

// For unserializing 
$restored = unserialize(base64_decode($encoded_and_serialized)); 
+0

真棒,感谢修复!所以你会推荐保存列表的unserialize()和serialize()方法?怎么样的base64_decode()和base64_encode()函数,我需要它们(我想这取决于什么数据即时保存,不适宜将int变量保存到列表中)?再次感谢您的帮助! – bahudso 2012-01-01 01:15:19

+1

是的,serialize/unserialize专门用于传输数据结构(如数组)。 base64函数避免了[8位清理](http://en.wikipedia.org/wiki/8-bit_clean)数据的麻烦。例如,假设您序列化并存储包含UTF-16字符串的数组,但您的数据库归类不支持这些字符。如果您不对编码序列化的数据进行base64编码,则最终会导致数据损坏。我在答案的最后添加了一条注释以说明这一点。但是,如果您只是存储数字数据,则base64函数将不再需要。 – rdlowrey 2012-01-02 01:56:24