【问题标题】:Recommended MySQL data model for similar class objects类似类对象的推荐 MySQL 数据模型
【发布时间】:2012-07-13 11:59:02
【问题描述】:

我们将创建一个 MySQL 数据库来反映以下 PHP 类:

  • 内容
  • 文章扩展了内容
  • 帖子扩展了内容
  • ...

会有与内容相关的模型,例如评论、忽略等。

这里的问题是使用哪种数据模型。

1) 每个模型一个表

2) 一个大型内容表(所有类属性作为列),以及其他模型的单个表。我相信它被称为单表继承。

3) 包含常用字段的大型内容表,或仅包含我们通常搜索的字段(索引),以及包含其余属性的大型内容数据表。

4) 其他方式?

我们希望能够查询内容,并获取最近的、基于位置的或以某种方式过滤的内容,而不管它是哪种内容类型(子类)。因此解决方案 1 可能是不可能的。

这个系统应该是快速和可扩展的。解决这个问题的最佳方法是什么?

【问题讨论】:

  • 就个人而言,我通常选择选项 2,因为选项 3 让人想起 EAV,许多顶级开发人员认为这是一种反模式。
  • 您可以简单地查看 WordPress 架构并复制它。为什么要重新发明轮子?

标签: mysql datamodel


【解决方案1】:

我写了一篇关于这个主题的博文,你可能会觉得有帮助:http://jasonswett.net/blog/composition-a-better-alternative-to-orm-inheritance/

首先,我建议您将您的餐桌称为content_item 或其他名称,而不是content。这样做的原因是我相信表名应该与它所代表的事物的名称相匹配。有关详细信息,请参阅this other blog post of mine

因此,您可能有一个名为content_item 的表、一个名为article 的表和一个名为post 的表。 content_item 将具有 titleslug 等列 - 每个内容项将具有的所有内容,无论是帖子、文章还是其他内容。然后article 将有一个content_item_id,然后是特定于文章的任何其他内容,但只有特定于文章的内容。对于每篇文章,您将拥有一条 content_item 记录,然后是一条附加到该 content_item 记录的 article 记录。

这将使您能够查询content_item 并获得包含所有内容类型的结果。

我过去曾成功实施过这种解决方案。 (我也尝试过不同的方法,但不太喜欢它们。)

【讨论】:

  • 我同意 content_item 的命名。
  • 如果你想要 100 个最近的内容项,你会如何查询这种数据库?这里的问题是您希望加入不同的表,具体取决于 content_item 的类型(文章、帖子等)。
  • SELECT * FROM content_item JOIN article ON article.content_item_id = content_item.id JOIN post ON post.content_item_id = content_item.id ORDER BY content_item.id DESC LIMIT 100
【解决方案2】:

如果它们是足够相似的对象,我会使用选项 3... 一个 la drupals 节点概念或当前 wordPress 的“帖子”想法

【讨论】:

    【解决方案3】:

    也许可以试试这样的东西。您对文章和文章扩展内容的需求可能不同,但不是从内容 -> 文章(或文章)的 1..many 关系,为什么不增加在任何内容中混合/匹配内容的灵活性。如果您不需要/不希望这样做,则省略 article_content 和 post_content 表,只需将外键 content_id INT NOT NULL 分别添加到每个 post 和 article 表..


    CREATE TABLE IF NOT EXISTS content (id INT NOT NULL AUTO_INCREMENT, title VARCHAR(32) NOT NULL, description VARCHAR(255) NULL, body TEXT, published DATETIME NOT NULL, updated DATETIME NULL, owner_id INT DEFAULT '0', status TINYINT(1) DEFAULT '1', PRIMARY KEY (id), INDEX idx_content_status (status));

    CREATE TABLE IF NOT EXISTS article (id INT NOT NULL AUTO_INCREMENT, title VARCHAR(32) NOT NULL, excerpt VARCHAR(255) NULL, url_slug VARCHAR(64) NOT NULL, author_id INT NOT NULL, 发布的 DATETIME NOT NULL, 更新DATETIME NULL, status TINYINT(1) DEFAULT '1', sort_order INT DEFAULT '1', PRIMARY KEY (id), UNIQUE INDEX idx_article_slug(url_slug), INDEX idx_article_search(title, published, status, sort_order));

    CREATE TABLE IF NOT EXISTS post(id INT NOT NULL AUTO_INCREMENT,title VARCHAR(32) NOT NULL,comment VARCHAR(128) NULL,author_id INT NOT NULL,发布的 DATETIME NOT NULL,更新的 DATETIME NULL,状态 TINYINT(1)默认'1',主键(id));

    CREATE TABLE IF NOT EXISTS tags (id INT NOT NULL AUTO_INCREMENT, tag VARCHAR(24) NOT NULL, PRIMARY KEY (id));

    如果不存在则创建表 article_content (article_id INT NOT NULL, content_id INT NOT NULL, status TINYINT(1) DEFAULT '1', sort_order INT DEFAULT '1', INDEX idx_article_content_search(article_id, content_id, status, sort_order));

    如果不存在则创建表 post_content (post_id INT NOT NULL, content_id INT NOT NULL, status TINYINT(1) DEFAULT '1', sort_order INT DEFAULT '1', INDEX idx_post_content_search(post_id, content_id, status, sort_order));

    CREATE TABLE IF NOT EXISTS article_tags (article_id INT NOT NULL, tag_id INT NOT NULL, INDEX idx_article_tag_search(article_id, tag_id));

    如果不存在则创建表 post_tags (post_id INT NOT NULL, tag_id INT NOT NULL, INDEX idx_post_tag_search(post_id, tag_id));

    【讨论】:

    • 如果你想要 100 个最近的内容项,你会如何查询这种数据库?这里的问题是您希望加入不同的表,具体取决于 content_item 的类型(文章、帖子等)。
    猜你喜欢
    • 2021-04-17
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 2019-06-27
    相关资源
    最近更新 更多