【问题标题】:How to efficiently design MySQL database for my particular case如何为我的特殊情况有效地设计 MySQL 数据库
【发布时间】:2013-02-17 13:25:56
【问题描述】:

我正在用 PHP MySQL 开发一个论坛。我想让我的论坛尽可能高效。

这两张表我做了

  1. tbl_threads
  2. tbl_cmets

现在,问题是每个评论下都有一个喜欢和不喜欢的按钮。我必须使用comment_id 存储已单击“喜欢”或“不喜欢”按钮的user_name。我在tbl_comments 中创建了一个user_likes 列和一个user_dislikes 列来存储逗号分隔的user_names。但是在这个论坛上,我读到这不是一种有效的方法。有人建议我创建第三个表来存储喜欢和不喜欢,并让我的数据库设计符合 1NF。

但问题是,如果我创建第三张表 tbl_user_opinion 并创建两个这样的字段 1.comment_id 2.类型(喜欢或不喜欢)

那么,我是否必须运行与我页面上的 cmets 一样多的 sql 查询才能获取每个评论的喜欢和不喜欢数据。会不会低效。我认为我在这里有些困惑。有人能澄清一下吗?

【问题讨论】:

  • Postgres 可以使分层查询比 mysql 容易得多

标签: mysql sql database database-design relational-database


【解决方案1】:

逗号分隔的列表违反了atomicity 的原则,因此违反了1NF。您将很难维护引用完整性,并且在大多数情况下,查询也是如此。

这是一种以标准化方式进行的方法:

这对clustering 非常友好:它将属于同一评论的赞成票分组在物理上靠得很近(反对票同上),使以下查询相当有效:

SELECT
    COMMENT.COMMENT_ID,
    <other COMMENT fields>,
    COUNT(DISTINCT UP_VOTE.USER_ID) - COUNT(DISTINCT DOWN_VOTE.USER_ID) SCORE
FROM COMMENT
    LEFT JOIN UP_VOTE
        ON COMMENT.COMMENT_ID = UP_VOTE.COMMENT_ID
    LEFT JOIN DOWN_VOTE
        ON COMMENT.COMMENT_ID = DOWN_VOTE.COMMENT_ID
WHERE
    COMMENT.COMMENT_ID = <whatever>
GROUP BY
    COMMENT.COMMENT_ID,
    <other COMMENT fields>;

[SQL Fiddle]

如果这对您来说足够快,请根据实际数据量进行衡量。如果不是,则对模型进行非规范化并将总得分缓存在 COMMENT 表中,并在每次向 *_VOTE 表插入或删除新行时通过触发器使其保持最新。

如果您还需要获取特定用户对哪些 cmets 进行了投票,则需要 *_VOTE {USER_ID, COMMENT_ID} 上的索引,即上述主键/集群键的反面。1


1 这就是为什么我没有只使用一个包含额外字段的 VOTE 表的原因之一,该字段可以是 1(用于投票)或 -1(否决票):使用二级索引的cover 效率较低。

【讨论】:

    【解决方案2】:

    你有一个这样的关系方案:

    有两种方法可以解决这个问题。第一个,“干净”的一个是建立你的“喜欢”表,并在适当的列上做“计数(*)”。

    第二种方法是在每条评论中存储一个计数器,指示那里有多少涨跌。 如果您想检查,如果特定用户对评论投票,您只需要检查一个条目,您可以轻松地将它们作为自己的查询处理并将它们合并到您的数据库之外(为此使用查询导致 comment_id 和用户在特定线程中所做的投票。)

    您使用逗号分隔列表的方法不是很高效,因为您无法在没有更高智能或大量解析字符串的情况下解析它。如果您有数据库 - 使用它!

    (“一个信息 - 一个数据集”!)

    【讨论】:

    • 如果我遵循第一种方法并创建一个单独的表来存储喜欢和不喜欢。那么我的三个表之间就会有关系。首先,我将根据 tbl_threads.thread_id = tbl_cmets.thread_id 从 tbl_cmets 中检索 cmets,然后我必须通过从 tbl_likes 中检索数据来检查登录用户是否喜欢或不喜欢每个评论。会不会是一个复杂耗时的sql查询。
    猜你喜欢
    • 2016-07-10
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    相关资源
    最近更新 更多