如果你要必须在MySQL中实现一个键值存储,那么使它比这更复杂没有任何意义。
create table key_value_store (
run_time datetime not null,
key_name varchar(15) not null,
key_value varchar(15) not null,
primary key (run_time, key_name)
);
如果你的关键字和值两者的平均长度为10字节,你看约86万行,每月2.5GB,你不需要任何连接。如果所有值(列key_value)都是整数或浮点数,则可以更改数据类型并减少一点空间。
一个与SQL实现键值存储的主要问题是,除非所有值都相同的数据类型,你必须使用所有值类似VARCHAR(n)的。你失去了类型安全和声明约束。 (您不能检查key3的值是否在1和15之间,而key7的值是在0和3之间。)
这可行吗?
这种结构(称为“EAV” - 谷歌的那种)是一种众所周知的餐桌设计反模式。问题的一部分是你基本上将列存储为行。 (您在key_value_store.key_name中存储了列名。)如果您有有史以来必须以正常表的格式写出数据,您会发现三件事。
- 很难编写查询来输出正确的格式。
- 需要永久运行。如果您必须编写数百个列,它可能永远不会完成。
- 你会希望你有更快的硬件。很多,很多更快的硬件。
我寻找什么
- 机遇组键进入逻辑表。这与第一个设计有关,它可能不适用于你。这听起来就像你的应用程序基本上存储了一个日志文件,并且你不知道每次运行哪些键会有值。
- 减少行数的机会。我会问,“我们可以少写一遍吗?”所以我会考虑每5秒或6秒写入数据库,而不是每3秒写一次,假设这意味着我正在写更少的行。 (真正的目标是更少的行数,而不是更少的写入数量。)
- 合适的平台。 PostgreSQL 9.2可能是更好的选择。版本9.2具有仅索引扫描,并且它具有实现键值存储的hstore模块。
测试你决定
如果我是你的话,我会在这两个MySQL和PostgreSQL构建这个表之前。我会加载大约一百万行随机数据。然后,我会尝试一些查询和每个报告。 (报告很重要。)衡量绩效。将负载增加到1000万行,重新调整服务器和dbms,然后再次运行相同的查询和报告。再次测量。
重复1亿行。当你有信心时退出。预计这一切需要几天。
您是否关注通过将相同的时间戳写入100行所使用的磁盘空间? –
是的。 我的计算是: 100值* 16bytes * 24(h)* 60(min)* 60(s)* 30(month)= 3.8GB /月 –
无论谁建议像这样存储不应该推荐数据库楷模。 – Kermit