【问题标题】:EAV vs Serialized Object vs SQL with Xpath?EAV vs 序列化对象 vs SQL with Xpath?
【发布时间】:2011-05-13 23:40:11
【问题描述】:

我正在尝试实现一个徽章系统,徽章基于用户的元数据,可能会发生变化。

这些元数据是可变的,并且是动态设置的。

元数据示例:

  • commentCount
  • hasCompletedProfile
  • isActiveMember

等等。稍后,我想添加hasGravatar 元数据,因此我无法轻松设计和规范化表。

这些数据虽然是应用程序的重要组成部分,但并不“明智”,但几乎所有这些元数据都可以重新计算,这意味着数据的完整性不是约束的一部分。

目前,我知道三个选项,即使我一个都不知道。

  • EAV
  • 序列化对象
  • XML 字段(我在某处读到可以将 XML 存储在列中,并使用 XPATH 或其他方式查询数据)

所有这些选项看起来都有利有弊,但由于我从未尝试过它们,所以我真的不知道是哪个。

您有什么意见或建议吗?

我目前正在使用带有 MySQL 服务器的 Zend Framework & Doctrine 2

【问题讨论】:

    标签: sql database-design doctrine-orm


    【解决方案1】:

    XML 和序列化对象都非常相似,因为您可能会使用 1 列来存储这些任意数据。这很快就会变得非常混乱,很难在 SQL WHERE 子句中轻松区分(尽管一些 DBMS 支持 XPath)

    另一方面,EAV 将为您拥有的每个 Key => Value 对提供一个单独的行,您可以使用 JOIN 或子查询轻松地将其提取出来。主要的缺点是,如果您在此处有 大量 数据,它可能会影响性能。另一个缺点是,为了简单起见,您会将所有键/值作为文本存储在数据库中。您可以为每种类型创建一个 EAV 表,但在大多数语言中实际上并不需要它,因为您获取的内容以字符串形式出现,或者无论如何都可以在那里进行转换。简单地存储用户配置/属性对于 EAV 来说应该是完全可以的。

    所以你可能有一个表 user_metadata 有 3 个字段:

    metadata_id INTEGER
    user_id INTEGER
    key CHAR
    value CHAR
    

    然后您可以一次为用户获取所有这些数据:

    SELECT * FROM user_metadata WHERE metadata_user_id = $user_id
    

    或者您可以获取单个元数据以及您的用户数据

    SELECT user.*, meta_gravatar.value AS hasGravatar
    FROM user
    LEFT JOIN user_metadata AS meta_gravatar
     ON meta_gravatar.user_id = user.user_id AND meta_gravatar.key = 'hasGravatar'
    WHERE user.user_id = $user_id
    

    【讨论】:

      【解决方案2】:

      EAV:复杂且缓慢。这是一个如何不使用 SQL 数据库的示例。您不能在 EAV 中对属性进行索引,并且您需要一些重要的逻辑来将数据从数据库获取到业务逻辑对象中。此外,您的 SQL 查询也变得难以优化。

      序列化对象:序列化通常取决于语言或平台。无法对某些属性进行索引或搜索任何内容,但这是一种存储未定义结构数据的简单方法。

      XML 字段:使用标准化表示优于序列化。此外,您的 SQL 服务器可能支持此类数据结构。

      JSON 字段:与 XML 字段相同,但 JSON 支持原始数据类型(int、bool、null),并且解析和序列化比 XML 更快、更容易。一些 SQL 服务器也为它提供了一些支持。

      这三种序列化方式都有一个共同的缺点:属性上没有索引。在大多数应用程序中,这是可以接受的,因为无论如何数据库都不处理数据,因此它们只是应用程序的一个 blob。好消息是,这个 blob 不会使数据库架构和操作复杂化。

      还有另一种实现这种 EAV 替代方案的方法:普通的旧 SQL 表。如果新属性需要对应用程序代码进行一些更改,那么您也可以添加 SQL 列。如果您有用户界面和应用程序逻辑来在运行时定义属性,您可以教您的应用程序使用 ALTER TABLE 查询。然后,您只需根据需要添加或删除列。最后,只要您有一个好的查询构建器,它就会比实施 EAV 更容易、更有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-10
        • 2012-06-21
        • 2011-03-30
        • 2016-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多