1

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

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

是不是比这样保存好?

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

我认为第一种方法比最后一种方法更快,因为您只需要选择一个字段而不是三个或更多。你怎么看待这件事?

4

5 回答 5

6

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

您永远不应该将多个数据放入单个列中。

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

id  name    password
1   Fluff   itsASecret
2   Flupp   Ohnoes

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

以您为例,您如何更新密码?如何在用户 ID 上放置索引?

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

如果您将所有内容存储在一个单独的列中,您可以像这样轻松地进行计数:

select
    sum(NumberOfVotes)
from
    yourTableName

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

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

在这种情况下,返回数据所需的时间将是相同的,毕竟数据库返回的字节数相同。但是,使用正确设置的表,只需找到正确的数据就会快几个数量级。

举个例子,简单地使用一个包含各种信息的表是多么困难,尝试编写一个查询来更新以单词“test”开头的行中的“number”值。

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

于 2013-09-10T12:13:52.687 回答
2

我认为第一种方法更快

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

于 2013-09-10T12:24:10.270 回答
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
于 2013-09-10T12:19:36.233 回答
1

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

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

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

把事情简单化!

于 2013-09-10T12:25:00.637 回答
0

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

在您的代码中,您获取序列化对象,反序列化并正常使用它们。通过这种方式,您可以添加并非针对每个页面通用的页面特定数据,但页面仍然是相同的。

于 2013-09-10T12:23:28.970 回答