Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: поля с параметрами, разделенными запятыми или несколько таблиц?
 
 автор: exc   (06.05.2011 в 08:57)   письмо автору
 
 

Здравствуйте!
Планирую БД, решил спросить совета.
Есть конфигурационный файл с тремя массивами:
(в каждом массиве до 15 четко определенных элементов)

// Города:
$gorod['1'] = "Город 1";
$gorod['2'] = "Город 2";
$gorod['3'] = "Город 3";
...
$gorod['15'] = "Город 15";

// Род деятельности:
$rd['1'] = "Деятельность 1";
$rd['2'] = "Деятельность 2";
$rd['3'] = "Деятельность 3";
...
$rd['15'] = "Деятельность 15";

// Категории:
$category['1'] = "Категория 1";
$category['2'] = "Категория 2";
$category['3'] = "Категория 3";
...
$category['15'] = "Категория 15";


- Это возможные "наборы свойств" компании.
Каждая компания может иметь несколько (3-5-7) свойств из каждого из трех наборов.

Предполагаю примерно следующую таблицу company:
id INT
name TINYTEXT
gorod TINYTEXT
rd TINYTEXT
category TINYTEXT
...


В форме добавления записи (компании) в таблицу из массивов формируются наборы чекбоксов (или multiple select -ов).
При формировании запроса INSERT формируются 3 строки, например:
$gorod = ",1,4,12,";
$rd = ",7,8,";
$category = ",3,5,6,15,";
и заносятся в базу (строки с числами, с обоих сторон окруженными запятыми (или любыми другими разделителями)).

Планируются следующие варианты использования:
1 - отображение информации о компании с указанием городов, родов деятельности и категорий, к которым она причастна
Это, полагаю, несложно, и данная реализация хранения в бд (строка с разделителями) оправдана.?
2 - Участие в выборке - например, "вывести все компании, причастные к городу Y, с родом деятельности X" или "вывести все компании категории Z".
Вот здесь я теряюсь в догадках - неужели правильнее/оптимальнее организовать это с помощью пачки дополнительных таблиц (таблицы с массивами свойств плюс связывающие)?
Или использовать LIKE (1 запрос к 1 таблице при любом условии)?

  Ответить  
 
 автор: cheops   (06.05.2011 в 09:06)   письмо автору
 
   для: exc   (06.05.2011 в 08:57)
 

Намаетесь с такой базой данных, особенно при редактировании. Лично я бы под Города, Род деястельности и Категории выделил бы отдельную таблицу вида
id_city name
1 Город 1
2 Город 2
...
3 Город 3
Плюс еще ввел бы четвертую таблицу (я так понимаю для компаний), которая бы связывала бы Города, Род деятельности и Категории
id name id_city id_rd id_category

Вам базу данных редактировать будет проще и работать она будет на порядок быстрее, так как вы будете оперировать цифрами-связями, а не строками.

  Ответить  
 
 автор: exc   (06.05.2011 в 10:09)   письмо автору
 
   для: cheops   (06.05.2011 в 09:06)
 

Вот спасибо! :-)
Теплилась надежда услышать в ответ "Да, вариант с одной таблицей и LIKE при выборке подойдет".

А если серьезно - пока для меня проще помаяться при редактировании (вывод чекбоксов через foreach из массивов конфига, explode-implode).
А с многотабличной выборкой, да еще и при различных условиях...

Но вопрос я задавал, в первую очередь беспокоясь о производительности.
Отсюда просьба - не направите ли вы ход моих мыслей к дальнеишим действиям?
Уточню условия. Основная таблица - компании. Компания имеет различные поля - имя, адрес и т.д., в числе которых и планировались эти три - город, деятельность и категория, и как раз они предполагаются с множественным выбором.
Теперь таблицу разбиваем на 5:
- компании (ид, имя, адрес, телефон и пр.) - (основная таблица, теперь без полей город, деятельность и категория)
- город (ид, город)
- деятельность (ид, деятельность)
- категория (ид, категория)
- связывающая (ид, компания_ид, город_ид, деятельность_ид, категория_ид)
Так?

Как при этом могут выглядеть запросы:
- на добавление/обновление записи компании с учетом, например, одного города, трех видов деятельности и двух категорий? (понятно, что наборы чекбоксов также несложно сформировать из таблицы)
- отображение нужной компании с указанием города/ов, деятельности/тей, категории/ий к которым она причастна?
- выборка компаний для определенного города, деятельности и категории?

У самого на этот счет только нечленоразборчивая каша в голове. (INSERT INTO компании, связывающая VALUES ... JOIN... ON... ?, SELECT * FROM компании JOIN ...WHERE компании.ид = какиенибудь другие ид из других таблиц...? )

Да, и уточню количество записей в таблицах:
- компании - не более 500 (реально - порядка 200)
- города, деятельности и категории - до 15

  Ответить  
 
 автор: Lotanaen   (06.05.2011 в 10:32)   письмо автору
 
   для: exc   (06.05.2011 в 10:09)
 

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

  Ответить  
 
 автор: exc   (06.05.2011 в 10:42)   письмо автору
 
   для: Lotanaen   (06.05.2011 в 10:32)
 

Да, если по одному значению, то проблем нет, но необходим множественный выбор. Например, одна компания может вести деятельность на территории нескольких городов, иметь несколько направлений деятельности и соответствовать нескольким категориям.

  Ответить  
 
 автор: Lotanaen   (06.05.2011 в 10:52)   письмо автору
 
   для: exc   (06.05.2011 в 10:42)
 

а как много разнообразий в будущем возможно для городов, видов деятельности и т.п. доп данных? т.е. сейчас ваши массивы статичны или динамичны?

  Ответить  
 
 автор: exc   (06.05.2011 в 11:09)   письмо автору
 
   для: Lotanaen   (06.05.2011 в 10:52)
 

Сейчас они статичны и имеют по 8 разнообразий каждый. Ранее я говорил, что их число до 15 (брал с запасом), но в настоящий момент по 8 и изменений не планируется.

  Ответить  
 
 автор: Lotanaen   (06.05.2011 в 11:21)   письмо автору
 
   для: exc   (06.05.2011 в 11:09)
 

ну если их в будущем никогда не будет более 30, то как вариант могу предложить работать с массивами, а в таблице компаний сделать соответствующие поля типа bigint и в них применить так сказать двоичную систему... т.е. сумму двоек в степенях ключей массивов. тогда никаких доптаблиц не понадобится

  Ответить  
 
 автор: exc   (06.05.2011 в 12:02)   письмо автору
 
   для: Lotanaen   (06.05.2011 в 11:21)
 

Да, думаю что даже более 15 их никогда не будет. Например, города это муниципалитеты некоего района. А как часто в районах тусуются или добавляются/удаляются муниципалитеты? Поэтому эти три "набора свойств" компании - города, деятельность и категория - достаточно статичные и практически неизменные величины, почему я изначально и не планировал заносить их в бд и выделять отдельные таблицы. Если бы их число или названия менялись, то несомненно было-бы логично засунуть их в бд и организовать удобный интерфейс управления. Но ход моих мыслей был таков - засунуть их однажды в конфиг и использовать в режиме чтения, и, возможно, раз в год и придется что-то добавить ручками.

А "сумму двоек в степенях ключей массивов" это как? (если возможно, с примером) И как заносить и выбирать их?

У меня была мысль ключи в двоичной системе, правда в режиме ноль/единица (например, есть 8 городов в списке - имеем 8 активных бит поля "город" в таблице компаний, и если у компании отмечены 3 и 5 города - 3 и 5 бит единицы, остальные нули. Как то так.), а не двоек в степени ключа. Как формировать представляю, а как выбирать - пока нет. Например, как выбрать все компании, у которых 3й бит (или 3й и 5й) в поле "город" - единица.

  Ответить  
 
 автор: Lotanaen   (06.05.2011 в 12:22)   письмо автору
 
   для: exc   (06.05.2011 в 12:02)
 

ну в принципе тот же двоичный принцип, только не 1 и 0 пишем в таблицу:
вывод формируем примерно так:


foreach ($gorod as $key=>$value) {

   if ($town & pow(2,$key)) //$town - значение город из таблицы компаний
      echo $value;
}

update в таблицу(аналогично и для вставки) :

$arraytown = array (1,3,5);// массив ключей из массива $gorod, которые соответствуют компании
$town=0;
foreach ($gorod as $key=>$value) {

   if (in_array($key,$arraytown))
      $town+= pow(2,$key);
}

$sql = "update comp set gorod=$town where id=$id";
$res = mysql_query($sql);

  Ответить  
 
 автор: Lotanaen   (06.05.2011 в 12:47)   письмо автору
 
   для: exc   (06.05.2011 в 12:02)
 

а выборку в таблице аналогично:

$sql = "select * from comp where gorod & ".pow(2,3).">0";
$res = mysql_query($sql);

  Ответить  
 
 автор: exc   (06.05.2011 в 13:01)   письмо автору
 
   для: Lotanaen   (06.05.2011 в 12:47)
 

Большое спасибо за разъяснения.
А как теперь при отображении информации о компании выяснить города, к которым она относится?

И по ходу дискуссии у меня возник вопрос - неужели LIKE так плох? Или просто в данном случае неуместен?

  Ответить  
 
 автор: Lotanaen   (06.05.2011 в 13:21)   письмо автору
 
   для: exc   (06.05.2011 в 13:01)
 

>А как теперь при отображении информации о компании выяснить города, к которым она относится?

Вот этот код приведенный мною раньше:
foreach ($gorod as $key=>$value) {

   if ($town & pow(2,$key)) //$town - значение город из таблицы компаний
      echo $value;


>И по ходу дискуссии у меня возник вопрос - неужели LIKE так плох? Или просто в данном случае неуместен?

like не будет всегда точен (например: Новгород и Нижний Новгород - как правильно выбрать Новгород?) и работает медленее.

  Ответить  
 
 автор: exc   (06.05.2011 в 13:31)   письмо автору
 
   для: Lotanaen   (06.05.2011 в 13:21)
 

Да, но это если "Нижний Новгород", а в моем варианте - цифровые ключи. Причем окруженные с обеих сторон разделителями. В этом случае даже ;Новгород; и ;Нижний Новгород; всегда выберется верно.
Но в любом случае, спасибо. Буду размышлять.

UPD:
И все-равно не пойму.
Например ключи городов у компании - 1, 3
получаем значение в базу - 10 (2+8)
Как теперь достав из базы 10ку вывести города компании (1 и 3) неужели корнями?

  Ответить  
 
 автор: Lotanaen   (10.05.2011 в 12:56)   письмо автору
 
   для: exc   (06.05.2011 в 13:31)
 

я же привел выше код вывода списка городов...

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования