【问题标题】:json column vs multiple columnsjson列与多列
【发布时间】:2011-08-24 14:40:07
【问题描述】:

我什至不知道称它为序列化列是否正确,但我要解释一下自己,例如,我有一个用户表,我想存储用户电话数字(手机、家庭、办公室等),所以,我想为每种数字类型创建一个列,但同时我想到了一个想法,如果我将一个 json 字符串保存在一个单一的列,所以,我永远不会有一个可能永远不会使用的列,我可以在从数据库读取数据时将该字符串转换为 php 数组,但我想听听这种做法的优缺点,也许是只是一个坏主意,但首先我想知道其他人要说什么

谢谢

【问题讨论】:

    标签: php mysql performance json


    【解决方案1】:

    如果你使用 json,有比 MySQL 更优雅的方式。建议使用另一个与 json 配合得更好的数据库,比如 mongoDB,或者像 Persevere 这样的 SQL 包装器,http://www.persvr.org/Documentation(参见“Perstore”)

    【讨论】:

      【解决方案2】:

      简答,多列。

      长答案:

      为了世界上所有神圣的事物,请不要在单个文本列中存储多个数据集

      我假设你会有一张桌子,要么是

      +------------------------------+      +----------------------+
      | User |  cell | office | home |  OR  | User | JSON String   |
      +------------------------------+      +----------------------+
      

      首先我会说这两种解决方案都不是最好的解决方案,但如果您要从两者中选择第一个是最好的。主要有几个原因,尽管修改和查询的能力非常重要。考虑修改第二个选项的算法。

      SELECT `JSON` FROM `table` WHERE `User` = ?
      
      Then you have to do a search and replace in either your server side or client side language
      
      Finally you have to reinsert the JSON string
      

      此解决方案总共有 2 个查询和一个搜索和替换算法。不好!

      现在考虑第一个解决方案。

      SELECT * FROM `table` WHERE `User` = ?
      
      Then you can do a simple JSON encode to send it down
      
      To modify you only need one Query.
      
      UPDATE `table` SET `cell` = ? WHERE `User` = ?
      
      to update more than one its again a simple single query 
      
      UPDATE `table` SET `cell` = ?, `home` = ? WHERE `User` = ?
      

      这显然更好,但不是最好的

      还有第三种解决方案假设您希望用户能够插入无限数量的电话号码。

      让我们使用一个关系表,所以现在你有两个表。

                    +-------------------------------------+
      +---------+   |      Phone                          | 
      | Users   |   +-------------------------------------+ 
      +---------+   | user_name| phone_number | type      |
      | U_name  |   +-------------------------------------+
      +---------+
      

      现在您可以使用类似的方式查询用户的所有电话号码

      现在您可以通过连接查询表

      选择用户。,电话。 FROM Phone,用户 WHERE phone.user_name = ? AND Users.U_name = ?

      插入同样简单,类型检查也很容易。

      请记住,这是一个简单的示例,但 SQL 确实为您的数据结构提供了强大的功能,您应该使用它而不是避免它

      【讨论】:

        【解决方案3】:

        我不确定这种方法的优势是什么。你说“所以,我永远不会有一个可能永远不会使用的列......”我认为你的意思是(在你的系统中)有时用户可能没有可用的每种电话号码的值,并且既然如此,为什么要存储空列的记录?

        使用一些空列存储记录不一定是坏事。但是,如果您想规范化您的数据库,您可以为 user_phonenumber 创建一个单独的表,并在 useruser_phonenumber 记录之间创建 1:many 关系。 user_phonenumber 表基本上有四列:

        • id(主键)
        • userid(用户表的外键)
        • 类型(例如手机、家庭、办公室等)
        • 值(电话号码)

        约束条件是 id 是主键,userid 是 user.id 的外键,type 是枚举(所有可能的电话号码类型)。

        【讨论】:

          【解决方案4】:

          我只会对非必要数据执行此操作,例如,用户最喜欢的颜色、最喜欢的有袋动物类型(显然“非必要”由您决定)。对基本数据(电话号码、用户名、电子邮件、名字、姓氏等)执行此操作的问题在于,您将自己限制在可以使用数据库完成的事情上。这些包括索引字段,使用 ORDER BY 子句,甚至搜索特定的数据。如果以后你意识到你需要执行这些任务中的任何一个,那将是一个令人头疼的问题。

          在这种情况下,最好的方法是使用关系表来处理 1 到多个对象 - 例如 UserPhoneNumbers。它将有 3 列:user_idphone_numbertypeuser_id 允许您将此表中的行链接到适当的 User 表行,phone_number 是不言自明的,type 可以是“家”、“单元”、“办公室”等。这使您仍然可以执行我上面提到的任务,并且它还具有不浪费空列上的空间的额外好处,因为您只需根据需要向该表添加行。

          我不知道您对 MySQL 有多熟悉,但如果您还没有听说过数据库规范化和查询 JOIN,那么现在是开始阅读它们的好时机 :)

          希望这会有所帮助。

          【讨论】:

          • 因此,从 MySQL 5.7 开始,您可以使用 JSON 进行排序或搜索特定数据 - 所以这个答案不再相关。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-19
          • 1970-01-01
          • 2013-05-23
          • 1970-01-01
          相关资源
          最近更新 更多