В общем, просто жму руку Мы идем по одной дороге Кстати, сразу такой вопрос, в случае EAV архитектур пробовал с помощью view привести к какой-то plain таблице? Интересует примерно следующее - в случае если я вставлю новую запись с новым аттрибутом, в результате view легко ли получить новый столбец не меняя кода самого view? Я просто даже не заморачивался этим вопросом, посколько массово не применял EAV.
Вообще view не очень удобно, так как кроме view еще нужно написать тригер, который нормально отработает запись во все таблицы - это в случае если у нас модель поддерживает save(). Но реально мне приходилось делать вьюшки только для read-only моделей и то эти случаи можно пересчитать по пальцам, а и в принципе даже они - от лени. В большинстве случаев - одна модель - одна таблица. Все связи реализуются моделями (в них прописаны эти связи и датамапер уже сам строит необходимые join-ы). Если я правильно понимаю суть EAV и суть вашего вопроса - то теоретически с помощью вьюхи можно попробовать извлечь структурированные данные из поля, разбить их и представить в виде колонок вьюхи, но все это зависит от реализации EAV. В конце концов всегда можно написать функцию для базы. Опять же, если я правильно понимаю суть EAV - у нас используется нечто подобное в одной модели - очень много данных, но реально выборка из базы осуществляется по не более десятку из них. Остальные данные мы запихиваем в одно поле той же таблицы в формате hstore - это расширение для postgres позволяющее хранить хеши (ассоциативные массивы), т.е. опять же избегаем тут создание дополнительных таблиц. Реализация объедиения данных и их разделения при записи модели - вся внутри модели (тут, увы, пришлось перечислить поля базы внутри модели).
Теоретически и я знаю что можно. Меня интересовало практически Вот кстати про update я и забыл. Так что, возможно, набор из 4х функций в базе будет единственной альтернативой логике в приложении. Жаль. Но бывает Да, это частный вариант где можно использовать EAV. Только не данных много, а аттрибутов много Ключевой момент этот десяток полей не константен, а варьируется от записи к записи Т.е. у нас sparse matrix - разреженная матрица. В остальных случаях EAV слишком много логики перекладывает на приложение вместо БД. Хотя им и любят по-началу и неопытности строить всякие интернет-магазины но TCO для таких решений получается хуже. Это как раз причина, по которой не стоит EAV использовать везде. Контроль целостности данных и прочее все надо писать ручками а это нудно и долго. Хотя в начале кажется, что легко.
Восполнил как сделано у нас. Все же дополнительная таблица есть - она хранит в себе список атрибутов, указатель на то - куда атрибут сувать - в поле базы или же в общий массив, дефаултные значения ну и дополнительную информацию всякую. В принципе, эту информацию можно было бы перенести массивом в модель, но получилась бы большая простыня ну и для удобства управления все же решили в базу. В модели эта вспомогательная таблица просто выгребается вся запросом в БД. Не очень красивый вариант, но решили хоть тут не вводить модель этой доп.таблицы и плодить еще сотни объектов только ради красоты. Возможно еще и переделаем =) Десяток полей - он у нас все же константен, ибо по ним осуществляется выборка и эти признаки есть у каждой записи априори. А те атрибуты - которые могут быть - могут не быть - они уже валятся массивом в hstore. В принципе postgres позволяет строить индексы по hstore что бы легко делать выборки по ключам массива - т.е. могли и отказаться от того десятка полей, но это опять же усложнило билдер, ну и все же верится, что индексы просто по полям - оно быстрее будет.
TheShock короче мы нервно курим в стороне. Simpliest Блин. Объясни мне, неопытному, в чём прикол: PHP: <?php $model->filter('id', function ($val) {return $val >5}); Код (Text): function ($val) {return $val >5} - это то, что должно выполняться в filter() ? Если да, то почти так и делается!!! А вообще я думаю билдер не рашает кроссбазность, но как приянтно написать, что то типа PHP: <?php $UserFilter = new QueryCondition(); $UserFilter->SetLeftObject(new QueryField(new QueryTable(USER_TABLE), 'user_id')); $UserFilter->SetRigthObject(new Qeuryoperator(Qeuryoperator::EQUAL)); $UserFilter->SetRightObject(new QueryValue($UserId, Db::FormatInt)); и валить во все запросы? Что это не вкусно? Или создать модель комментария одним методом: PHP: <?php class Comment extends SObject { /** * @param int $iCommentId */ public function __construct($iCommentId = NULL) { parent::AddProperty('Published', 'dtcreate'); parent::AddProperty('Body', 'tbody'); parent::AddProperty('UserId', 'user_id'); parent::AddProperty('NodeId', 'node_id'); parent::AddProperty('Author', 'author'); parent::Initialize(COMMENT_TABLE, $iCommentId); } } Причем нет там ORM-а. Просто билдер с рюшиками и всё!!!
kostyl Вот демонстрируется основная проблема билдеров - где остановиться. Например, сравниваем "=" и "new Qeuryoperator(Qeuryoperator::EQUAL)". Стоит оно того? Имхо, после любования на такую вот конструкцию и переходу к написания реальных приложений - дальше будет только мат. А уж объем документации для всех несчастных, кому придется с этим потом столкнуться... да не будет этой документации, правда? Значит мата будет еще больше =) Если забыть об ORM, как промежуточный вариант, с которым я столкнулся при работе с формум Инвижн, можно использовать такую штуку: 1. Простой билдер. Даже без джойнов. Основные операции выборки, апдейта, удаления. 2. Классы с готовыми сложными sql запросами. Это позволяет держать весь написанный sql в одном месте (для удобства адаптации к другой базе, к примеру) и не усложнять билдер. Но в общем, это никакого отношения к API не имеет =))))
да, я очень долго думал, писать эту хрень или нет. В первой версии было просто '=', ровно как 'AND'. Но потом написал, поюзал, и понял что надо бы откатить.. ))) А простой билдер - я так не могу, мне джоины нужны. Без них фигово вообще. А что эта ветка про API форума? А я думал про билдер )))
Это алгоритм(впрочем не весь, часть алгоритма лежит в самом filter()) по которому будут выбираться записи. В приведенном мной примере предполагается, что оно возвращает лишь true/false. Прикол именно в разнице декларативных и императивных языков. В примере приведенном мной, указывается как брать. Я пишу алгоритм выбора на привычном языке и callback позволяет мне это сделать. В случае SQL я указываю что надо взять. И билдерами вы симулируете это поведение. Не зная SQL пользоваться билдерами будет очень сложно. Я просто помню - как туго до меня доходило понимание принципа работы SQL. Рекурсию в чистом SQL-92 не пробовал? А в моем примере - играючись, поскольку язык это позволяет. А ОРМ вообще создает 100ни моделей одной строкой из схемы базы Код (Text): build stubs А уж набрать структуру в YAML, а еще лучше нарисовать в DIA/MySQLWorkbench и автоматом! одним движением получить готовый код моделей... Слабо? MiksIr прав, в реальных сложных приложениях с сотнями таблиц, где таблицы легко могут иметь десятки и сотни полей... все будет не так радужно В свое время я от EAV пищал... потом писк прошел и пришло понимание геморроя при неуместном(читай повсеместном) его применении. Универсальные решения - работают хреново. И работать с ними не так легко, как казалось вначале. Для стандартных решений конкретно твой билдер избыточен. Проще написать десяток - другой запросов. Да, он хорошо подойдет в ОРМ. Но тогда уж проще использовать готовую ОРМ. В общем - пиши, просто пиши. Через это надо перешагнуть. Это как езда на велосипеде. Я не знаю как тебе еще объяснить.
Simpliest Я понял, у нас разные головы, у тебя одна - у меня другая. Но я лучше сам запросы буду писать, чем ОРМ за меня. Не знаю, может я и не сталкивался с такими задачами но я лучше начну ближе к низу чем к верху. Ты правильно говоришь - универсальные решения работают хреново, но билдер - не универсальное решение. И срал я в принципе какой язык испльзую декларированный или императивный, я пишу и всё тут. И вообще тут каждый все рано останется при своем мнении, так что предлагаю постепенно перейти к основной теме.
Так то генератор, а то билдер. Билдером я сам делаю. А генератор из структуры бд генерирует. Не надо путать, не надо.
Ну это что-то вроде "я лучше функции писать буду, чем какие-то объекты". В общем, каждому свое применение, конечно... А что, думаете запросы написанные самим будут быстрее работать? =)
Как-то проблематично из структуры БД нагенерировать что-то большее чем DDL запрос А его гораздо утобнее генерировать вот такими инструментами.
Да генерируйте, ради Бога, но я пока сам в состоянии написать. По крайней мере не было таких структур на моем пути, для которых нельзя было самостоятельно сделать запрос. И чем больше сущьностей учавствуют в запросе, тем лучше мозгом его написать. ИМХО
тупо риторический вопрос: ну и на каком api сошлись после 5-ти страниц обсуждения? Хотя не, даже так: вы ваще api обсудили?))
Насчет API тут спорный вопрос, давать ли возможность пользователю API внедрить свои реалзации работы с БД. API должно быть простым и полнофункциональным и совместимым, возвращать данные простыми типами.