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

时间:2016-05-25 10:31:44

标签: php mysql

我想知道在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

或者可能在类别表中添加另一列,并在文本字段中存储属性,如1,7,19,23

或者也许创建名为例如7.json的json文件,内容如

{1,7,19,23}

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:2)

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

对于一对多,'many'侧的外键(FK)将许多项目与'one'相关联。反之亦然,多对一。

对于多对多(M2M),您需要完全按照建议使用中间关系(或联结)表。这允许您以任何组合“重用”类别和属性。然而,它稍微多一些SQL - 需要2个JOIN。

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

在你的情况下,我猜测“显卡”和“硬盘驱动器”可能都有例如“内存大小”加上其他属性,因此您需要建议的M2M关系表。

只要您的密钥被编入索引(PK是哪个),您对此关系表的加入将非常快速有效。

如果您在关系中使用CONSTRAINT,那么您可以确保维护数据完整性:您无法删除属性“附加”的类别。从长远来看,这是一个很好的功能。

数以千计的记录对于MySQL来说是微不足道的。即使有数百万条记录,您也会使用此技术。所以不用担心尺寸。

RDBMS数据库专门用于执行此操作,因此我建议使用本机功能,而不是尝试在JSON中自行完成。 (除非我错过了一些新的JSON MySQL功能!*)

*自发布以来,我确实偶然发现了a new JSON MySQL feature。从快速阅读看,似乎可以使用JSON和虚拟列键实现各种新结构和关系,可能不需要连接表。这可能会模糊MySQL作为RDBMS和NoSQL之间的界限。

答案 2 :(得分:1)

关于关系数据库,第一种解决方案更好。您应该创建一个表,将每个类别与多个属性(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
);

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