如果你必须在 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 字节,那么您每月查看大约 8600 万行和 2.5GB,并且您不需要任何连接。如果所有值(列 key_value)都是整数或浮点数,则可以更改数据类型并进一步减少空间。
在 SQL 中实现键值存储的主要问题之一是,除非所有值都是相同的数据类型,否则您必须对所有值使用类似 varchar(n) 的东西。你失去了类型安全和声明性约束。(您无法检查 key3 的值是否在 1 和 15 之间,而 key7 的值在 0 和 3 之间。)
这可行吗?
这种结构(称为“EAV”--Google 认为)是一种众所周知的表格设计反模式。部分问题在于您实际上是将列存储为行。(您将列名存储在 key_value_store.key_name 中。)如果您必须以普通表的格式写出数据,您会发现三件事。
- 很难编写查询以输出正确的格式。
- 它需要永远运行。如果您必须编写数百列,它可能永远无法完成。
- 你会希望你有更快的硬件。快得多的硬件。
我在寻找什么
- 将键分组到逻辑表中的机会。这与第一个设计有关,它可能不适用于您。听起来您的应用程序基本上是在存储一个日志文件,并且您不知道每次运行时哪些键将具有值。
- 减少行数的机会。我会问,“我们能不能少写点?” 因此,我会考虑每 5 或 6 秒而不是每 3 秒写入一次数据库,假设这意味着我正在写入更少的行。(真正的目标是更少的行,而不是更少的写入。)
- 合适的平台。PostgreSQL 9.2 可能是一个更好的选择。9.2 版具有仅索引扫描,并且具有实现键值存储的 hstore 模块。
在你决定之前测试
如果我站在你的立场上,我会在 MySQL 和 PostgreSQL 中构建这个表。我会用大约一百万行随机数据加载每个。然后我会尝试一些查询和报告。(报告很重要。)衡量绩效。将负载增加到 1000 万行,重新调整服务器和 dbms,然后再次运行相同的查询和报告。再次测量。
重复 1 亿行。当你有信心时退出。预计这一切需要几天时间。