Подход к выборке и работе с данными
Я человек просто, деревенский. Алгоритмов хитрых знаю пока мало, опыта в проектировании маловато, с языками разными работал тоже немного. Но все же расскажу немножко о том, как работаю с данными в БД я. Заранее оговорюсь, что описанные мной удобности и неудобности могут быть результатом моего неумения. В этом случае, надеюсь, меня поправят.
На Delphi я пробовал два похода. Первый подход - работа с датасетами. Датасет в дельфи - это класс, который содержит в себе методы выборки данных, изменения их и коммита данных обратно в БД. Неудобность основная для меня одна - "плоское" представление данных.
Второй подход мой - преобразование такого датасета в коллекцию объектов, каждый из которых является представлением записи из БД. Этот подход мне нравится больше, я могу издеваться над представлением данных очень по-разному, и тебе древовидный формат можно реализовать, и реализовывал. Неудобность в отсутствии, например, средств фильтрации, каковые есть у датасетов. Отфильтровал контент, например, по сегодняшней дате и работай, а в коллекции как это сделать я не знаю. И с поиском неудобство. И так по мелочам.
В результате все выливается в желание получить датасет, умеющий представлять данные в виде дерева. Видимо как-то так.
В PHP и Python'е, как я понял, работа с данными складывается в работу с массивом или словарем или чем еще. Это вообще, имхо, жуть. То есть работать можно, но многое приходится делать "ручками". Массив - это все-таки относительно низкоуровневая конструкция по сравнению с датасетами из дельфи.
Это одна сторона вопроса. О представлении, так сказать данных.
Другая - о быстродействии и целостности данных, пожалуй.
В этом плане у меня тоже два подхода наблюдалось. Первый - "выдергивание" данных из БД, затем изменение их локально и коммит изменений на сервер БД. Причем коммит, естественно, именно изменений. Неудобство в том, что порой изменения могут повлиять на многие данные, и локально приходится делать кучу изменений и еще и проверок. При удалении записи А в БД напрямую, БД мне скажет, что нельзя удалить ибо есть связанные записи в таблице Б. Локального этого не будет. Надо делать кучу проверок вручную иначе нарушается целостность данных.
Другой подход - вносить изменения в саму БД. После изменения обновлять локальные данных. Здесь неудобность в том, что процесс обновления зачастую весьма небыстр. Например - очистить коллекцию объектов и дочерние коллекции этих объектов. Затем обновить датасет и снова преобразовать его в объекты.
Блин, описал немножко сумбурно, потому что, видимо, в голове бардак в этом плане.
Короче хотелось бы послушать кто как работает с данными, какие есть подходы. Рассмотреть плюсы и минусы этих подходов с точки зрения простоты, гибкости, быстродействия и безопасности. Хочется узнать о разных инструментах работы с данными в разных языках.
Как верно было сказано - в PHP все сводится к массивам. Просто, доступно, но неудобно. В виду этого теперь у меня все данные из БД представляются обычно в следующем виде:
1) Создается какой-либо абстрактный класс, имеющий методы get/set.
2) В данном классе зарезервирована специальная переменная-массив, которая содержит одну запись результата выборки (т.е. каждая запись оборачивается в объект)
3) Доступ к элементам выбоки происходит только посредством get/set. В set() можно передавать массивы, чтобы массово за раз устанавливать значения.
4) Все классы, описывающие конкретный тип записи, наследуются от данного абстрактного класса.
5) Собственно, в самом классе или где-то вне него описываются все возможные ключи записи, а также их допустимые значения (ограничения целостности на уровне значений, так сказать).
6) При установке значений происходит сверка данных на корректность.
Собственно минусы:
- массив данных довольно-таки сильно обрастает и тяжелеет;
- сохранение и загрузка результатов все так же висит на программисте, сама задумка реализована так, что к БД данные класс прямого отношения обычно не имеет (если только это не реализовано в специальных методах при наследовании класса).
И плюсы:
- для каждого такого класса пиши какие угодно специфичные методы для обработки;
- контроль корректности значений на уровне описания полей в классе, а не в ручную в каждом участке кода, т.е. изменяются допустимые значения полей в одном месте;
- простота доступа, большая гибкость.
Есть такая штука ORM. Кто-то скажет что это хорошо, кто - плохо. Я считаю ORM в SQLAlchemy - это хорошо.
Стоит ещё добавить, что в целом нет универсального решения. Так как много зависит от различных факторов: объём задачи, сроки, наличие опыта, согласие команды и т.д.
Почитаю. :)
Как я понял, моя работа с коллекциями объектов и есть что-то вроде ORM. Тут в общем-то и интересно послушать о плюсах и минусах подобного подхода, почему кто-то говорит хорошо, а кто-то плохо. Как я понял - основная проблема в конвертации данных из одного представления в другое и слежение за их целостностью. Хардкейз рассказывает в чате об Entity Framework в дотнете, тоже надо смотреть. И BLToolkit.
Ну да. Тем более, что я замечаю, что гибкость решения обратно пропорциональна его универсальности.
В силу того, что теперь основу моих приложений составляет Pylons, где изначально заложена концепция MVC, причём весьма удачно, я не заморачиваюсь работой с базой за пределами модели.
А совершенства нет и никогда не будет, если работают не один-два человека с одной БД, да ещё удалённой на достаточное расстояние. тут в идеале вообще бы лишить прямой связи с БД, сделать трёхзвенную цепь. Но и тут граблей подводных не оберёшься. Вобщем, выбирать нужно "или шашечки, или ехать".
ADO хорош. Но вот использовать его в связке с VirtualStringTree, да и вообще, как я выше говорил, представить данные в виде дерева с помощью ADODataSet, я хз как. Есть в этом плане опыт? Это основная причина, почему я начал фигачить все в объекты.
не знаю, что такое VirtualStringTree, но достаточно много приходилось маяться с TTreeView. Никакой DataSet не поможет. Всё надо затачивать под конкретную задачу. Ну, единственное что можно сделать - написать какие-то методы и поля, которые явно всегда будут.
Вот последняя беда у меня была: у дерева два корневых узла, в каждом корне девять уровней вложенности. При этом узлы на каждом уровне (и в каждом из корней) имеют совершенно разный функционал, у них разные менюхи, разная реакция на Dragndrop и DragOver. И соответственно данные совершенно из разных наборов данных.
Учитывая такую разницу в поведении, я писал наследышей TTreeView с наследышами TTreeNode, которые живут уже в соответствии с предназначением.
не знаю, что такое VirtualStringTree, но достаточно много приходилось маяться с TTreeView. Никакой DataSet не поможет. Всё надо затачивать под конкретную задачу. Ну, единственное что можно сделать - написать какие-то методы и поля, которые явно всегда будут.
Вот последняя беда у меня была: у дерева два корневых узла, в каждом корне девять уровней вложенности. При этом узлы на каждом уровне (и в каждом из корней) имеют совершенно разный функционал, у них разные менюхи, разная реакция на Dragndrop и DragOver. И соответственно данные совершенно из разных наборов данных.
Учитывая такую разницу в поведении, я писал наследышей TTreeView с наследышами TTreeNode, которые живут уже в соответствии с предназначением.
Вот, а задача вполне актуальная. Тут, как я понял, пригождается ORM. Я про сей подход не знал и писал наследников TList и хитрые объекты. Но минус в том, что для каждой таблицы класс объекта - обертки для записи я создавал вручную. Коллекция под эти объекты тоже затачивалась вручную. Сейчас я хочу попробовать доставать метаданные из БД, на их основе генерировать классы в Delphi. Хотя и прихожу к мысли, да, что тут без кодогенерации как в дотнете все это будет большим костылем. В гугле по запросу ORM Delphi ничего путного не нашлось, Одни костыли. Как вообще люди работают? Я не понимаю. :)