есть общая таблица obj, в которой все объекты. Разные. есть таблицы с описанием доп полей и самими полями. [sql]CREATE TABLE IF NOT EXISTS `xtra_param` ( `onp_id` int(11) NOT NULL auto_increment, `onp_obj_type` smallint(6) NOT NULL default '0', `onp_name` varchar(30) NOT NULL default '', `onp_descr` varchar(200) NOT NULL default '', `onp_tname` varchar(50) NOT NULL default '', `onp_type` enum('str','ref','func','refx','int','funcint') NOT NULL default 'str', `onp_refname` varchar(50) NOT NULL default '', PRIMARY KEY (`onp_id`), KEY `onp_name` (`onp_name`), KEY `onp_on_holder` (`onp_on_holder`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=79 ; CREATE TABLE IF NOT EXISTS `xtra_value` ( `onv_id` int(11) NOT NULL auto_increment, `onv_obj_id` int(11) NOT NULL default '0', `onv_onp_id` int(11) NOT NULL default '0', `onv_value` text NOT NULL, `onv_moderated` tinyint(1) NOT NULL default '0', `onv_intvalue` int(11) NOT NULL default '0', PRIMARY KEY (`onv_id`), UNIQUE KEY `onv_obj_id_2` (`onv_obj_id`,`onv_onp_id`), KEY `onv_onp_id` (`onv_onp_id`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=247335 ;[/sql] последовательно пришлось наворачивать эту структуру чтобы выполняла что требовалось. enum('str','ref','func','refx','int','funcint') ref _общий справочник, refx - справочник в отдельной таблице, остальное вроде понятно. обработка: вывод: PHP: if($onp_type=="ref") { $tpl->setVariable($onp_tname."_OPT", GetRefName($onv_value)); elseif($onp_type=="func") { $tpl->setVariable($onp_tname, $onp_refname($obj_id,$onv_value,'0')); } elseif($onp_type=="funcint") { $tpl->setVariable($onp_tname, $onp_refname($obj_id,$onv_intvalue,'0')); } ... обновление: PHP: $xtras=array(); $sql=" select onp_name,onp_type from "._XTRA_PARAM_TBL." xp "; $q=xquery($sql,__FUNCTION__); while ($row=mysql_fetch_assoc($q)) { $xtras[$row['onp_name']]=$row['onp_type']; } foreach ($params as $field=>$value) { ..... if($new != $old)) { $zsql="insert into "._XTRA_VALUE_TBL." (SELECT null,'".$on_id."',onp.onp_id, '',0,'".$new."' FROM "._XTRA_PARAM_TBL." onp WHERE onp.onp_name = '".$field."' and onp.onp_obj_type='".$params['on_obj_type']."' ) on duplicate key update ".$fname."='".$new."', onv_moderated=0"; .... } } Поиск: вложенный запрос and obj_id in(select onv_obj_id ...) вопросы собственно кто какие проблемы с такими структурами имел и какие альтернативы.
для каждого типа объекта - своя таблица. по хорошему каждая таблица должна быть максимально однородна.
нюню. для добавления товара, у которого параметр - децибеллы вместо метров, надо вызывать программиста?
если программист это заранее не предусмотрел - да в этой ситуации достаточно вынести все параметры в отдельную таблицу: идентификатор параметра, идентификатор товара, значение идентификатора. также для особо продвинутого каталога можно добвить поле "отношение", в которое может принимать значения: равно, неравно, больше, меньше.
начнем с простого: [sql]# CREATE TABLE IF NOT EXISTS `xtra_value` ( # `onv_id` int(11) NOT NULL auto_increment, # `onv_obj_id` int(11) NOT NULL default '0', # `onv_onp_id` int(11) NOT NULL default '0', # `onv_value` text NOT NULL,[/sql]
4 таблицы описывают модель (классы). 2 таблицы хрянят объекты я для простоты храню все в TEXT и не парюьсь. реальный проект www.art-index.org 16000 объпектов около 200000 записей и работает. все довольны. могу пустить внутрь. стучитесь в личку.
например, в попытке самому изложиь и лучше понять ситуацию ))) балансирую между упрощением работы за счет унификации и усложнением за счет сложности структуры. все виды объектов у меня обрабатываются одной функцией, различия в обработке минимальны. Вопрос в реализации функционала. Конкретно например хочется вынести в xtra поле с соотношением один ко многим, то есть несколько строк из справочника соответствуют id, лежащему в xtra и вести по ним поиск, в том числе лайком. что-то типа [sql]select * from obj where obj_id=onv_obj_id and onv_intvalue=onv2ref.onv_id and onv2ref.ref_id=ref.id and ref.value like...[/sql] и как организовать onv2ref, одну на всех? Все это легко, пока не накладывается несколько условий поиска друг на друга.
я тоже, до тех пор пока по ним не стало необходимо искать и использовать индексы. Теперь разделил на value и intvalue.
http://php.ru/forum/viewtopic.php?t=5895 хмм. serialize($object) включая доп поля? и в основной таблице? а все доп. поля нужны только для формирования структуры?
Мое имхо - не стоит в одну таблицу сваливать разнородные данные, надо разносить по разным таблицам, по крайней мере разделить объекты на группы однотипных и для каждой группы сделать по таблице. Но если уж все запихали в одну таблицу - ну ничего страшного, если в поле хранится NULL то физически это поле занимает 0 байт, т.е. особых потерь в месте не будет. Идея с serialize мне не нравится - потом ничего не найдешь, и руками такие "данные" не поправишь. P.S. Вот к чему приводит ORM - раньше программист хотя бы над структурой таблиц думал, а теперь пытается все свалить в одну кучу, и хоть трава не расти :twisted:
нет, тут не так. Данные хранятся разделенными по полям и названиям, но для кеша их же дубль в таблице. Скажем сложный адрес (справочники городов, улиц, направлений, дома-квартиры и т.п.) в отдельной таблице и его же актуальная копия одной строкой в объектах - потому как для вывода таблицы нужна только она. Обновление идет по всем таблицам и после этого собрать_и_кучкой_в_объекты() а сейчас "программист" не то что над структурой думает, а не знает что такое индекс.