Подскажите способ хранения данных

krafty

new Exception
Подскажите способ хранения данных

Задача такая. Есть первоначальный список элементов - множество A. Пользователь имеет возможность удалять и добавлять новые элементы в этом списке, а само поле содержит лишь некоторое подмножество B множества А.
Объясняю на примере таблицы:

PHP:
id  |  field1 | field2
--- |---------|----------
В поле field2 может содержаться один или несколько элементов множества А, или не содержаться вообще ничего, т.е. В может быть пустым.

У меня была идея использовать тип поля SET(a,b,c,...).
Тогда, чтобы добавить в А элемент 'a', используем запрос
[sql]
ALTER TABLE table1 CHANGE field2 field2 SET('a','b')
[/sql]
Чтобы В было пустым множеством
[sql]
UPDATE table1 SET field2 = NULL WHERE id =1
[/sql]
Заполнение множества B:
[sql]
UPDATE table1 SET field2 = 'a' WHERE id=1;
[/sql]

Есть проблемы:
1. А как же увидеть все элементы множества 'А'? Т.е. каким запросом вывести все элементы a,b,c,...
2. При изменении множества А приходится перечислять все его элементы - это неудобно

Есть вторая идея - использование дополнительной таблицы
 

SelenIT

IT-лунатик :)
Вынести "множество А" в отдельную таблицу и добавить таблицу связей?
 

krafty

new Exception
ну с отдельной таблицей это легко. в ней будет два поля id и element, а в основной таблице в поле field2 будут перечислены id через запятую id из вспомагательной таблицы.
я правильно тебя понял?

ЗЫ. ИМХО через множества рациональней было бы
 

SelenIT

IT-лунатик :)
В отдельной таблице все так. В основной таблице поля field2 вообще не будет, а будет третья таблица, содержащая пары main_id - element_id. Каждому значению из множества будет соответствовать своя строчка в третьей таблице (и, соответственно, в выборке).
 

krafty

new Exception
если я правильно понял, в третей таблице каждому элементу из главной таблицы будет сопоставлятся строка с перечисленными id из таблицы множества А.
тогда вопрос: чем создание дополнительной таблицы лучше создания поля field2 в главной таблице. ведь в этом поле тоже будут перечислены id из множества А.
 

SelenIT

IT-лунатик :)
Нет, для каждого элемента множества А, сопоставленного каждому элементу главной таблицы, будет создана отдельная строчка в таблице связей. Это практически стандартное решение для реализации отношения m:n. Ничего перечислять через запятую вообще нигде не понадобится.
 

krafty

new Exception
т.е. таблица связей будет выглядеть так:

PHP:
ID_A  |  ID_MAIN
--------|------------
  1      |     2
  1      |     3 
  2      |     2
  3      |     2
  4      |     3
  4      |     5
в этой таблице будут только "активные" элементы множества А.
Если необходимо допустим, элементу с ID_MAIN=5 добавить еще несколько элементов из А, то делаем запрос к таблице связей:
[sql]
INSERT INTO table1 SET ID_A=1 ID_MAIN=5

INSERT INTO table1 SET ID_A=4 ID_MAIN=5
[/sql]
 

krafty

new Exception
это на самом деле два запроса:). вообще если приплести сюда реализацию на пхп, то получится примерно так:
PHP:
//$a - массив, содержащий подмножество множества А
foreach ($a as $key=>$v)
  mysql_query("INSERT INTO table1 SET ID_A = $v ID_MAIN = $id_main")
а если в таблице связей будет несколько одинаковых пар. можно конечно проверять перед вставкой на наличие в таблице идентичной записи. но стоит ли? мне кажется можно логигу программы построить так, что бы исключить такую ситуацию, т.е. все проверки заложить при формировании массива $a
 

SelenIT

IT-лунатик :)
krafty
Ты точно не путаешь INSERT и UPDATE? По-моему, тут хватит одного запроса [sql]INSERT INTO table1 (ID_A, ID_MAIN) VALUES (1,5),(4,5)[/sql]который элементарно построить на PHP вообще без циклов (через implode). А одинаковых пар можно избежать, построив уникальный индекс по обоим полям и используя INSERT IGNORE...
 
Сверху