存储在数组或字段中?哪个更好?

时间:2013-09-10 12:11:58

标签: php mysql mysqli

今天我在我的网站上工作,我问自己一个简单的问题。
存储具有所有信息的数组比将它们保存在不同的字段中更好吗? 例如,如果我以这种方式在数据库的一个字段中存储单词,密码和数字

+-------------+----------------------------------------------------------------+
| Field       | Value                                                          |
+-------------+----------------------------------------------------------------+
| all         | ["test","fa26be19de6bff93f70bc2308434e4a440bbad02","25468684888"] |
+-------------+----------------------------------------------------------------+

这比以这种方式保存更好吗?

+-------------+------------------------------------------+
| Field       | Value                                    |
+-------------+------------------------------------------+
| word        | test                                   |
| password    | fa26be19de6bff93f70bc2308434e4a440bbad02 |
| number      | 25468684888                              |
+-------------+------------------------------------------+

我认为第一种方法比最后一种方法更快,因为你只需要选择一个字段而不是三个或更多字段。你觉得怎么样?

5 个答案:

答案 0 :(得分:5)

第二种方法。到目前为止。

您不应该将多个数据放入一个列中。

单行数据包含您需要的所有信息:

id  name    password
1   Fluff   itsASecret
2   Flupp   Ohnoes

基本上,它与更新,选择,搜索以及数据库所做的几乎所有事情有关。它们是在单列上完成的,而不是字符串中的少量数据。

举个例子,你如何更新密码?如何在用户ID上添加索引?

如果您还有一些名为“NumberOfVotes”的数据怎么办?如果您在伪数组中的一列中都拥有它,那么如何获得所有用户投票的总数?你真的想把每个条目都拉到PHP中,将它爆炸出来,把它添加到正在运行的总数中,那么显示已经投了多少票?如果你有一百万用户怎么办?

如果您将所有内容存储在一个列中,您可以很容易地做到这一点:

select
    sum(NumberOfVotes)
from
    yourTableName

编辑(回复更快的查询):

绝对不是,强制查询所需的时间将归结为两件事: 1)执行查询所需的时间 2)返回所有数据所需的时间。

在这种情况下,返回数据所花费的时间将是相同的,毕竟数据库返回相同数量的字节。但是,对于正确设置的表格,只需按照数量级的顺序查找正确的数据即可。

作为一个例子,简单地使用一个具有各种信息位的表都是多么困难,尝试编写一个查询来更新以“test”开头的行中的“number”值”

话虽如此,但可能存在一些可能的情况,即在一列中存储多个“字段”数据实际上是可以的。我曾经为那些以二进制存储各种权限的用户看到(并复制)了一个非常有趣的权限系统,数字中的每个数字等同于允许/不允许执行某种类型的操作。然而,这是一个有趣的例子 - 而且几乎是我所谓的例外证明规则:)

答案 1 :(得分:2)

  

我认为第一种方法更快

实际上是您的主要问题。您只是从“更快”的角度来比较解决方案。虽然你没有措施来判断是否存在任何差异。或者,即使存在,如果这种差异确实很重要。所以,唯一的理由是 false。虽然你完全忽略了重要的,基本的原因,如正确的数据库设计。

答案 2 :(得分:1)

在单独的字段中保存更加灵活,因为您可以使用SQL查询轻松搜索/操作数据,而如果它们在数组中,您经常会发现自己需要在SQL之外解析数据。请考虑以下示例:

+-------------+----------------------------------------------------------------+
| Field       | Value                                                          |
+-------------+----------------------------------------------------------------+
| all         | ["1","fa26be19de6bff93f70bc2308434e4a440bbad02","25468684888"] |
+-------------+----------------------------------------------------------------+

使用上表,你需要找到id为1的用户的号码字段,但是没有什么可以搜索的,你不能简单地在all的某个地方查询值1字段,因为它会找到数字1的每个实例!

在更改数据库中的数据时也会遇到此问题,因为您必须获取当前数组,解析它,更改值,然后重新插入。

此外,您还需要将某种形式的ID作为字段作为主键。

但是,每个值都有单独的字段,这很简单:

+-------------+------------------------------------------+
| Field       | Value                                    |
+-------------+------------------------------------------+
| id          | 1                                        |
| password    | fa26be19de6bff93f70bc2308434e4a440bbad02 |
| number      | 25468684888                              |
+-------------+------------------------------------------+

SELECT `number` FROM mytable WHERE id = 1

答案 3 :(得分:1)

第二种选择更好,因为它更具可读性和可维护性。

如果没有编写代码的人必须维护它,那么第一个选项就太糟糕了。 如果您需要更改字段或添加字段,同样,第一个选项就是噩梦。

第二种选择需要的工作少得多。

保持简单!

答案 4 :(得分:0)

我认为给出的例子是微不足道的,这就是为什么具体例子的答案是第二种方法。但是有时候第一种方法更容易实现。例如,您可以从管理面板动态创建网站页面,并且在开始时您不知道将在每个页面中使用的所有值。所以你把第二种方法中的常规选项放在第二种方法中,然后输入类似page_data的内容并用它来存储序列化对象。现在,您应该将序列化对象用于不太可能单独更改的数据,因为它们被视为单个数据。

在您的代码中,您获取序列化对象,进行反序列化并正常使用它们。这样,您可以添加不针对每个页面进行一般化的页面特定数据,但页面仍然是相同的。