Scott przedstawia świetny punkt dotyczący kolejnych dni targowych. Polecam obsługi to z tabeli złącza jak:
CREATE TABLE `market_days` (
`market_day` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`date` DATE NOT NULL DEFAULT '0000-00-00',
PRIMARY KEY USING BTREE (`market_day`),
UNIQUE KEY USING BTREE (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0
;
Ponieważ coraz więcej dni rynkowe upłynąć, zaledwie INSERT
nowych date
wartości w tabeli. market_day
odpowiednio zwiększy.
Podczas wstawiania danych należy wyszukać wartość LAST_INSERT_ID()
lub odpowiednią wartość dla danego parametru date
dla poprzednich wartości.
chodzi o sam stół prices
można uczynić przechowywanie, SELECT
i INSERT
operacje znacznie bardziej wydajne użytecznej PRIMARY KEY
i bez kolumny AUTO_INCREMENT
. W poniższym schemacie Twój PRIMARY KEY
zawiera istotne informacje i nie jest zwykłą konwencją identyfikującą unikalne wiersze. Używanie MEDIUMINT
(3 bajty) zamiast INT
(4 bajty) zapisuje dodatkowy bajt na wiersz, a co ważniejsze 2 bajty na wiersz w PRIMARY KEY
- a jednocześnie zapewnia ponad 16 milionów możliwych dat i symboli ticker (każdy).
CREATE TABLE `prices` (
`market_day` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
`ticker_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
`price` decimal (7,2) NOT NULL DEFAULT '00000.00',
PRIMARY KEY USING BTREE (`market_day`,`ticker_id`),
KEY `ticker_id` USING BTREE (`ticker_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
;
W tym schemacie każdy rząd jest unikalne w każdej parze market_day
i ticker_id
. Tutaj ticker_id
odpowiada liście symbol giełdowy w tickers
stole z podobnego schematu do market_days
tabeli:
CREATE TABLE `tickers` (
`ticker_id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`ticker_symbol` VARCHAR(5),
`company_name` VARCHAR(50),
/* etc */
PRIMARY KEY USING BTREE (`ticker_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0
;
Daje podobny zapytanie do innych proponowane, ale z dwoma istotnymi różnicami: 1) Nie ma transformacja funkcjonalny w kolumnie daty, która niszczy zdolność MySQL do używania kluczy w sprzężeniu; w poniższym zapytaniu MySQL użyje części PRIMARY KEY
do dołączenia na market_day
. 2) MySQL może używać tylko jednego klucza na klauzulę JOIN
lub WHERE
. W tym zapytaniu MySQL użyje pełnej szerokości PRIMARY KEY
(market_day
i ticker_id
), podczas gdy w poprzednim zapytaniu może użyć tylko jednej (MySQL zwykle wybierze bardziej selektywny z dwóch).
SELECT
`market_days`.`date`,
`tickers`.`ticker_symbol`,
`yesterday`.`price` AS `close_yesterday`,
`today`.`price` AS `close_today`,
(`today`.`price` - `yesterday`.`price`)/(`yesterday`.`price`) AS `pct_change`
FROM
`prices` AS `today`
LEFT JOIN
`prices` AS `yesterday`
ON /* uses PRIMARY KEY */
`yesterday`.`market_day` = `today`.`market_day` - 1 /* this will join NULL for `today`.`market_day` = 0 */
AND
`yesterday`.`ticker_id` = `today`.`ticker_id`
INNER JOIN
`market_days` /* uses first 3 bytes of PRIMARY KEY */
ON
`market_days`.`market_day` = `today`.`market_day`
INNER JOIN
`tickers` /* uses KEY (`ticker_id`) */
ON
`tickers`.`ticker_id` = `today`.`ticker_id`
WHERE
`today`.`price` > 0
AND
`yesterday`.`price` > 0
;
Punkt drobniejsza jest potrzeba również dołączyć przeciwko tickers
i market_days
aby wyświetlić rzeczywiste ticker_symbol
i date
, ale te operacje są bardzo szybko, ponieważ wykorzystanie klawiszy.
@Scott: Dzięki za komentarz. Mogę zmienić znacznik czasu tylko na datę, aby ułatwić sobie pracę, a nie zajmować się zakresami. –
@Knix Funkcja daty jest całkiem czysta, nie wiem, ile jest kosztowna, ale z pewnością twoja rozmowa. Nadal istnieje problem z zamykaniem rynku w weekendy i święta. previousZamknij kolumnę eliminuje samo łączenie, niechlujność zamkniętych dni targowych kosztem duplikowania danych i konieczności uprzedniego zamknięcia przy wstawianiu dzisiejszego zamknięcia. – Scott
Dzięki ... Przyjmę twoją radę! –