需要正确的数据库结构来减小大小

时间:2012-12-06 18:28:49

标签: mysql sql database-design entity-relationship

我想正确设计我的数据库。也许有人可以帮助我。

我有一个设备可以将每3s大约100个键/值写入表中。 有人建议像这样存储它:

  

^ timestamp ^ key1 ^ key2 ^ [...] ^ key150 ^

     

| 12/06/12 | null | 2243466 | [...] | null ^

但我认为这完全是错误的而不是动态的。因为我可以有很多空值。 所以我尽力做到并设计了我在学校学到的东西: http://ondras.zarovi.cz/sql/demo/?keyword=tempidi

这是我为每个值编写的问题,时间戳意味着在100个值内它总是相同并产生大量数据。

有人可以告诉我如何减少数据库大小吗?我的ERM基本上是否正确?

2 个答案:

答案 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中。)如果必须以普通表的格式写出数据,您将发现三件事。

  1. 编写查询以输出正确的格式很困难。
  2. 运行需要永远。如果必须编写数百列,则可能永远不会完成。
  3. 你希望你有更快的硬件。很多,很多更快的硬件。
  4. 我在寻找什么

    • 将密钥分组到逻辑表中的机会。这与第一个设计有关,它可能不适用于您。听起来您的应用程序基本上存储了一个日志文件,并且您不知道每次运行时哪些键都有值。
    • 减少行数的机会。我会问,“我们可以减少写作次数吗?”所以我会考虑每隔5或6秒而不是每3秒写一次数据库,假设这意味着我写的行数减少了。 (真正的目标是更少的行,而不是更少的写入。)
    • 正确的平台。 PostgreSQL 9.2可能是更好的选择。版本9.2具有仅索引扫描,并且它具有实现键值存储的hstore模块。

    在您决定之前进行测试

    如果我在你的鞋子里,我会在MySQL和PostgreSQL中构建这个表。我将每个加载大约一百万行随机数据。然后我会尝试一些查询和报告。 (报告很重要。)衡量绩效。将负载增加到1000万行,重新调整服务器和dbms,并再次运行相同的查询和报告。再次测量。

    重复1亿行。当你有信心时退出。预计所有这些都需要几天时间。