【问题标题】:Advice on database design for portfolio website投资组合网站数据库设计建议
【发布时间】:2013-02-19 03:09:37
【问题描述】:

所以我是一个视觉设计师类型的人,学习了大量的 PHP 和一点 SQL。

我正在组建一个个人多媒体作品集网站。我正在使用 CI 并且喜欢它。问题是我对数据库设计一无所知,我一直在重写(和破坏)我的表。这是我需要的。

我有一个表来存储项目:

我想对标题和描述进行全文搜索,所以我认为这需要是 MyISAM

项目

  • 身份证
  • 名称(仅供管理员阅读)
  • 标题(供访客阅读的标题)
  • 说明
  • 日期(项目完成的日期)
  • 已发布(项目发布时的时间戳)

那我需要标签:

我想我已经想通了。来自研究。

标签

  • tag_id
  • 标签名称

PROJECT_TAGS

  • project_id(外键PROJECTS TABLE)
  • tag_id(外键TAGS TABLE)

这是我有四种媒体类型的问题;相册、Flash 应用程序、打印件和网站设计。没有项目可以有两种类型,因为(除了一种例外)它们都需要在视图中显示不同的逻辑。我不确定是否将媒体类型 in 放入项目表并直接加入类型表 使用中间表来定义标签等关系。我还考虑了父类型/子类型,即;博客、项目 - Flash、项目 - 网络。我真的很感激一些方向。

也可能对如何使用给定解决方案有效地查询项目提供一些帮助。

【问题讨论】:

    标签: php mysql database codeigniter


    【解决方案1】:

    首先要考虑的是您的数据库引擎 MyISAM。数据库引擎是 MySQL 存储数据的方式。有关 MyISAM 的更多信息,您可以查看:http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html。如果你想拥有引用完整性(推荐),你希望你的数据库引擎是 InnoDB (http://dev.mysql.com/doc/refman/5.0/en/innodb-storage-engine.html)。 InnoDB 允许您创建外键并强制执行该外键关系(我发现 MyISAM 没有这样的困难方式)。 MyISAM 是 MySQL 数据库的默认引擎。如果您使用 phpMyAdmin(这是 MySQL 和 PHP 开发的强烈推荐工具),您可以轻松更改数据库的引擎类型(参见:http://www.electrictoolbox.com/mysql-change-table-storage-engine/)。

    话虽如此,搜索或查询可以在 MyISAM 和 InnoDB 数据库引擎中完成。您还可以索引列以使搜索查询(SELECT 语句)更快,但代价是 INSERT 语句将花费更长的时间。如果您的数据库不是很大(即数百万条记录),您应该不会看到明显的差异。

    就您的设计而言,有几件事情需要解决。首先要了解的是实体关系图或 ERD。这是您的表格及其对应关系的图表。

    可以存在几种类型的关系:一对一关系、一对多关系、多对多关系以及分层或递归关系。多对多关系是最复杂的,不能直接在数据库中产生,必须用间歇性的表来解决(我会用例子进一步解释)。

    一对一的关系很简单。例如,如果您有一个包含所有员工列表的员工表和一个包含所有薪水列表的薪水表。一名员工只能拥有一份薪水,一份薪水只能属于一名员工。

    话虽如此,要添加到组合中的另一个元素是基数。基数是指关系是否可能存在或必须存在。在前面的员工示例中,工资和员工之间必须存在关系(否则可能不会向员工支付报酬)。这种关系被解读为,一个员工必须有一个且只有一个薪水,而一个薪水可能有也可能没有一个且只有一个员工(因为薪水可以在不属于员工的情况下存在)。

    短语“one and only one”指的是一对一的关系。短语“必须”和“可能或可能不”指的是需要存在或不需要存在的关系。这转化为设计,因为我在员工表中的薪水 id 的外键不能为空,并且在薪水表中没有引用员工的外键。

    员工
    id 主键
    名称 VARCHAR(100)
    Salary_id NOT NULL 唯一

    薪水
    id 主键
    金额 INTEGER NOT NULL

    一对多关系被定义为具有多个关系的可能性。例如,与您的投资组合有关,客户可能有一个或多个项目。因此项目表client_id中的外键字段不能唯一,因为它可能会重复。

    多对多关系被定义为不止一个可以双向。例如,正如您正确显示的那样,项目可能有一个或多个标签,并且标签可能分配给一个或多个项目。因此,您需要 PROJECT_TAGS 表来解决多对多问题。

    关于直接解决您的问题,您需要创建一个单独的媒体类型表,如果项目所在的位置存在任何可能与多种类型相关联的可能性,您可能需要一个间歇性表并可以添加一个project_media_type 表中名为 primary_type 的字段,它允许您将项目类型主要区分为该媒体类型,尽管如果您按类别过滤它可能属于其他类别。

    这让我想到了递归关系。因为您有可能具有递归关系或 media_types,所以您需要添加一个名为 parent_id 的字段。您可以将外键索引添加到 parent_id 引用 media_type 表的 id。它必须允许空值,因为所有顶级父 media_types 的 parent_id 都将具有空值。因此,要选择您可以使用的所有父 media_types:

    SELECT * FROM media_type WHERE parent_id IS NULL
    

    然后,要让孩子遍历每个父母,并可以使用以下查询:

    SELECT * FROM media_type WHERE parent_id = {$media_type_row->id}
    

    这需要在一个递归函数中,这样你就可以循环直到没有更多的孩子。可以在recursive function category database 上查看使用 PHP 与分层类别相关的示例。

    我希望这会有所帮助,并且知道这很多,但本质上,我试图突出整个学期的数据库设计和建模。如果您需要更多信息,我也可以附上一个示例 ERD。

    【讨论】:

    • 哇,教人钓鱼。那里有很多东西。其中一些我已经理解了。但我认为你已经授权我根据我将如何使用这些信息做出自己的决定。我打算在媒体类型和项目之间建立多对一的关系,所以听起来我需要在 Media Types 表中包含 Parent_id 字段,并只需在项目表中添加 type 作为字段,其中 type 或 type_id 作为外部键。
    • 就数据库引擎而言。我被 InnoDB 引擎的优点所吸引,但据我了解,直到 MySQL 5.6 版才可以在 InnoDB 引擎上进行 FULLTEXT 索引。我确定我的服务器正在运行 5.4 的东西。我曾考虑使用标签仅包含“关键字搜索”,但认为提供全文搜索功能更为传统。
    • 关于全文搜索,我认为在您的上下文中没有必要。在我使用电子商务数据库、内部网数据库和投资组合数据库的许多数据库的经验中,从未使用过全文搜索。我认为“关键字搜索”将是最有效的,所有这些都是必要的。 stackoverflow.com/questions/1381186/fulltext-search-with-innodb 提到 MyISAM FULLTEXT 搜索遇到了困难。我很高兴我能提供帮助。此外,您仍然可以搜索描述列,只是不是每个单词都会被索引。
    【解决方案2】:

    另一个可能的想法是向项目表中添加满足所有媒体类型需求的列,然后在编辑数据时只使用给定媒体类型所需的某些列。

    这样数据库效率会更高(连接更少)。

    如果您的媒体类型在您需要的列中差别不大,我会选择这种方法。

    如果差别很大,我会选择@cosmicsafari 推荐。

    【讨论】:

      【解决方案3】:

      你为什么不把所有人的共同点放在一个表格中,然后把特定的东西放在表格中,这样你就可以在一个表格中搜索所有的标题和描述。

      Basic Table
      - ID int
      - Name varchar()
      - Title varchar()
      etc
      
      Blogs
      -ID int (just an auto_increment key)
      -basicID int (this matches the id of the item in the basic table)
      etc
      

      每种媒体类型都有一个。这样,您可以一次搜索所有描述和标题,并在用户单击搜索页面中的链接时加载适当的数据。 (当你说你希望能够让人们搜索时,我认为这就是你所说的那种功能。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 2011-05-01
        相关资源
        最近更新 更多