首先要考虑的是您的数据库引擎 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.