SQL设计问题-多节中的项目

时间:2020-03-06 14:50:47  来源:igfitidea点击:

我有一个节表和一个项目表。

问题在于每个项目可能位于一个或者多个部分中,因此每个项目都无法使用简单的" section_id",并且sql无法在我可以说" WHERE 5 in section_ids"中存储数组。 ..

我曾考虑过将ID列表存储为逗号分隔的字符串,问题是我看不到从SQL查询中检查项目是否位于给定部分中的方法。我在这里看到的唯一选项是选择整个表,然后解析php中的字符串。不用说,拥有1000多个项目并不是一个好主意。

有没有更好的方法来"链接"具有多个部分的项目,并且能够轻松地为给定的部分ID选择所有项目?

解决方案

我们需要第三个表itemsPerSection,其主键由itemid和sectionid组成,这样我们就可以具有N对N的关系,并且非常容易搜索。

所以:

Items   -   ItemsPerSection   -   Secion
itemid  <->   itemid
             sectionid        <->   sectionid

我们需要第三个表,称为联结表,该表提供N到N关系以及2个指向父表的外键。

为了表示多对多关系,我们需要一个带有SectionId和ItemId的支持表。两者均应为各自表的外键,并且该表的主键应均为列。

从维基百科:

Because most DBMSs only support one-to-many relationships, it is necessary to implement such relationships physically via a third junction table, say, AB with two one-to-many relationships A -> AB and B -> AB. In this case the logical primary key for AB is formed from the two foreign keys (i.e. copies of the primary keys of A and B).

我知道的方式(但我不是经验丰富的数据库设计人员!),并且在多个数据库中看到的方式是,拥有第三个表:它具有两列,一列带有sections表的ID,一列带有sections的ID项目表。
它在这些条目之间创建了一个关系,而没有太多的花费,如果我们同时使用两个ID组成复合索引,则可以进行快速搜索。

我们需要一个中间查询表:

CREATE TABLE item_in_section (item_id int, section_id int)

(我在猜测密钥类型,使用适当的密钥类型)。

要查找部分中的项目,请执行以下操作:

SELECT item.* from item, item_in_section WHERE item_in_section.item_id = item.item_id AND item_in_section.section_id = X GROUP BY item_id

要查找项目所属的部分

SELECT section.* from section, item_in_section WHERE item_in_section.section_id = section.section_id AND item_in_section.item_id = Y GROUP BY section_id

我们正在谈论多对多关系。最好使用第三张表以规范化的形式处理:

items
sections
itemsections

itemsections中的每一行都有一个项目ID和一个部分ID。对于正常的一对多关系,这不是必需的,但这是我们要查看的标准实践。

我们需要一个相交表放在两者之间,即描述哪些项目位于哪些部分中的表。

就像是..

CREATE TABLE item_sections (
  ID datatype
  ITEM_ID datatype,
  SECTION_ID datatype);

然后,我们需要联接表以取出数据。

SELECT items.*
FROM   items, item_sections
WHERE  items.id = item_sections.item_id
and    item_sections.section_id = the-id-of the-section-you-want

我们需要将部分关系存储在第二个表中。这是一个非常简单的示例:

CREATE TABLE foos (
    id              INTEGER,
    name            VARCHAR
)

CREATE TABLE foo_sections (
    foo_id              INTEGER,
    section_name        VARCHAR,
)

-- Add some 'foos'
INSERT INTO foos (1, 'Something');
INSERT INTO foos (2, 'Something Else');

-- Add some sections for each 'foo'
INSERT INTO foo_sections (1, 'Section One');
INSERT INTO foo_sections (1, 'Section Two');
INSERT INTO foo_sections (2, 'Section One');

-- To get all the section names for a specific 'foo' record:
SELECT section_name FROM foo_sections WHERE foo_id = 1
> Section One
> Section Two

当然,在第二个表中,我们可以存储对第三个"节"表的引用,但为清楚起见,我将其排除在外。

祝你好运 :)

我们可以在一个字段中存储多个ID,以逗号分隔,然后使用FIND_IN_SET命令:

SELECT * FROM items WHERE FIND_IN_SET(5, section_id);

http://dev.mysql.com/doc/refman/5.0/zh-CN/string-functions.html#function_find-in-set