我有一个桌面应用程序,它具有名为Field
的实体的概念。
-----------------------
| Id | FieldName |
-----------------------
| 1 | "Field 1" |
-----------------------
| 2 | "Field 2" |
-----------------------
Field
由用户定义,因此可以有多个用户想要的。它们与另一个名为Employee
的实体相关联。
Field
有一个值(由应用程序计算和存储的16位整数)。
Field
个值存储在一个表格中,其中每个记录包含一个Employee
个Field
的一整年的值。
因此,所述表看起来有点像这样:
---------------------------------------------
| FieldId | EmployeeId | FieldValues | Year |
---------------------------------------------
| 1 | 4 | byte[] | 2012 |
---------------------------------------------
| 2 | 4 | byte[] | 2012 |
---------------------------------------------
| 1 | 5 | byte[] | 2013 |
---------------------------------------------
| ... | ... | ... | ... |
---------------------------------------------
FieldValues将值保存为BLOB字段中的字节数组,然后在向网格上的用户显示之前将其转换回16位整数数组。
现在我们有了一些背景,真正的问题。
这是一款传统应用,我不是原创设计师。但是,很容易猜到,以二进制格式存储这些数据的目的是限制每年每Employee
Field
每年存储365(或366)值所需的记录数量。 }}
我现在正在做的是一个“同步”应用程序,它从本地Access数据库中提取此数据(不要求),并通过REST API将其推送到远程服务器上的Web应用程序。 此类应用需要拥有此数据的副本,因此我必须将其存储在数据库中。
以二进制格式存储数据具有明显的优势,即真正限制我们需要存储的记录数量,但缺点是人为不可读。
另一方面,网络应用程序是多租户的,因此以任何其他方式存储这些数据意味着存储大量记录:只有几千Employee
秒,平均为20 {{ 1}} s意味着每年存储超过1400万条记录(并且Field
不是唯一可以生成数百万条记录的实体)。另外,每年大量的记录本身不会成为一个问题,如果在路上的某个地方,比如每两三年,我们就可以扔掉它们;但事实并非如此。
然后,真正的问题是如何来存储所述数据。我应该坚持旧格式吗?
任何人都可以想到一种完全不同的方式吗?
为了完整起见,即使我认为不重要,目标数据库也是Postgres。
答案 0 :(得分:1)
如果可能的话,你应该正确地规范化这些数据。
以下是一些原因。
以二进制格式存储数据具有明显的优势 限制我们需要存储的记录数量,但缺点 是人类不可读的。
您还缺少其他一些缺点,包括增加并发性,因为您必须重新编写所有值。对这些数据的查询都不是SARGable,你不能在db级别上限制这些数据,基本上你违反1NF时遇到的所有问题
另外,每年大量的记录本身不会成为问题 如果在路上的某个地方,比如说每两三年,我们可以扔掉它们;但事实并非如此。
我想不出您没有数据保留政策的正当理由。这样做非常危险。
另一方面,网络应用程序是多租户,因此存储此数据 以任何其他方式意味着存储大量记录:只是一个 几千名员工和平均20个领域意味着 每年存储超过1400万条记录
这不是很多记录。通常情况下,您存储的数据量往往是首先出现的问题。其中大部分都被FieldValues中的数据占用,而不是数据库必须执行的内部簿记。