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


Автор: mexico 16.5.2009, 00:23
Во общем пишу WEB скрипт на php для MySQL где входящими данными являются статьи (доходов / расходов).
Если обобщить что мне надо так это:
-юзвер
-календарь 365 дней
-статьи расходов|доходов

на мой взгляд с точки зрения реляционности БД нужно сделать так
T_user  (   id_user,      name,                email   ) - пользователь 
T_article(  id_article,    debit/credit,       description) - описание статьи и собственно куда ее записывать
T_day    (  id_day,        id_user,     id_article,   date,   summa)  - в такой-то день такой-то пользователь потратил такую-то сумму по статье

все отлично, только вот моя логика не дает покоя, думаю что не так? 
1пользователь * 365дней * вдень ~10 записей = 3 650 записей на одного пользователя мне кажется через чур много 
и в конце собрать эти данные  мигом,  обработать, построить графики.

1- можно ли уменьшить количество записей на пользователя хотя бы до 365-и ?

Если посмотреть глубже в задачу. 
например есть кредиты/депозиты их можно взять у пользователя в самом начале и разбить на месяца (создаем таблицу "месячного" бюджета) для того что бы обобщить статьи также в таблицу "месячного" бюджета могут входить квартплата, меньше годятся такие статьи как транспортные затраты, пища, одежда.
В итоге теряем гибкость но существенно уменьшаем количество (~3 650) записей. гибкость можно терять но что бы в конечном результате я смог обработать данные для графиков по статьям и по временной шкале месяцам.

Меня бы устроил вполне вариант 3 650 если бы это было не веб программирование где ключевую роль играет скорость т.к. объемы процессорного времени и трафика ограничены.

Автор: Gluttton 16.5.2009, 13:17
Если Вас смущает количество записей 3650, то прочь сомнения smile !

Я сейчас работаю над созданием достаточно простой БД, так вот, там одна из таблиц имеет объем ~6М записей.
http://forum.vingrad.ru/forum/topic-258795/kw-firebird-индекс.html, в результате запрос на выборку выполняется за 0,167 секунд smile .

В MySQL ведь есть индексы?

Автор: mexico 16.5.2009, 16:17
Спасибо за комментарий.

Да конечно MySQL есть индексы smile

Для успокоения помогла статья - http://forum.vingrad.ru/forum/topic-255994.html - где 15млн записей и поиск по индексу занимает сотые доли секунд.

Но я все ровно не могу успокоится тобиш у меня по задачи к примеру есть статья "транспортные расходы" на транспорте я езжу каждый день тратя одну и туже сумму в табл. T_day  уменя 365 совершенно одинаковых записей за исключением даты что если сделать 2 поля даты 
1 поле ха-ра начало статьи "транспортные расходы"
2 поле ха-ра конец  статьи "транспортные расходы"

может следует иерархию сделать ? или это бред параноика ?

Автор: LSD 17.5.2009, 20:04
При наличии индекса по полям id_user, id_article, date, выборка строки из таблицы по этим же полям, будет идти быстрее, чем join двух таблиц. Так что пытаться тут сделать нормализацию - не стоит.

Автор: mexico 18.5.2009, 21:07
"будет идти быстрее, чем join двух таблиц"

Объясните пожалуйста что имелось ввиду а то совсем не понятно?   smile 

Автор: LSD 19.5.2009, 10:53
http://www.javenue.info/post/20

Автор: mexico 19.5.2009, 16:52
LSD Спасибо конечно за ссылку но что такое join я в курсе я не понял что ты тут хотел сказать "Дата 17.5.2009, 20:04" 

Цитата
При наличии индекса по полям id_user, id_article, date,
  ну конечно индекс стоит 

Цитата
выборка строки из таблицы по этим же полям, будет идти быстрее, 
 понял!  дурак бы не понял. 

Цитата
быстрее, чем join двух таблиц.
  - вот тут имеет место недопонимание тойсть id_user конечно известен он в сессиях лежит про дату я молчу. но вот про-JOIN-ить T_article с T_day  по id_article по любому придется.  Мне показалась вы предлагаете обойтись без join Но как ???

Цитата
Так что пытаться тут сделать нормализацию - не стоит.
 если имеется ввиду нормализация UPDATE and DELETE то согласен а по другим па-рам разве не соответствует?  


ЗЫ: Вы случайно не тим лидер ? А то у меня начальник тоже опишет картинку что у него в мозгу а я потом пол дня сижу гадаю что же он имел ввиду  smile 

Автор: LSD 20.5.2009, 17:02
Я говорил про то, что иногда денормализация таблиц может быть полезна. Например в данном случае можно добавить в таблицу T_day колонку article_description которая бы была ссылкой на соответствующее поле в T_article. Получится дублирование информации, плюс изменение имени статьи может стать длительной операцией. Но зато мы получим прирост производительности по запросам которым надо получать расходы и их статьи.



Цитата(mexico @  19.5.2009,  16:52 Найти цитируемый пост)
Вы случайно не тим лидер ?

Пока нет, но это чисто случайно smile

Автор: Zloxa 20.5.2009, 18:01
Цитата(LSD @  20.5.2009,  17:02 Найти цитируемый пост)
плюс изменение имени статьи может стать длительной операцией

плюс необходимо сериализовать операции добавления/изменения дня и модификации статьи...
Самостоятельно поддерживать согласованность данных.. ох геморройная задача.

В данном случае, денормализация t_day, перенесение description врядли даст приросту для построения графика.
вот debit/credit, пожалуй следовало бы.. и fk кинуть по паре (id_article,    debit/credit) дабы запретить менять, если уже есть записи.

Уменьшить количество записей можно было бы если бы pk назначить по (id_day,  id_user,     id_article).

mexico, Какие вы отчеты желаете делать по вашим данным?

От чегото мне кажется, что в годовом периоде, Вам вряд ли нужно будет показывать операции в разрезе (день,статья) скорее в разрезе (месяц,статья).
А вот по месяцу уже детализацию по дням можно бы показывать.

Тогда ввести сущность месяц, держать баланс на начало(или конец) месяца и движуху по статьям агрегированную помесячно.
Тогда при добавлении операции по дню, перечитать движуху по статье за текущий месяц, изменить баланс по следующему(текущему) меясцу и всем последующим. Врядли у вас будет много операций задним числом, более чем месячной давности.

Автор: mexico 20.5.2009, 21:35
Цитата

Какие вы отчеты желаете делать по вашим данным?

пока не предпалагаю нечего грандиозного.
- Отображу 2 прямые (доход/расход)  за год в разрезе по месяцам.
- доходы/расходы в процентном соотношении за год 


Zloxa - а добавление сущности "месяц" по идее будет хранить сумму затрат за месяц,
 вы подозреваете что SUM() плохо справится (ресурсоемко) с этой задачей?

просто у меня была идея сущности "месяц" но предназначение ее было бы уменьшить количество записей в T_day а не хранение вычислений.


ЗЫ: спасибо модераторам топика за коментарии smile  

Автор: Zloxa 21.5.2009, 01:04
Цитата(mexico @  20.5.2009,  21:35 Найти цитируемый пост)
 вы подозреваете что SUM() плохо справится (ресурсоемко) с этой задачей?

C озвученными Вами объемами, не затруднительно будет справиться и экселю. smile
Однако ж чтото побуждает Вас опасаться за производительность? 

Объемы хранимых данных это лишь меньшая половина проблемы. Хранить ради хранить, думаю, мало кому интересно. Хранить нужно прежде всего для того, чтобы иметь возможность извлечь.

Принцип, описанный мной я использую для хранения остатка в разрезе даты в периоде ~2 года, ~300 розничных магазинов, 1,5к номенклатуры.
Остаток по магазину на дату по транзакциям рассчитывается ~1,5 часа
Остаток по магазину на дату по предложенной структуре рачитывается ~3 мин.

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