Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Модель прогаммы работающей с СУБД


Автор: stmamont 15.2.2007, 13:03
Какую модель придумать для программы, с возможностью использования СУБД.

Использовать собираюсь ADO, но возможно изменение на другое.

Не могу придумать достаточно гибкую модель, для того, что бы работать с различными типами объектов
(например: человек, машина), информация о которых хранится в СУБД.

Раньше делал так (когда задачи были маленькие):
В качестве БД использовал XML.
при загрузке программы создавал объект класса Humans выполняющий функции СУБД, который парсил xml
и создавал ВСЕ объекты которые, информация о которых хранилась в БД.

Ну, минусы очевидны:
  •  для каждого объекта (Humans , Cars) приходилось реализовывать СУБД)
  •  все это дело хранится в памяти!!!
  •  и прочие жуткие вещи)
Очевидно, что придется писать классы для работы с ADO
И как то заставить их работать с Humans , Cars...
Причем сам принцип работы мне видется таким
При запросе какого то Human у Humans
Humans связывается с классами которые работают с ADO и выдирает инфу оттуда.
затем отдает

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

Не могу никак решить, как это правильно делается. Задача типичная. Как обычно вы это делаете?

Пишу на 6 билдере, но здесь это не имеет значения!

Гуру, помогите!!

Автор: Vyacheslav 15.2.2007, 13:18
А что тут нового, кроме того, что повозится придется. Во первых БД
Есть несколько вариантов мапинга классов на реляционныую БД. У каждой есть свои плюсы и минусы. Поищите в интернете. Вот могу на первый случай предложит Григорьева. http://fizmat.vspu.ru/citforum/database/articles/rxo.shtml
http://fizmat.vspu.ru/citforum/database/articles/moq.shtml
http://www.citforum.ru/database/articles/nrm/nrm.pdf
Кстати этот вопрос обсуждался когда то на форуме автор статей принимал в этом участие

Автор: pandrew 15.2.2007, 13:27
Цитата(stmamont @  15.2.2007,  13:03 Найти цитируемый пост)
Не могу никак решить, как это правильно делается. Задача типичная. Как обычно вы это делаете?

Вообще-то я обычно начинаю с проектирования БД. 
Тебе разумно начать с примеров, поставляемых с BCB. Там был какой-то пример работы с продавцами, счетами и т.д. По-моему это тоже самое, что и у тебя. Или книжку какую-нибудь почитай.
Не зацикливайся на технологии BDE, ADO или еще что-то: принцип один и тот же. 

Автор: stmamont 15.2.2007, 13:35
pandrew, БД спроектирована, уже.
примеры поставляемые с BCB не отражают суть вопроса о том, что мне нужно
Vyacheslav, спасибо за ссылки. сейчас буду читать. 
никогда не говорил что здесь чтото новое (только для меня)) я знаю , что это делается многими, не знал только как...

Автор: Vyacheslav 15.2.2007, 14:03
Цитата(pandrew @  15.2.2007,  13:27 Найти цитируемый пост)
Вообще-то я обычно начинаю с проектирования БД. 
Тебе разумно начать с примеров, поставляемых с BCB. Там был какой-то пример работы с продавцами, счетами и т.д. По-моему это тоже самое, что и у тебя. Или книжку какую-нибудь почитай.

Вообще-то человек не об этом спрашивает. Примеры хороши, но они отнсятся к чисто реляционному подходу. А он хочет сделать объектную настройку над реляционной БД

Цитата(stmamont @  15.2.2007,  13:35 Найти цитируемый пост)
pandrew, БД спроектирована, уже. 

Теперь я не понял smile Боюсь, если вы спроектировали БД без учета того, что будете мапить на нее классы, то у Вас проблем будет выше крыши. 
Приведу пример с Вашим Humans. Типичная структура   наследования классов  будет  примерно выглядеть таким образом
TDBObject-> TDBPerson -> TDBEmployee
                                       -> TDBClient
                                       -> TDBChild

Ну и например  будут задачи. 
Вытащить из БД информацию о всех людях ( рабониках, клиентах, детях)
Вытащить из БД о всех работниках,
Вытащить из БД всех   детях работников.
Или скажем вытащить всех людей, у которых день рождение в текущем месяце

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

Автор: stmamont 15.2.2007, 20:44
Vyacheslav, после прочтения двух приведенных выше статей, я понял, что моя главная ошибка была - попытка надстройки чисто О- среды над обычным для реляц. БД способом хранения информации.
и БД была спроектирована - стандартным для реляц. БД способом.

Теперь все перепланировать буду)

Возможно этот вопрос освящен в третьей статье (pdf), но мне пока не совсем ясен вопрос:
если объект А содержит список объектов B, то в какой момент мне считывать информацию из БД об объектах B: в момент непосредственного создания объекта A или при обращении к какому либо объекту B?
То же относится и к атрибутам объектов.

Автор: Vyacheslav 16.2.2007, 11:38
Скорее всего вам придется создавать класс контейнер, который долже иметь коллекцию объектов. Кстати, хотя это инструментальный класс , его тоже лучше замапить в БД. На его основе  хорошо создаются справочники
Считывать вы должны все объекты  сразу. Когда - неважно. Лучше иметь для этого отдельный метод ( Fetch или Refresh), при вызове которого будут выполнятся следующие действия  
1. Уничтожается выборка предыдущих объектов, если она была
2. Направляется запрос к БД для вычитывания данных по всем объектам ( пока в терминах SQL)
3. Из полученнго курсора восстанавливаются Ваши объекты, примерно также, как Вы это делали из XML

Автор: Anikmar 16.2.2007, 11:44
Цитата(Vyacheslav @  16.2.2007,  11:38 Найти цитируемый пост)
Считывать вы должны все объекты  сразу.

На мой взгляд все-таки радикально. Интересно бы знать сколько объектов планируется хранить в базе.

У меня тоже объектами все организовано, правда я не мапил их на БД - начал с разработки структуры БД, а объекты от туда уже тянут то, что им надо. Количество записей планируется порядка миллиона. Тянуть их все сразу, да еще в многопользовательском режиме приведет к тормозам.

Автор: Vyacheslav 16.2.2007, 11:46
Цитата(stmamont @  15.2.2007,  20:44 Найти цитируемый пост)
То же относится и к атрибутам объектов.

Вы похоже не совсем понимаете суть дела
В результата выполнения запроса  например
select * from Person 

Вы будете иметь таблицу со строками, каждая из которых  - содержимое объекта. Дальше все построчно
1. Создать объект
2. Заполнить атрибуты
3. Вставить объект в контейнер
И далее по циклу

Добавлено @ 11:51 
Цитата(Anikmar @  16.2.2007,  11:44 Найти цитируемый пост)
У меня тоже объектами все организовано, правда я не мапил их на БД - начал с разработки структуры БД, а объекты от туда уже тянут то, что им надо. Количество записей планируется порядка миллиона. Тянуть их все сразу, да еще в многопользовательском режиме приведет к тормозам. 

Э ... И Вы всегда изпользуете Весь миллиона для работы? Обычно запросы типа 
select * from table  
большая редкость. И применяются только, когда число записей ограничено. В остальных случаях
select * from table where или любые другие с различного рода условиями, ограничивающими выборку


Автор: stmamont 16.2.2007, 12:11
Vyacheslav, 
Цитата

Вы похоже не совсем понимаете суть дела
В результата выполнения запроса  например
select * from Person 

Вы будете иметь таблицу со строками, каждая из которых  - содержимое объекта. Дальше все построчно
1. Создать объект
2. Заполнить атрибуты
3. Вставить объект в контейнер
И далее по циклу



Имелось в виду стоит ли считывать ВСЕ атрибуты объекта из БД если требуется только один из них?
Везде в учебниках по SQL и по БД написано, что не стоит писать select *, вместо этого лучше перечислять необходимые параметры т.е. select id , name , ...
Вот я и подумал, может и в объектах из БД тянуть и подтягивать только необходимую инфу?

Автор: Vyacheslav 16.2.2007, 12:31
Вы работает с объектом. Объект без атрибута создать нельзя. Так лучше сразу его заполнить

Автор: Anikmar 16.2.2007, 15:17
Цитата(Vyacheslav @  16.2.2007,  11:46 Найти цитируемый пост)
Э ... И Вы всегда изпользуете Весь миллиона для работы? Обычно запросы типа 
select * from table  
большая редкость. И применяются только, когда число записей ограничено. В остальных случаях
select * from table where или любые другие с различного рода условиями, ограничивающими выборку

Так я по этому поводу и писал, в ответ на предложение:

Цитата(Vyacheslav @  16.2.2007,  11:38 Найти цитируемый пост)
2. Направляется запрос к БД для вычитывания данных по всем объектам ( пока в терминах SQL)


Просто я подумал вы имеете в виду всю БД. Вот и засомневался в целесообразности.  smile 
Просто неправильно вас понял 

Автор: stmamont 16.2.2007, 22:16
Простите, а существует ли SQL запрос позволяющий сделать выборку всех аттрибутов по данному OID объекта, по схеме предложенной Григорьевым
http://fizmat.vspu.ru/citforum/database/articles/rxo.shtml

Автор: stmamont 16.2.2007, 22:53
Вот такие таблички получились:
Код

CREATE TABLE CLASSES(
    classID INTEGER PRIMARY KEY, 
    className CHAR(100)
);

CREATE TABLE DELTAS(
    classID INTEGER FOREIGN KEY REFERENCES CLASSES classID,
    deltaID INTEGER FOREIGN KEY REFERENCES CLASSES classID
);

CREATE TABLE ATTRIBUTES(
    SID INTEGER PRIMARY KEY,
    deltaID INTEGER FOREIGN KEY REFERENCES CLASSES classID,
    name CHAR(100),
    tableName CHAR(100)
);

CREATE TABLE OBJECTS(
    OID INTEGER PRIMARY KEY,
    classID INTEGER FOREIGN KEY REFERENCES CLASSES classID
);

CREATE TABLE PARAM1(
    OID INTEGER FOREIGN KEY REFERENCES OBJECTS OID,
    SID INTEGER FOREIGN KEY REFERENCES ATTRIBUTES SID,
    value /*some type*/
);

ИМХО, как надо находить все атрибуты объекта у которого OBJECTS.OID = :OID :
шаг1. находим все DELTAS.deltaID которые содержатся в классе объекта
// findDeltas(int OID);
шаг2.  находим все ATTRIBUTES.tableNames в которых могут лежать атрибуты объекта
// findTableNames(findDeltas(int OID))
шаг3. находим все атрибуты из всех таблиц из tableNames найденных + у атрибутов найденных должен быть OID = :OID
// ??

база данных firebird 2

неужели все на самом деле так сложно? и придется использовать PSQL?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)