0

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

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

我有一个表来存储项目:

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

项目

  • ID
  • 名称(仅管理员可读)
  • 标题(供访客阅读的标题)
  • 描述
  • 日期(项目完成的日期)
  • 已发布(项目发布时的时间戳)

然后我需要标签:

我想我已经想通了。从研究。

标签

  • tag_id
  • 标签名称

项目标签

  • project_id(外键项目表)
  • tag_id(外键标签表)

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

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

4

3 回答 3

0

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

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

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

于 2013-02-18T18:39:20.277 回答
0

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

那将是更高效的数据库(更少的连接)。

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

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

于 2013-02-18T18:45:27.300 回答
0

首先要考虑的是您的数据库引擎 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。这是您的表格及其对应关系的图表。

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

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

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

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

EMPLOYEE
id 主键
名称 VARCHAR(100)
Salary_id NOT NULL UNIQUE

SALARY
id PRIMARY KEY
金额 INTEGER NOT NULL

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

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

关于直接解决您的问题,您将需要创建一个单独的媒体类型表,如果项目所在的位置存在任何可能与多种类型相关联,您将需要一个间歇性表,并可以将一个字段添加到名为 primary_type 的 project_media_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}

这需要在一个递归函数中,所以你循环直到没有更多的孩子。可以在递归函数类别数据库中查看与层次类别相关的使用 PHP 的示例。

I hope this helps and know it's a lot but essentially, I tried to highlight a whole semester of database design and modeling. If you need any more information, I can attach an example ERD as well.

于 2013-02-18T19:09:37.550 回答