Было так много изменений, которые я должен был внести в свой первый ответ, я начинаю этот !!!
USE test
DROP TABLE IF EXISTS ngram_key;
DROP TABLE IF EXISTS ngram_rec;
DROP TABLE IF EXISTS ngram_blk;
CREATE TABLE ngram_key
(
NGRAM_ID UNSIGNED BIGINT NOT NULL AUTO_INCREMENT,
NGRAM VARCHAR(64) NOT NULL,
PRIMARY KEY (NGRAM),
KEY (NGRAM_ID)
) ENGINE=MyISAM ROW_FORMAT=FIXED PARTITION BY KEY(NGRAM) PARTITIONS 256;
CREATE TABLE ngram_rec
(
NGRAM_ID UNSIGNED BIGINT NOT NULL,
YR SMALLINT NOT NULL,
MC SMALLINT NOT NULL,
PC SMALLINT NOT NULL,
VC SMALLINT NOT NULL,
PRIMARY KEY (NGRAM_ID,YR)
) ENGINE=MyISAM ROW_FORMAT=FIXED;
CREATE TABLE ngram_blk
(
NGRAM VARCHAR(64) NOT NULL,
YR SMALLINT NOT NULL,
MC SMALLINT NOT NULL,
PC SMALLINT NOT NULL,
VC SMALLINT NOT NULL
) ENGINE=BLACKHOLE;
DELIMITER $$
CREATE TRIGGER populate_ngram AFTER INSERT ON ngram_blk FOR EACH ROW
BEGIN
DECLARE NEW_ID BIGINT;
INSERT IGNORE INTO ngram_key (NGRAM) VALUES (NEW.NGRAM);
SELECT NGRAM_ID INTO NEW_ID FROM ngram_key WHERE NGRAM=NEW.NGRAM;
INSERT IGNORE INTO ngram_rec VALUES (NEW_ID,NEW.YR,NEW.MC,NEW.PC,NEW.VC);
END; $$
DELIMITER ;
INSERT INTO ngram_blk VALUES
('rolando',1965,31,29,85),
('pamela',1971,33,21,86),
('dominique',1996,30,18,87),
('diamond',1998,13,28,88),
('rolando edwards',1965,31,29,85),
('pamela edwards',1971,33,21,86),
('dominique edwards',1996,30,18,87),
('diamond edwards',1998,13,28,88),
('rolando angel edwards',1965,31,29,85),
('pamela claricia edwards',1971,33,21,86),
('dominique sharlisee edwards',1996,30,18,87),
('diamond ashley edwards',1998,13,28,88);
UPDATE ngram_rec SET yr=yr+1,mc=mc+30,pc=pc+30,vc=vc+30;
INSERT INTO ngram_blk VALUES
('rolando',1965,31,29,85),
('pamela',1971,33,21,86),
('dominique',1996,30,18,87),
('diamond',1998,13,28,88),
('rolando edwards',1965,31,29,85),
('pamela edwards',1971,33,21,86),
('dominique edwards',1996,30,18,87),
('diamond edwards',1998,13,28,88),
('rolando angel edwards',1965,31,29,85),
('pamela claricia edwards',1971,33,21,86),
('dominique sharlisee edwards',1996,30,18,87),
('diamond ashley edwards',1998,13,28,88);
UPDATE ngram_rec SET yr=yr+1,mc=mc+30,pc=pc+30;
INSERT INTO ngram_blk VALUES
('rolando',1965,31,29,85),
('pamela',1971,33,21,86),
('dominique',1996,30,18,87),
('diamond',1998,13,28,88),
('rolando edwards',1965,31,29,85),
('pamela edwards',1971,33,21,86),
('dominique edwards',1996,30,18,87),
('diamond edwards',1998,13,28,88),
('rolando angel edwards',1965,31,29,85),
('pamela claricia edwards',1971,33,21,86),
('dominique sharlisee edwards',1996,30,18,87),
('diamond ashley edwards',1998,13,28,88);
UPDATE ngram_rec SET yr=yr+1,mc=mc+30;
SELECT * FROM ngram_key;
SELECT * FROM ngram_rec;
SELECT A.ngram NGram,B.yr Year,B.mc Matches,B.pc Pages,B.vc Volumes FROM
ngram_key A,ngram_rec B
WHERE A.ngram='rolando angel edwards'
AND A.ngram_id=B.ngram_id;
Гораздо меньшие таблицы для годовой информации, но гораздо большие ключи, чтобы сохранить исходный ngram. Я также увеличил количество тестовых данных. Вы можете вырезать и вставить это прямо в MySQL.
ПРЕДОСТЕРЕЖЕНИЕ
Просто удалите ROW_FORMAT, и он станет dymanic и сожмите таблицы ngram_key намного меньше.
Метрики DiskSpace
nrgram_rec имеет 17 байтов в строке
8 байтов для ngram_id (максимальное значение без знака 18446744073709551615 [2 ^ 64 - 1])
8 байтов для 4 строчных символов (по 2 байта в каждом)
1-байтовый внутренний флаг удаления MyISAM
Индексная запись для ngram_rec = 10 байт (8 (ngram_id) + 2 (год))
47 миллионов строк X 17 байтов в строке = 0799 миллионов байтов = 761,98577 МБ
47 миллионов строк X 12 байтов в строке = 0564 миллионов байтов = 537,85231 МБ
47 миллионов строк X 29 байтов в строке = 1363 миллиона байтов = 1,269393 ГБ
5 миллиардов строк X 17 байт на строку = 085 миллиардов байт = 079,1624 ГБ
5 миллиардов строк X 12 байт на строку = 060 миллиардов байт = 055,8793 ГБ
5 миллиардов строк X 29 байт на строку = 145 миллиардов байт = 135,0417 ГБ
ngram_key имеет 73 байта 64 байта для ngram (ROW_FORMAT = ИСПРАВЛЕНО установить varchar в char) 8 байтов для ngram_id 1 байт внутренний флаг удаления MyISAM
2 записи индекса для ngram_key = 64 байта + 8 байтов = 72 байта
47 миллионов строк X 073 байта на строку = 3431 миллион байтов = 3,1954 ГБ
47 миллионов строк X 072 байта на строку = 3384 миллиона байтов = 3,1515 ГБ
47 миллионов строк X 145 байтов на строку = 6815 миллионов байтов = 6,3469 ГБ
5 миллиардов строк X 073 байта на строку = 365 миллиардов байтов = 339,9327 ГБ
5 миллиардов строк X 072 байта на строку = 360 миллиардов байтов = 335,2761 ГБ
5 миллиардов строк X 145 байтов на строку = 725 миллиардов байтов = 675,2088 ГБ
Вот довольно дикое предложение
Конвертировать все нграммы в 32-символьные ключи MD5
Эта таблица будет содержать все нграммы любого размера (до 255 символов), 1 грамма, 2 грамма и т. Д.
Причина, по которой я выбрал 256 разделов, связана с тем, что функция MD5 возвращает 16 различных символов (все шестнадцатеричные цифры). Первые два байта - это 16 X 16, 256.
Вот результат в MySQL 5.5.11 на моем рабочем столе Windows 7
Пожалуйста, обратите внимание, что я загрузил 1-грамм, 2-грамм и 3-грамм в одну и ту же таблицу, но вы не знаете, какой MD5 принадлежит какому ngram. Таким образом, все ngram могут быть преобразованы в эту таблицу. Просто не забудьте вставить в таблицу ngram_blackhole, а все остальное за вас.
Вы должны запросить таблицу ngram_node, используя MD5 () ngram, независимо от того, какой ngram.
Если вы хотите разделить 1-грамм, 2-грамм и 3-грамм на отдельные репозитории, просто создайте другую таблицу, другую таблицу с черными дырами и еще один триггер на столе с черной дырой, чтобы вставить его в другую таблицу.
Кроме того, если ваши ngram длиннее 255 (если вы делаете 7 грамм или 8 грамм), просто увеличьте размер VARCHAR столбца NGRAM в таблице ngram_blackhole.
Попробуйте!
ОБНОВИТЬ
В вопросе было указано, что в MySQL было загружено 47 миллионов строк. Для моего предложенного расположения таблицы, пожалуйста, обратите внимание на следующее:
ngram_node - 41 байт на строку: 32 для NGRAM_KEY
8 для чисел (2 для каждого SMALLINT)
1 для внутреннего флага MyISAM DELETED
Каждая запись индекса первичного ключа будет 34 байта
32 для NGRAM_KEY
2 для NGRAM_YEAR
47 миллионов строк X 41 байт на строку = 1,927 миллиарда байтов, около 1,77966 ГБ.
47 миллионов строк X 34 байта на каждый элемент индекса = 1,598 миллиарда байтов, около 1,48825 ГБ.
Потребление таблицы MyISAM должно составлять примерно 3,28291 ГБ.
В вопросе также упоминается загрузка 5 миллиардов строк.
5 миллиардов строк X 41 байт в строке = 205 миллиардов байтов, что составляет около 190,9211 ГБ.
5 миллиардов строк X 34 байта на каждый элемент индекса = 170 миллиардов байтов, что составляет около 158,3248 ГБ.
Потребление таблицы MyISAM должно составлять примерно 349,2459 ГБ.
Обратите внимание, что скорость роста пространства, используемого в таблице MyISAM, линейна из-за первичного ключа постоянного размера. Теперь вы можете планировать дисковое пространство на основе этого.
источник