SQL设计问题-多节中的项目
我有一个节表和一个项目表。
问题在于每个项目可能位于一个或者多个部分中,因此每个项目都无法使用简单的" 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