логика программы. как лучше сделать. класс и класс-список

Phoenix

есть небольшое приложение, отображающее список сотрудников, и формочку для редактирования одного сотрудника.
есть два класса
class person {
private $opt;
public update - обновляет запись в БД.
public sync - читает заново из БД по $opt['id'];
}

class personlist {
private $personlist;
public loadlist($from,$amount) - читает из БД начиная с $from $amount записей и заполняет $personlist
}
возникает вопрос, куда лучше запихнуть общение с БД.(для этого будет свой класс, но запросы всё равно придётся писать в этих)
вариант 1(не нравится):
все функции update, sync, loadlist будут свои запросы мастерить.
update: SELECT name, org FROM person WHERE id=$id;
sync: UPDATE person set name=$name, org=$org WHERE id=$id;
loadlist: SELECT name, org FROM person LIMIT $from, $amount;
вариант 2(ещё хуже):
loadlist делает SELECT id FROM person LIMIT $from, $amount; создаёт по этому id экзепляр $person, потом вызывает $person->update - итого $amount+1 запросов вместо одного.
вариант 3:
всё делает класс personlist:
тогда при редактировании одного сотрудника, придётся создавать список, состоящий из одного сотрудника, что в не очень логично.
проблемы:
если добавить новый параметр, например, возраст $age, то придётся менять все запросы и есть вероятность забыть где-нибудь и возраст не прочитается, но запишется.
ещё при обновлении хотелось бы, чтобы обновлялись только те поля, которые действительно обновились.
в общем, хочется сделать всё достаточно просто и вместе с тем неизбыточно. Потому как потом к этому нельзя будет вернуться и переделать.

0000

А вариант переноса логики общения с БД в саму БД не рассматривается что ли? т.е. когда пишутся хранимые процедуры, возвращающие ответ, а приложение дергает их.
К тому же, ты вроде не озаботился проблемой потерянного изменения: т.е. допустим оператор редактирует запись и долго тупит, а в это время эту же запись быстро редактирует другой оператор, сохраняет и убегает. Тогда первый оператор перетрет данные второго. Хотя я не понял, может у тебя sync за это отвечает, но почему он тогда UPDATE генерит?

Phoenix

А вариант переноса логики общения с БД в саму БД не рассматривается что ли?

думаю, не стоит.
т.е. допустим оператор редактирует запись и долго тупит, а в это время эту же запись быстро редактирует другой оператор, сохраняет и убегает. Тогда первый оператор перетрет данные второго. Хотя я не понял, может у тебя sync за это отвечает, но почему он тогда UPDATE генерит?

я думаю, эту проблему нужно будет решать в sync.
вот именно из-за таких вот проблем и хочется сделать всё в одном месте.

katrin2201

Я честно говоря не очень вдумчиво прочитал, плюс не понял почему в варианте 2 amount+1 запрос вместо одного (что за один запрос такой, что селект и апдейт сделает).
Но вообще проблемы организации кода, работающего с БД, возникают довольно часто, и я знаю по большому счету ровно два "правильных" способа.
1. Суть вариант 1. Ботай паттерн DAO (data access object). Пользоваться с умом, ибо реализовывать его полностью в простых приложениях, особенно где не требуется полной абстракции от типа БД, совершенно не обязательно и избыточно.
2. ORM (object-relational mapping). Это в гугл.
Для задач твоего приложения вторая штука подходит по-моему идеально. Проблема только в том, что если с орм никогда не работал, то начинать достаточно тяжело. Зато потом это окупается.

Phoenix

в варианте 2 amount+1 запрос вместо одного

SELECT id from person limit 10,10;
получает $ar[]
foreach $ar as $id
SELECT name,org from person where id =$id

Maurog

SELECT id from person limit 10,10;
лучше сделай
SELECT id, name, org from person limit 10,10;
остальные операции в памяти сам сделай без обращения к базе.
по поводу классов: сделай все через personList
struct Filter
{
   std::list IDs;
  //TODO: add something useful in the future
};
class PersonList
{
  Person Get(int index)
  int Size
  Update(Filter&)
  Sync(Filter&)
};
Так как приложение небольшое, то ORM лучше не трогать имхо.
зы: надеюсь, С++ стайл понятен человеку, который на другом языке пишет?

Phoenix

намного более понятен, чем php.
SELECT id, name, org from person limit 10,10; - ну это вариант с 1 запросом.
в общем, ты предложил вариант 3, который я выше описывал.
как быть с редактированием одного?
я так понимаю, использовать просто статические методы класса list?
такой способ не нравится только тем, что класс person не самодостаточный, но это не вызывает такого раздражения, как первые два.
ок. на нём и останавлюсь тогда, если не поступят ещё какие-нибудь предложения

slonishka

2. ORM (object-relational mapping). Это в гугл.
http://slonik-v-domene.livejournal.com/10818.html
там и форумчане имеются.

slonishka

на сайентологии имхо менелдор сдох.

slonishka

о, пианист подключилса! :D

tipnote

Так как приложение небольшое, то ORM лучше не трогать имхо.
Все жизнь думал как раз обратное :D

tipnote

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

slonishka

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

katrin2201

Ага, и кроме всего прочего учитывать особенности, в духе того, что например хочется чтобы объекты были версионируемые, или особенность бд такова, что в ней динамически генерятся таблицы, и их тоже хотелось бы как-то маппить, итд итп.
Удел ORM - небольшие-средние проекты, небольшой сложности, не специфические по требованиям.
Повторюсь еще раз, что единственный тормоз при начале использовании ORM - один раз заботать нужную либу. Время на прикручивание ОРМа к новому проекту, при условии изученности либы, стремится к нулю. Бенефитов масса.
Тот же хибернейт в джаве, который сейчас поддерживает стандарт EJB3 - на мой взгляд очень и очень в этом плане вкусен.
Подправить пара конфигов на связку ORM-DataSource, потрудиться проаннотировать существующие модельные классы, и оно даже схему тебе само сгенерит.
Генерит кстати довольно корректно, включая форейн констрейнты и подобные глупости.
Аннотации довольно интуитивные. Навигация по ссылкам и контекстными подсказкам в популярных IDE тоже присутствует.
Сам стараюсь использовать ORM везде, где оно пролазит в требования.

pitrik2

Тот же хибернейт в джаве, который сейчас поддерживает стандарт EJB3 - на мой взгляд очень и очень в этом плане вкусен. Подправить пара конфигов на связку ORM-DataSource, потрудиться проаннотировать существующие модельные классы, и оно даже схему тебе само сгенерит. Генерит кстати довольно корректно, включая форейн констрейнты и подобные глупости.
поддерживаю
не знаю как в сишарпе, но в джаве хибернейт очень даже ничего
трудности с ним ток когда у тебя сложная структура базы

katrin2201

Пытаюсь начать читать статью. Честно говоря, после первого же абзаца не хочется продолжать.
Снижение стоимости разработки путем введения ORM - миф, с реальностью не имеющий никакой связи. Почему так? Очень просто. Используя ORM вы вынуждены делать одну и ту же работу дважды: сначала проектировать БД и запросы к ней (клинические случаи, когда программист не знаком с EXPLAIN и в глаза не видел БД, не рассматриваем а потом - переводить запросы из plaintext в ORM вид. При этом не факт что более-менее сложный запрос вообще будет возможно перевести. Практика показывает что даже простейшие запросы некоторые ORM раскладывают черт знает во что.
ORM и была введена для того, чтобы в идеале никогда больше не писать SQL код. Чтобы строить свои запросы не от SQL, а от объектной модели. Чтобы можно было ходить по связям в бд не отдельным запросом/джойном, а просто обратившись к полю объекта.
А автор переворачивает все с ног на голову, а потом удивляется, почему же все так криво.

slonishka

да там коменты ржачные.
btw, я просто запостил, чтоб вы такие грустные не были.
обсуждать-то смысла нет, религия, чо там.

slonishka

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

katrin2201

http://.ru/ ;) (жать f5, большинство картинок из местной зоны)

slonishka

ооох. ну мне для такого лень было бы джаву ставить.
я бы встроенным перлом сделал на nginx-е.

sinet

А тем не менее автор-то абсолютно прав. Даж добавить нечего. Для мелких-средних несложных проектов ORM отлично прокатит. Но сделаем шаг в сторону от выборки по PRIMARY KEY и получим перманентную 100% загрузку сервера. :)
Я немного утрирую, но это так и есть, и подтверждается на больших проектах.

slonishka

ну про большие проекты тут и так написали, что плохо.
любопытно то, что существуют люди, которым не лень трахаться с непонятным ORM на маленьких проектах,
когда можно тупо писать все в plain SQL, и в этом автор тоже прав, собственно. =)

sinet

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

katrin2201

А тем не менее автор-то абсолютно прав. Даж добавить нечего. Для мелких-средних несложных проектов ORM отлично прокатит. Но сделаем шаг в сторону от выборки по PRIMARY KEY и получим перманентную 100% загрузку сервера. :)
Я немного утрирую, но это так и есть, и подтверждается на больших проектах.
Вопрос про загрузку - очень тонкий.
Когда вы натыкаетесь на проблемы нагрузки встает вопрос оптимизации.
Налажать можно как в ORM'е, так и в плейн SQL'е.
Вопрос в том, насколько сложнее оптимизировать ORMный код по сравнению с plan-SQL.
Разумеется, мы никуда не денемся от того оверхеда, который тратится на ORM прослойку, необходимый чтобы распарсить биндинги, сгенерить эскуэли, обработать ответ бд сервера и насоздавать объектов. Но по замерам того же хибернейта этот оверхед очень мал. Что-то в духе не более 10% в оптимизированном до предела коде. Если интересно - на их сайте где-то есть.
А реальный боттлнек - это неоптимизированные запросы. Вот там добавлением пары слов можно добиться разницы в скорости на порядок.
И вот хватит ли тебе знаний, умений, и возможности либы, чтобы оптимизировать генерящиеся запросы до необходимого уровня есть важный вопрос.
Несомненно, это сложнее чем оптимизировать просто plain-SQL. Иногда невозможно без вмешательства в код либы. Вот в таких случаях использование ORM действительно становится явно нецелесообразным.
А однозначно воспринимать ORM как зло, жрущее ЦПУ, все равно, что однозначно воспринимать какой-нибудь Oracle как зло, жрущее mem. Мол, нафига нужен Оракл, если все и так можно хранить в одном большом xml'е, а то и csv. Накрайняк использовать третий мускул с майисамом.

slonishka

А однозначно воспринимать ORM как зло, жрущее ЦПУ, все равно, что однозначно воспринимать какой-нибудь Oracle как зло, жрущее mem. Мол, нафига нужен Оракл, если все и так можно хранить в одном большом xml'е, а то и csv. Накрайняк использовать третий мускул с майисамом.
о боже! неужели xml сожрет меньше памяти?

katrin2201

не-DOM парсер сожрет конечно меньше =)
Оставить комментарий
Имя или ник:
Комментарий: