【问题标题】:Query Serialized Data查询序列化数据
【发布时间】:2016-12-22 05:23:50
【问题描述】:

我 1000+ 的 SQL 数据行如下所示

umeta_id | user_id | meta_key | meta_value
433369   | 44      | all_contests | a:1:{s:12:"all_contests";a:2:{i:5011;a:1:{s:7:"entries";i:3;}i:8722;a:1:{s:7:"entries";i:3;}}}
433368   | 63      | all_contests | a:1:{s:12:"all_contests";a:2:{i:5032;a:1:{s:7:"entries";i:3;}i:8724;a:1:{s:7:"entries";i:3;}}}

当你反序列化其中一个值时,你会得到一个如下所示的数组:

Array
(
    [all_contests] => Array
        (
            [5011] => Array
             (
              [entries] => 3
             )

            [8722] => Array
             (
              [entries] => 3
             )

      )

)

我正在尝试从给定比赛 ID 的所有用户中创建一个排行榜。 “all_contests”键包含一个数组,该数组由用户注册的所有竞赛的 id 键控。里面是给定比赛的条目。

查询需要查看包含“all_contests”键的所有行,并找到给定比赛 ID 的 10 个最高条目值。

我什至不确定是否可以按照我想要的方式可靠地搜索一段序列化数据。

【问题讨论】:

  • 天啊。这完美地展示了如何将数据存储为序列化数组使得从 SQL 查询中使用该数据几乎是不可能的
  • 您必须选择您可能感兴趣的行,然后在 PHP 中选择 unserialize() 该数据,然后计算出您想对每一行做什么,并可能构建另一个数据数组然后可以处理以获取您需要的信息

标签: php mysql sql serialization


【解决方案1】:

不,在一段序列化数据中搜索是不切实际的。

你可以通过足够细致地使用MySQL String Functions来做到这一点,例如INSTR()SUBSTR()FIELD()等等。但是编写这样的查询来开发查询很耗时,而且性能不会很好。

您正在做的是一个常见错误的变体:将逗号分隔的列表存储在一个表的列中。

这避免了创建交集表来表示多对多关系。换句话说,您有两个用于用户和竞赛的表,您需要第三个表,其中每一行代表一个用户参与了一个竞赛。

查看我对Is storing a delimited list in a database column really that bad?的回复 答案是关于逗号分隔的列表,但它同样适用于你正在做的序列化数组。

【讨论】:

  • 感谢您的意见,我要调整我的模型。
猜你喜欢
  • 2014-12-10
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多