Hubo tantos cambios que tendría que hacer a mi primera respuesta. ¡Comienzo esta!
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;
Tablas mucho más pequeñas para información del año pero claves mucho más grandes para preservar el ngram original. También aumenté la cantidad de datos de prueba. Puede cortar y pegar esto directamente en MySQL.
CONSIDERACIÓN
Simplemente elimine ROW_FORMAT y se vuelve dinámico y comprima las tablas ngram_key mucho más pequeñas.
DiskSpace Metrics
nrgram_rec tiene 17 bytes por fila
8 bytes para ngram_id (valor máximo sin signo 18446744073709551615 [2 ^ 64 - 1])
8 bytes para 4 letras pequeñas (2 bytes cada una)
Indicador de eliminación interna MyISAM de 1 byte
Entrada de índice para ngram_rec = 10 bytes (8 (ngram_id) + 2 (año))
47 millones de filas X 17 bytes por fila = 0799 millones de bytes = 761.98577 MB
47 millones de filas X 12 bytes por fila = 0564 millones de bytes = 537.85231 MB
47 millones de filas X 29 bytes por fila = 1363 millones de bytes = 1.269393 GB
5 mil millones de filas X 17 bytes por fila = 085 mil millones de bytes = 079.1624 GB
5 mil millones de filas X 12 bytes por fila = 060 mil millones de bytes = 055.8793 GB
5 mil millones de filas X 29 bytes por fila = 145 mil millones de bytes = 135.0417 GB
ngram_key tiene 73 bytes 64 bytes para ngram (ROW_FORMAT = FIXED set varchar to char) 8 bytes para ngram_id 1 byte Indicador interno de eliminación de MyISAM
2 entradas de índice para ngram_key = 64 bytes + 8 bytes = 72 bytes
47 millones de filas X 073 bytes por fila = 3431 millones de bytes = 3.1954 GB
47 millones de filas X 072 bytes por fila = 3384 millones de bytes = 3.1515 GB
47 millones de filas X 145 bytes por fila = 6815 millones de bytes = 6.3469 GB
5 mil millones de filas X 073 bytes por fila = 365 mil millones de bytes = 339.9327 GB
5 mil millones de filas X 072 bytes por fila = 360 mil millones de bytes = 335.2761 GB
5 mil millones de filas X 145 bytes por fila = 725 mil millones de bytes = 675.2088 GB
Aquí hay una sugerencia bastante salvaje
Convierta todos los ngrams a claves MD5 de 32 caracteres
Esta tabla contendrá todos los ngrams de cualquier tamaño (hasta 255 caracteres), 1 gramo, 2 gramos, etc.
La razón por la que elegí 256 particiones se debe al hecho de que la función MD5 devuelve 16 caracteres distintos (todos los dígitos hexadecimales). Los primeros dos bytes son 16 X 16, 256.
Aquí estaba el resultado en MySQL 5.5.11 en mi escritorio de Windows 7
Tenga en cuenta que cargué 1 gramos, 2 gramos y 3 gramos en la misma tabla, pero no tiene idea de qué MD5 pertenece a qué ngram. Por lo tanto, todos los ngrams pueden adaptarse a esta tabla. Solo recuerde insertar en la tabla ngram_blackhole y el resto ya está hecho.
Debe consultar la tabla ngram_node utilizando el MD5 () del ngram sin importar qué ngram.
Si desea separar 1-gramos, 2-gramos y 3-gramos en repositorios separados, simplemente cree otra tabla, otra tabla de agujeros negros y otro disparador en la tabla de agujeros negros para insertar en la otra tabla.
Además, si sus ngrams son más largos que 255 (si está haciendo 7 gramos u 8 gramos) simplemente aumente el tamaño VARCHAR de la columna NGRAM en la tabla ngram_blackhole.
Darle una oportunidad !!!
ACTUALIZAR
En la pregunta, se afirmó que 47 millones de filas se cargaron en mysql. Para mi diseño de tabla sugerido, tenga en cuenta lo siguiente:
ngram_node es 41 bytes por fila: 32 para NGRAM_KEY
8 para los números (2 para cada SMALLINT)
1 para el distintivo interno MyISAM DELETED
Cada entrada de índice de clave principal sería de 34 bytes
32 para NGRAM_KEY
2 para NGRAM_YEAR
47 millones de filas X 41 bytes por fila = 1.927 mil millones de bytes, aproximadamente 1.79466 GB.
47 millones de filas X 34 bytes por entrada de índice = 1.598 mil millones de bytes, aproximadamente 1.48825 GB.
El consumo de la tabla MyISAM debe ser de un total combinado de 3.28291 GB.
La pregunta también mencionó cargar 5 mil millones de filas.
5 mil millones de filas X 41 bytes por fila = 205 mil millones de bytes, aproximadamente 190.9211 GB.
5 mil millones de filas X 34 bytes por entrada de índice = 170 mil millones de bytes, aproximadamente 158.3248 GB.
El consumo de la tabla MyISAM debería ser de un total combinado de 349.2459 GB.
Tenga en cuenta que la tasa de crecimiento del espacio utilizado en la tabla MyISAM es lineal debido a la clave primaria de tamaño constante. Ahora puede planificar el espacio en disco basándose en esto.
fuente