我想正确设计我的数据库。也许有人可以帮助我。
我有一个设备可以将每3s大约100个键/值写入表中。 有人建议像这样存储它:
^ timestamp ^ key1 ^ key2 ^ [...] ^ key150 ^
| 12/06/12 | null | 2243466 | [...] | null ^
但我认为这完全是错误的而不是动态的。因为我可以有很多空值。 所以我尽力做到并设计了我在学校学到的东西: http://ondras.zarovi.cz/sql/demo/?keyword=tempidi
这是我为每个值编写的问题,时间戳意味着在100个值内它总是相同并产生大量数据。
有人可以告诉我如何减少数据库大小吗?我的ERM基本上是否正确?
答案 0 :(得分:1)
我不担心数据库大小。更大的问题是维护和灵活性。
这就是我要做的。首先,使用设备可以写入的可能键来定义和填充此表:
tblDataKey
(
ID int primary key (auto-increment - not sure how mysql does this)
Name varchar(32)
)
接下来定义'数据事件'表:
tblEvent
(
ID int primary key (auto-inc)
TimeStamp
...anything else you need - device ID's? ...
)
然后将事件与键及其值匹配:
tblEventData
{
EventID INT FK-to-tblEvent
KeyID INT FK-to-tblDataKey
DataValue varchar(???)
)
现在,无论您的数据是多少秒,您都可以在tblEvent中创建一个条目,在tblEventData中创建多个条目,并根据需要使用键值。并非每个事件都需要每个键,并且您可以在将来扩展键数。
这真的很闪耀,因为空间不会浪费,您可以轻松地使用特定数据键和值对evnet进行查询。当这种结构失效时,您需要生成“类似交叉表”的事件和数据项表。你必须决定这是不是一个问题。
答案 1 :(得分:0)
如果必须在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” - 谷歌认为)是众所周知的表格设计反模式。部分问题在于您实际上将列存储为行。 (您将列名存储在key_value_store.key_name中。)如果曾必须以普通表的格式写出数据,您将发现三件事。
我在寻找什么
在您决定之前进行测试
如果我在你的鞋子里,我会在MySQL和PostgreSQL中构建这个表。我将每个加载大约一百万行随机数据。然后我会尝试一些查询和报告。 (报告很重要。)衡量绩效。将负载增加到1000万行,重新调整服务器和dbms,并再次运行相同的查询和报告。再次测量。
重复1亿行。当你有信心时退出。预计所有这些都需要几天时间。