Php 在MySQL中存储两个表之间的分配

Php 在MySQL中存储两个表之间的分配,php,mysql,Php,Mysql,我想知道在mysql中存储两个表之间关系的最佳解决方案是什么 我有以下结构 Table: categories id | name | etc... _______________________________ 1 | Graphic cards | ... 2 | Processors | ... 3 | Hard Drives | ... Table: properties_of_categories id |

我想知道在mysql中存储两个表之间关系的最佳解决方案是什么

我有以下结构

Table: categories

 id   | name           | etc...
_______________________________
 1    | Graphic cards  | ...
 2    | Processors     | ...
 3    | Hard Drives    | ...

Table: properties_of_categories

id    | name     
_____________________
 1    | Capacity
 2    | GPU Speed
 3    | Memory size
 4    | Clock rate
 5    | Cache
现在我需要它们有连接,问题是什么是更好、更高效和更轻的解决方案,这很重要,因为可能有数百个类别和数千个属性分配给它们

我是否应该创建另一个具有如下结构的表

categoryId | propertyId
或者向categories表中添加另一列,并在文本字段中存储属性,如1,7,19,23

或者创建名为example 7.json的json文件,内容如下

{1,7,19,23}

由于这个问题与关系世界有关,我建议添加另一个表来存储类别和属性之间的多对多关系

您还可以使用JSON列在一个表中存储多个值


MYSQL 5.7中引入了JSON数据类型,它具有用于JSON数据检索和更新的各种功能。但是,如果您使用的是较旧的版本,则需要使用字符串列和一些繁琐的字符串操作查询来管理它。

对于关系数据库,第一种解决方案更好。您应该创建一个表,将每个类别与多个属性配对(1:n关系)

您可以这样构造表:

CREATE TABLE categories_properties_match(
    categoryId INTEGER NOT NULL,
    propertyId INTEGER NOT NULL,
    PRIMARY KEY(categoryId, propertyId),
    FOREIGN KEY(categoryId) REFERENCES categories(id) ON UPDATE CASCADE ON DELETE CASCADE,
    FOREIGN KEY(propertyId) REFERENCES properties_of_categories(id) ON UPDATE CASCADE ON DELETE CASCADE
);

主键确保不会有重复的条目,这意味着将一个类别与同一属性匹配两次的条目

所需的结构取决于关系类型:一对多、多对一或多对多(M2M)

对于一对多,“多”侧的外键(FK)将许多项与“一”侧关联。相反,多对一是正确的

对于多对多(M2M),您需要一个完全符合您建议的中间关系(或连接)表。这允许您在任何组合中“重用”类别和属性。然而,它需要2个连接,这稍微多了一点SQL

如果您正在寻找性能,那么使用FKs到主键(PK)将非常有效,查询也非常简单。使用JSON可能需要您在PHP中解析并动态构造第二个查询,这将成倍增加您的编码工作和测试、数据传输、CPU开销,并限制可伸缩性

在您的情况下,我猜“图形卡”和“硬盘驱动器”可能都有“内存大小”和其他属性,因此您需要一个M2M关系表

只要您的键被索引(PK是什么),您对这个关系表的连接就会非常快速和高效

如果对关系使用约束,则可以确保保持数据完整性:不能删除属性“附加”到的类别。从长远来看,这是一个很好的特性

成百上千条记录对于MySQL来说只是一小部分。即使有数百万条记录,你也会使用这种技术。所以不用担心尺寸

RDBMS数据库是专门为此而设计的,因此我建议使用本机特性,而不是尝试自己使用JSON。(除非我缺少一些新的JSON MySQL特性!)


*自从发布这篇文章后,我确实偶然发现了。通过快速阅读,您似乎可以使用JSON和虚拟列键实现各种新的结构和关系,从而消除对连接表的需求。这可能会模糊MySQL作为RDBMS和NoSQL之间的界限。

哇,我刚刚学到了一些新东西。我不知道CASCADE的事。谢谢你的帮助,我会使用你的解决方案。哇,这是一个全面的答案。谢谢,不客气。迪姆卢卡斯的答案是正确的,我只是告诉你更多的“为什么”,这是正确的选择。我会小心级联删除!它们可以工作,但通常需要应用程序逻辑来确保删除是您想要的。