Sql проблема дизайна - элементы в нескольких разделах - PullRequest
0 голосов
/ 28 сентября 2008

У меня есть таблица разделов и таблица предметов.

Проблема в том, что каждый элемент может находиться в одном или нескольких разделах, поэтому простой 'section_id' для каждого элемента не будет работать, а в sql нет способа хранить массивы, где я могу сказать "ГДЕ 5 section_ids»...

Я рассмотрел вопрос о сохранении списка идентификаторов в виде строки, разделенной запятыми, проблема в том, что я не вижу способа проверить, находится ли элемент в данном разделе из запроса sql. Единственный вариант, который я вижу здесь, это выбрать всю таблицу и проанализировать строки в php. Излишне говорить, что с тысячами предметов это не очень хорошая идея.

Есть ли лучший способ «связать» элемент с несколькими разделами и иметь возможность легко выбирать все элементы для данного идентификатора раздела?

Ответы [ 9 ]

3 голосов
/ 28 сентября 2008

Вам нужна промежуточная таблица поиска:

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
2 голосов
/ 28 сентября 2008

Чтобы представить отношение многие ко многим, вам нужна таблица поддержки с SectionId и ItemId. Оба должны быть внешними ключами для соответствующих таблиц, а первичный ключ этой таблицы должен быть обоими столбцами.

Из Википедия :

Поскольку большинство СУБД поддерживают только отношения один-ко-многим, необходимо физически реализовать такие отношения через третью соединительную таблицу, скажем, AB с двумя отношениями один-ко-многим A -> AB и B -> AB. В этом случае логический первичный ключ для AB формируется из двух внешних ключей (то есть копий первичных ключей A и B).

0 голосов
/ 28 сентября 2008

Вы можете сохранить несколько идентификаторов в поле, разделенных запятой, а затем использовать команду FIND_IN_SET:

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

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

0 голосов
/ 28 сентября 2008

Вам необходимо сохранить отношение раздела во второй таблице. Вот действительно простой пример:

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

Конечно, во второй таблице вы можете хранить ссылку на третью таблицу «секций», но я исключил это для ясности.

Удачи:)

0 голосов
/ 28 сентября 2008

Вам нужна таблица пересечений, чтобы сидеть между ними, т. Е. Таблица, которая описывает, какие элементы находятся в каких разделах.

Что-то вроде ..

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
0 голосов
/ 28 сентября 2008

Вы говорите об отношениях многих со многими. В нормализованной форме лучше всего работать с третьей таблицей:

items
sections
itemsections

Каждая строка в разделах элементов имеет идентификатор элемента и идентификатор раздела. Для нормальных отношений один ко многим это не нужно, но это стандартная практика для того, что вы смотрите.

0 голосов
/ 28 сентября 2008

Насколько я знаю (но я не опытный разработчик баз данных!), И что я видел в нескольких базах данных, это иметь третью таблицу: она имеет два столбца, один с идентификаторами таблицы разделов, один с Идентификаторы таблицы товаров.
Он создает связь между этими записями без особых затрат, позволяя выполнять быстрый поиск, если вы составляете составной индекс из обоих идентификаторов.

0 голосов
/ 28 сентября 2008

Вам нужна третья таблица, называемая соединительной таблицей, которая обеспечивает отношение N к N с двумя внешними ключами, указывающими на родительские таблицы.

0 голосов
/ 28 сентября 2008

Вам нужна третья таблица itemsPerSection с первичным ключом, состоящим из itemid и sectionid, чтобы вы могли иметь отношение N к N, и поиск по нему очень прост.

Итак:

Items   -   ItemsPerSection   -   Secion
itemid  <->   itemid
             sectionid        <->   sectionid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...