我想要将对"entity"表所做的更改保存下来,类似于日志记录。当前在MySQL中实现的方式是使用以下表:
CREATE TABLE `entitychange` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`entity_id` int(10) unsigned NOT NULL,
`entitytype` enum('STRING_1','STRING_2','SOMEBOOL','SOMEDOUBLE','SOMETIMESTAMP') NOT NULL DEFAULT 'STRING_1',
`when` TIMESTAMP NOT NULL,
`value` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
entity_id
是我的entity
表的主键。entitytype
是在entity
表中更改的字段。有时只更改一个字段,有时更改多个。一次更改=一行。value
是字段“新值”的字符串表示形式。
例如将字段entity.somedouble
从3更改为2时,运行以下查询:
UPDATE entity SET somedouble = 2 WHERE entity_id = 123;
INSERT INTO entitychange (entity_id,entitytype,value) VALUES (123,'SOMEDOUBLE',2);
我需要选择特定实体和实体类型最近15天的更改。例如:在最近15天内,具有SOMEDOUBLE
的实体ID 123
的最新更改。
现在,有两件事我不喜欢:
- 所有数据都存储为
TEXT
——尽管大多数(少于1%)实际上并不是文本,在我的情况下,大多数值是DOUBLE
。这是个大问题吗? - 由于表已经有2亿行,因此插入速度变得非常缓慢。目前我的服务器负载已经达到10-15。
我的问题:如何解决这两个"瓶颈"?我需要扩展。
我的方案如下:
- 像这样存储:http://sqlfiddle.com/#!2/df9d0 (点击浏览)——将更改存储在
entitychange
表中,然后按其数据类型在entitychange_[bool|timestamp|double|string]
中存储值 - 使用
HASH(entity_id)
进行分区——我考虑了大约50个分区。 - 我应该使用另一个数据库系统,比如MongoDB吗?