Mysql Помогите с алгоритмом работы

darksmoke

Новичок
Добрый день.

Есть сайт ukr-kurs.com.ua

Курс валют с сайтов банка, раз в час.

Раньше хранить историю не надо было, было так:
Записал значания в таблицу, через час отчистил таблицу и опять записал все данные.

А вот теперь надо хранить историю, за месяц:
Т.е. должен оставатся курс валют 23.00 прошлого дня в базе.

А на основании этих курсов будет график и стрелочки вверх вниз типо вырос или упал курс

Вот и не как не могу понять как правильно это организовать таблицу.

Придумал писать все в одну таблицу и рулить через WHERE `date`=(INTERVAL -1 DAY + curdate()), но тут наверное минус, т.к. курс валют парсится раз в час, то мне надо каждый раз удалять записи за день и записывать новые. ID будет очень быстро расти. Если это не проблема, то оставлю такой вариант.

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

Absinthe

жожо
Искать время последнего обновления по каждой валюте и потом взять значения по этому времени.
Одним запросом.
 

Absinthe

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

darksmoke

Новичок
Ну повторюсь. Мне нужна помощь в организации правильной логики.

Достаю курс валют за сегодня
Код:
SELECT * FROM bank WHERE `date`=(INTERVAL -1 DAY + curdate())
Так как курс валют парсится раз в час, то мне надо удалять записи сегодняшние и заново их писать
Код:
DELETE FROM bank WHERE `date`=curdate()
Ну и вставляю записи с сегодняшним числом
Код:
INSERT INTO `kurs_valuta`.`bank` (`id`, `date`, `name`, `rub_buy`, `rub_sell`, `usd_buy`, `usd_sell`, `eur_buy`, `eur_sell`) VALUES (NULL, '2014-07-16', 'Альфа банк', '0.3350', '0.3650', '11.6500', '11.8700', '15.8000', '16.6000');
До этого придумал что каждому числу календаря соответствует таблица в бд. Но потом подумал что это совсем криво, 31 таблица.
 

AnrDaemon

Продвинутый новичок
Хорошо, задам вопрос иначе - как ты определяешь, что один день закончился и начался другой?
 

AnrDaemon

Продвинутый новичок
Смешно, хотя и предсказуемо... практически все новички делают эту ошибку при работе с датами. Ну да ладно, к делу это не относится.

UNIQUE (`bank_id`, `date`, `currency_id`)

REPLACE INTO `kurs_histroy` (`bank_id`, `date`, `currency_id`, `value`) VALUES (1, curdate(), 2, 3);
 

Тугай

Новичок
Текущий курс - это курс с максимальной датой-временем, предыдущий это тоже максимум но c датой меньше текущего, что за танцы с бубном с INTERVAL -1 DAY ?

На праздниках и выходных курс обычно не меняется.
 

darksmoke

Новичок
Текущий курс - это курс с максимальной датой-временем, предыдущий это тоже максимум но c датой меньше текущего, что за танцы с бубном с INTERVAL -1 DAY ?

На праздниках и выходных курс обычно не меняется.
Вопрос то не в этом. выборку я и так написал
ВОТ В ЧЕМ ВОПРОС
Придумал писать все в одну таблицу и рулить через WHERE `date`=(INTERVAL -1 DAY + curdate()), но тут наверное минус, т.к. курс валют парсится раз в час, то мне надо каждый раз удалять записи за день и записывать новые. ID будет очень быстро расти. Если это не проблема, то оставлю такой вариант.
 

fixxxer

К.О.
Партнер клуба
bigint - это 2^63, можешь посчитать, на сколько лет тебе хватит.

where date, как уже заметили, не нужен, достаточно order by date desc limit 1, и в этом случае будет эффективно использоваться правильно созданный индекс.

если выбирать текущий курс надо намного чаще, чем ходить в историю, я бы малость денормализовал и сделал отдельную таблицу с текущими курсами.
 

darksmoke

Новичок
а как правильно индексы расставить? Сейчас так
Код:
CREATE TABLE IF NOT EXISTS `bank` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `date` date DEFAULT NULL,
  `name` tinytext NOT NULL,
  `rub_buy` float NOT NULL,
  `rub_sell` float NOT NULL,
  `usd_buy` float NOT NULL,
  `usd_sell` float NOT NULL,
  `eur_buy` float NOT NULL,
  `eur_sell` float NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
 

Активист

Активист
Команда форума
Можно дельно, а не оущит...
MySQL engine должне быть innodb , а не myisam, лучше использовать транзакции - "start transaction" ... (всякие финансовые SQL) .. "commit" если успешно, "rollback" если ж@па.
Для хранения денежных сум используйте decimal (10,2) , а не float. Если нужна бОльшая точность, то собственно укажите это в decimal.
 

WMix

герр M:)ller
Партнер клуба
Активист, может всеже int, приводить к типу на уровне php не придется. а когда большая точность лучше float или double
 

fixxxer

К.О.
Партнер клуба
float или double для финансов нельзя никогда.

int в копейках (или, там, в сотых копейки) - можно, если нужны вычисления в коде, но тут надо быть уверенным, что все влазит в PHP_INT_MAX, иначе внезапно вылезет float. Лучше этого избегать и вычисления делать SQL-запросами, а в php пусть строками туда-сюда таскается.
 

fixxxer

К.О.
Партнер клуба
Ну вот нативный, с перегрузкой операторов, прилетит, тогда и будем.
 

WMix

герр M:)ller
Партнер клуба
я однажды так накрутил с этими вычислениями на уровне базы, перенося новое значение из резальта в запрос, что решил считать по максимуму на пхп.. нафиг!
doule на много точнее чем decimal или? я понимаю что не все числа можно представить, но посчитать то точнее будет...
 
Сверху