【问题标题】:How would I create this MySQL Schema?我将如何创建这个 MySQL Schema?
【发布时间】:2011-11-23 03:57:29
【问题描述】:

假设我有一个博客文章实体。

  • 它有很多属性
  • 它附有 cmets。
  • 它有许多状态(已删除/锁定/不可见等)。
  • 它有很多“标签”。 (关键字、school_id、user_id)

显然,cmets 应该是它自己的表,与 Blog 表是多对一的关系。

但是“状态”或“标签”呢?你会把它放在另一张桌子上吗?或者你会把它放在很多列中吗?

如果属性太大了怎么办?因为随着我网站的发展,博客文章将附加越来越多的属性(标题、作者、等等等等)。如果属性列表达到 100 会怎样?

【问题讨论】:

  • 总是在另一个表中。如果您将它们嵌入到单个字段中,您就否定了拥有关系数据库的目的 - 您失去了关联事物的能力。
  • "states" 会是它自己的表吗?
  • 状态应该只是帖子表中的一列。关键字绝对应该在一个单独的表中,由 post id 关联,keyword 和 post id 列都有主键。不明白为什么属性列表会增长。如果您要维护任何类型的结构,属性列表应该是相同的,因此在帖子表中将属性作为列是有意义的。

标签: mysql database schema


【解决方案1】:

这是一个示例:

再说一遍.. 这只是一个示例.. 您还可以使用其他方法。

我们开始吧:

-- basic-basic blog
CREATE TABLE blog_entry (
    blog_entry_id INT NOT NULL AUTO_INCREMENT,
    blog_entry_title VARCHAR(255) NOT NULL,
    blog_entry_text VARCHAR(4000) NOT NULL,
    create_date DATETIME,
    state_id INT
);

-- create a look-up table for your blog entry's state
CREATE TABLE be_state (
     state_id INT NOT NULL AUTO_INCREMENT,
     name CHAR(30) NOT NULL,
     PRIMARY KEY (state_id)
);

-- create a look-up table for your blog entry's tag/s
CREATE TABLE be_tag (
     tag_id INT NOT NULL AUTO_INCREMENT,
     name CHAR(30) NOT NULL,
     PRIMARY KEY (tag_id)
);

-- a table to store multiple tags to one entry
CREATE TABLE blog_entry_tags (
    blog_entry_id INT NOT NULL,
    tag_id INT NOT NULL,
    PRIMARY KEY (blog_entry_id, tag_id)
);

-- a table to store definitions of attributes
CREATE TABLE be_attribute (
    attribute_id INT NOT NULL AUTO_INCREMENT,
    name CHAR(30)
);

-- now have a table to which you can assign multiple attributes to one blog
-- of course, this is if I understand you correctly
-- where you want to have additional attributes
-- aside from the basic properties of a blog entry 
-- and will allow you, if you choose to do it
-- to not necessarily have all attributes for each entry
CREATE TABLE blog_entry_attributes (
    blog_entry_id INT NOT NULL,
    attribute_id INT NOT NULL,
    PRIMARY KEY (blog_entry_id, attribute_id) 
    -- PK enforces one blog entry may have only one attribute of its type
    -- meaning, no multiple attributes of 'location' attribute,
    -- for example, for one blog. Unless of course you wrote half the entry
    -- in one location and finished it in the next.. then you should
    -- NOT enforce this primary key
);
  1. blog_entry - 你的主桌,货物去哪里

  2. be_state - 在此处定义它们,并将它们的state_id 值插入blog_entry.state_id

  3. be_tag - 像我们这里一样有多个标签

  4. blog_entry_tags - 因为一个博客条目可能有多个标签,请将它们存储在这里并将blog_entry.blog_entry_id 和相应的be_tag.tag_id 一起插入。每个博客条目一个其类型的标签。这意味着您不能标记条目#1(例如)标记php 两次或更多次。

  5. be_attribute - 在此处存储属性定义,例如位置、作者等

  6. blog_entry_attributes - 类似于blog_entry_tags,您可以将一个或多个be_attribute 分配给博客条目。

同样,这只是一种方法。

【讨论】:

  • 我知道这是一篇很长的文章,但我希望它能以某种方式帮助你了解如何去做。这只是我现在准备的一个例子,所以它不会做最好的。
  • 谢谢!这真的很有帮助。
【解决方案2】:

首先,状态应该是一个结构紧密的事物,因此您应该为它们创建单独的列。在开始时考虑一下您需要什么,但稍后您可以轻松地再添加一两列。

不应将关键字等标签存储在列中,因为随着时间的推移,数量会迅速增长。那没有任何意义。因此,为此,构建一个包含 id 和关键字的表以及一个包含 post_id 和关键字 ID 的链接表。您也可以省略keyword_id,直接链接post_id 和keyword。 确保结合起来的两列都定义了主键,这样您就不会将一个关键字多次存储到一个特定的帖子中。

对于属性,它可以是相同的。使用attribute_id、attribute_name 和更多信息以及链接表attribute_id 和post_id 和内容来创建属性表并不是一个坏习惯。 您还可以使用 attribute_ids 轻松将其增强为多语言。

评论是相同的,存储在一个单独的表中,其中包含指向用户和帖子的链接:comment_id、user_id、post_id、content 可能还有 parent_id,如果您希望 cmets 再次可评论,则可以是 comment_id。

这就是简要概述。

【讨论】:

  • 谢谢!但是为什么“状态”不能成为它自己的表呢?然后我将与 Post 建立一对一的关系。因为我想象有 10-20 个州......
  • 好的,有一个单独的状态表是没有问题的。我不知道你有多少州。但是,您应该始终关注您的表和连接。获取一篇文章的所有数据意味着从不同的表中检索大量信息。
  • 所以,我知道您使用 mysql 标签发布了问题,因此以下内容与您完全无关,但也许值得考虑使用不同的数据库。如果您不仅要存储帖子,还要存储不同类型的数据(页面、文章等),具有不断变化的设置属性和状态,那么 NoSQL DB(例如 CouchDB)可以作为替代方案。我自己目前正在研究这一点。
  • 谢谢。 “从不同的表中检索大量信息”是不是很糟糕?
  • 一点也不差,但显然比从一小组表中检索数据要花费更多时间。如果您要详细显示一个元素(在这种情况下为帖子),您将看不到它,但如果您想列出您的帖子并需要来自大量连接表的信息而且您必须为 25 个帖子全部检索它们,这可能很耗时。根据需要设置数据库并用大量测试数据填充它是一种很好的做法。然后运行应用程序所需的查询并测量它们(通过解释和实际时间)。
猜你喜欢
  • 2023-03-25
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多