![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
36 таблиц, в среднем по 10 столбцов в каждой. В одной, самой главной, около 20.
Если приоткрывать завесу тайны, то пишется программа для работы, я работаю в туризме. База данных это справочник где содержатся такие вещи как страны, города, варианты туров, номера, размещения в отелях, рейсы, аиропорты и т.д. Например таблица с отелями может содержать огромное количество столбцов, где каждый отель представляет из себя booleвую переменную означающую есть ли какая-то услуга в отеле или нету: ИмяОтеля|Бассейн|Фен в номере|Бильярд|Корт и т.д. до бесконечности Естественно многие таблицы между собой завязаны примари ключами, потом мне нужно создать именно дерево, где вместо примари ключей будут ссылки. Теперь насчет цифры в 1 миллион. Это цены, которые могут быть просчитаны на сезон вперед, где-нибудь с 20 апреля до 31 августа. Несложная операция вычисления это добавление комиссии нашей фирмы. Причем говоря об 1 миллионе я говорю о количестве строк, где количество столбцов (ключи отеля, номер, размещения, питания, ночей, даты и т.д.) тоже будет не маленькое. В итоге все эти цены должны положиться в базу и должен получится 1 excel файл размером в 20-30 мегабайт... Сейчас это работает так. Есть 200 xml файлов размером по 10 мегабайт, по одному они кладутся через php скрипт во временную таблицу, происходит ручная сортировка, ненужные (непродаваемые) отели выкидываются. Эта процедура занимает 1-2 рабочих дня. Потом процедура на сервере все считает, это около 30 минут. Потом все это селектом выгружается на локальную машину, при этом программа сжирает около 2 гигабайт оперативы. Еще 30 минут. Потом программа формирует excel и т.д. Я хочу написать свою программу, где указав одну папку программа находит все 200 xml файлов и заносит в таблицу, мне остается нажать "Распарсить" и все это парсится хоть всю ночь, лишь бы небыло моего участия в этом. Далее я просто выделяю мышкой 200 записей в таблице и запускаю процедуру сортировки, которая спрашивает меня о действии только в том случае, если появился какой-нибудь новый отель, номер, размещение и т.д. Если я не отвечаю, сплю например, то программа через 30 секунд игнорирует эту запись и идет обрабатывать дальше. Т.к. я не сделал никакого выбора, то вместо сохранения всего этого в базу ничего не происходит и программа тупо ждет когда приду я. Если вопросов никаких у нее не возникло, то все автоматом сохраняется и начинается просчет. Просчет уже идет на сервере. Но, т.к. у меня на локальной машине есть все эти же данные, то просчет идет и на локальной машине (обычная накидка %) и тут же формируется Excel, минуя 2 гигабайтное сжирание памяти как это есть сейчас и 30 минутное ожидание ответа с сервера. Фух, устал |
|||
|
||||
| comcon1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
Значит грубо структура такая:
Страна | Город | \ Перелет Отель В классах "перелет" и "отель" будет куча столбцов с цыыыфрами)) Тебе нужно подсчитать сумму всевозможных вариантов путевок. Сколько записей в базе, я так и не понял. это раз. Два - не обязательно делать просчет, загружая все данные в память. Предлагаю такой вариант. Вот такую хрень оформляешь ввиде обычного дерева: Страна1 Страна2 Страна3 | Город1 Город2 Город3 | Отель1 Отель2 Отель3
Каждый пункт - структура, информацию в них не хранишь. Так сказать "СНИМОК ДЕРЕВА". Далее каждой структуре отеля соответствует структура HotelData, где хранятся все данные. Данные хранятся отдельно, допустим в базе. Из базы данные сериализуются ввиде дампов структур HotelData, допустим, раз в неделю. Снимок дерева хранится отдельно или тоже загружается из базы (это недолго). Подсчет. Ты просчитываешь различные туры - это различные обходы дерева. Строишь обход - загружаешь из дампа соответственные данные в память - считаешь. Можно не по одному обходу, а, к примеру по 100 обходам. Зачем сериализировать? Данные из базы будут браться НАМНОГО медленнее чем сериализированные предварительно. Вот. Как тебе такой вариант?? |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
с таблицей описания отеля вся понятно. там по сути только два поля - название и булевый массив фиксированного размера. Соответственно, конструктор структуры (один из) грузит данные из базы.
В остальных таблицах, я так понимаю, данных будет меньше и их можно будет легко упаковать в стройные структуры. Возможно, даже аналогичным образом. |
|||
|
||||
| comcon1 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
Во: зацените иерархию:
Таким образом за счет абстрактных классов можно полностью отвязать процедуру расчета стоимости тура от вида дерева классов. Т.е. можно добавлять не только новые экземпляры классов, но и новые классы без изменения процедуры расчета! код расчета типа такой
Это сообщение отредактировал(а) comcon1 - 17.3.2008, 14:02 |
||||
|
|||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Хех, нет вот как раз о запаковывании придется забыть. Так и знал, что привяжетесь к однотипности данных. Но нет, там помимо этого есть столбцы с адресом отеля, телефоном, факсом, e-mailом, сайтом, дополнительным описанием, фотографиями, ссылка на звездность и питание.
Количество записей в справочнике в зависимости от таблицы. Отелей - 3000, номером 17000, 50 стран, 2500 самолетов, 5000 партнеров (у них тоже дофига столбцов). В общем все это укладывается в 10 мегабайт. Дерево я выстраиваю по зависимостям. В общем вопрос то простой был, надо ли прописать friend классу, чтобы сделать первичную инициализацию членов или лучше передать указатель this на родителя, чтобы класс мог сам проинициализироваться средствами (ссылки на объекты других таблиц/классов, источник базы данных) пораждающего класса. Схематично это выглядит так.
В итоге обращение к таблицам сводится к database->Hotels(345)->name(); Я хоть и изобразил схематично, но становится понятной проблема, там где конструктор БазаДанных компилятор выдаст ошибку, что обращение идет к приватному члену, а через setName я достучаться не могу, т.к. просто тупо обновлю базу данных тем же значением. Вот и думаю сделать через friend или еще как-то... |
|||
|
||||
| comcon1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
здесь тебе нужен доступ не ко всем приватам. Может сделать интерфейсную внешнюю дружественную функцию?
|
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Значит надо сделать конструктор БазыДанных другом.
Такой подходят нормальный или есть еще мнения ? |
||||
|
|||||
| comcon1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
ну вроде как да. вероятность ошибок низка. только одна друг-функция.
|
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Возникла другая проблема. У меня ведь 36 таблиц, каждая таблица это класс, а каждому классу надо прописывать френда:
Пытался наследовать дружбу с базового класса, а она оказывается не наследуется... |
|||
|
||||
| comcon1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
вставляешь в каждый класс дефайн.
|
|||
|
||||
| inside_pointer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
В стране есть город (в него прилетает самолёт и есть отель(в отеле есть номеры)). А у тебя всё в куче, какие-то города страны 36 таблиц что куда непонятно, поэтому ты и сформулировать не можешь скока вешать. |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Дело в том, что структуру базы формировал не я. Я всего-лишь импортирую ее из базы данных другой программы, которая уже не справляется со своей задачей, но используется везде где только можно. Я пытаюсь хотябы часть ее функционала перенести в свою программу и узкие места переписать под себя. В базе нет привязок типа Отель-Питание-Номер-Размещение. Там многое идет раздельно и увязать это друг с другом я никак не могу. Хотя отели по веткам страны->регионы->города наверно рассортирую. Самолеты наверное тоже удасться рассортировать, они имеют параметр Порт, который завязан на Городе, а город уже на регионе и стране. Кстати это не избавит от 36 классов, т.к. каждый класс имеет свои методы. Это сообщение отредактировал(а) SABROG - 18.3.2008, 15:10 |
||||
|
|||||
| inside_pointer |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
А у тебя не построено дерево, тебе надо построить общее дерево для всех данных, на бумаге чтобы всё входило, а потом реализовать его в программе.
А на самолётах человеки летают, а на тех на которых никто не летает(например если у тебя там просто список вообще всевозможных рейсов), может летать нулевой человек.
А в жизни они как связаны(создай такой элемент).
Предлагаю обрабатывать данные внешней функцией. Т.е. просто идёт структура, а обрабатывает эту структуру снаружи одна две функции. |
||||||||
|
|||||||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Я немного пересмотрел проектирование классов, реально будут менятся всего 4 таблицы, т.к. остальные 32 буду исключительно читаться, а я об этом как-то забыл, по сути это кэши. Поэтому 32 обычные struct и 4 класса, а для 4х классов френды это нормально. Сейчас возникла иная проблема, некоторые поля в базе могут быть пустыми и не ссылаться на какие-либо данные, т.е. это те колонки, где пользователь сам делает выбор. В итоге некоторые ссылки оказываются "битыми", что вызывает краш системы. Чтобы этого избежать мне придется каждый раз проверять ссылку на NULL только для некоторых из колонок, только человек не программа и может забыть это сделать. Надо глянуть в сторону ассертов.
Кстати такая практика доступа к приватным членам на чтение является популярной или я намутил и компилятор сам бы оптимизировал так, чтобы метод не вызывался call'ом, а просто передавалась ссылка ?
Это сообщение отредактировал(а) SABROG - 19.3.2008, 09:55 |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
компилятор сам оптимизирует даже если ты пропустишь inline. Только оптимизацию нужно включить.
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |