【问题标题】:concat tables with different content具有不同内容的连接表
【发布时间】:2010-07-19 19:23:08
【问题描述】:

我目前正在构建一个使用 PHP 和 MySQL 发布故事的小型 Web 应用程序。每个故事可能是一篇文章(包含大量字段和数据)、只是一个超链接/网址、只是一张图片或具有某些属性的可下载文件(同样包含很多字段)。

我的问题与寻找系统的最佳数据库布局有关。我考虑了 3 种不同的解决方案,它们可能有效,也可能无效(字段只是示例,不要纠结于数据是否应该存储在数据库中):

1) 为每种类型制作一个表,然后将它们联合起来。例如:

文章
id | date | title | author | preview | last_edited | category | content

超链接
id | date | title | author | url

图片
id | date | title | author | thumbnail | fullimg

文件
id | date | title | author | filetype | filename | filecontent

是否可以创建一条 SQL 语句,以这样的方式连接这些字段,将每个字段添加到各个表的行中,并且根据其来自哪个表的类型,将各个行“标记”其类型?还是我必须只满足于公共字段(每个表的 3-4 个字段将是相同的)和每行的单独查找?

2) 制作某种索引表,根据类型引用正确的表和行?

索引
id | type | title | date | referenceid -> 文章、超链接、图片或文件,具体取决于“类型”字段。

在使用外键时,这是否可能以某种方式实现?我怀疑没有,但不确定在 MySQL 中可以做什么和不可以做什么。

3) 将所有类型的所有字段放在同一个表中,并将特定字段设为可空(我不太喜欢这种解决方案,因为它看起来很乱)。

有什么想法吗?

我怀疑我不可能是第一个遇到根据某种类型引用不同实体类型/字段问题的人。

非常感谢您的想法。

【问题讨论】:

    标签: php sql mysql database database-design


    【解决方案1】:

    如果你命名字段,你可以很容易地联合起来,并输入你喜欢的任何常量。我一直这样做:

    Select id, 'articles' as tablename, title, author, 
        preview, last_edited, category, '' as url
    from articles
    UNION
    Select id, 'hyperlinks' as tablename, title, author, 
        '' as preview, '' as last_edited, '' as category, url
    From hyperlinks
    ...
    

    【讨论】:

    • 以这种方式解决它会有什么性能损失?我非常有兴趣找出可能的解决方案的不同优点和缺点。
    • UNION 本身就很慢。对于 SQL Server,UNION ALL 快得多 - 不确定 mySQL。但与数据库的其他一切一样,性能依赖于太多的因素来隔离。除非您正在处理大量数据,否则我不希望此查询成为瓶颈。
    【解决方案2】:

    我建议添加一个stories 表作为中心表。这为系统设计提供了极大的灵活性,并集中了故事的核心数据。

    类似的东西:

    stories
        id
        date
        title
        author
        article_id
        hyperlink_id
        picture_id
        file_id
    
    articles
        id
        preview
        last_edited
        category
        content
    
    hyperlinks
        id
        url
    
    pictures
        id
        thumb
        full
    
    files
        id
        filetype
        filename
        filecontent
    

    【讨论】:

    • 如果article_id 与该特定条目不相关,这不会有外键和类似问题吗?
    【解决方案3】:

    你的字段这么少,把它们都放在一个表中,然后添加一个类型字段。没有必要把事情复杂化。

    【讨论】:

      【解决方案4】:

      我会在每个表中添加一个“类型”列,指定它来自哪个表,然后执行一个等值连接,然后是一个组:

      SELECT *
      FROM articles a INNER JOIN hyperlinks h
          ON a.id =h.id AND a.date=h.date AND a.title=h.title AND a.author=h.author
          JOIN pictures p ON h.id=p.id AND h.date=p.date AND h.title=p.title AND h.author=p.author JOIN files f
          ON p.id=f.id AND p.date=f.date AND p.title=f.title AND p.author=f.author
      ORDER BY type;
      

      这是一个丑陋的查询,但它应该做你想做的......

      【讨论】:

      • 以这种方式解决它会有什么性能损失?
      猜你喜欢
      • 2016-09-02
      • 1970-01-01
      • 1970-01-01
      • 2015-06-07
      • 2015-01-24
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多