情况就是这样:我正在创建一个每天运行的批处理脚本,解析日志文件并将数据导出到数据库。该文件的格式基本上是
std_prop1;std_prop2;std_prop3;[opt_prop1;[opt_prop2;[opt_prop3;[..]]]
标准属性映射到一个表,每个属性都有一列,其中日志文件中的每一行基本上都映射到相应的行。它可能看起来像LOGDATA(id,timestamp,systemId,methodName,callLenght)
。由于我们应该能够记录尽可能多的可选属性,因此我们无法将它们映射到同一个表,因为这意味着每次引入新属性时都会在表中添加一行。不要考虑NULL
引用的数量......
所以附加属性会放在另一个表中,比如EXTRA_PROPS(logdata_foreign_key,propname,value)
。实际上,大多数可选属性都是相同的(例如os版本,app容器等),因此在LOGDATA中为每行记录例如EXTRA_PROPS中的4行有点浪费(在平均有4行额外的情况下)属性)。所以我希望我的批处理工作是
for each additionalProperty in logRow:
see if additionalProperty already exist
if exists:
create a reference to it in a reference table
if not:
add the property to the extra properties table
create a reference to it in a reference table
那么我可能会有三个略有不同的表格:
LOGDATA(id,timestamp,systemId,methodName,callLenght)
EXTRA_PROPS(id,propname,value)
LOGDATA_HAS_EXTRA_PROPS(logid,extra_prop_id)
我不是100%这是一个更好的方法,我仍然会在LOGDATA_HAS_EXTRA_PROPS
表中为N个属性创建N行,但至少我不会向{{1}添加任何新行}。
即使这可能不是最好的方式(什么是?),我仍然想知道技术方面:我将如何使用Hibernate实现这一点?它不一定是超快的,但它需要咀嚼100K +行。
答案 0 :(得分:1)
首先,我不建议将Hibernate用于此类逻辑。 Hibernate是一款出色的产品,但进行这种高负载数据操作可能不是最强大的。
从数据建模的角度来看,我认为(propname,value)
实际上是EXTRA_PROPS
中的主键。基本上,您希望表达一种逻辑,例如,hostname
+ foo.bar.com
组合只会在表格中出现一次。我对吗?这将是PK。因此,您需要在LOGDATA_HAS_EXTRA_PROPS
中使用它。单独使用name
将不足以供参考。
在Hibernate中(如果您选择使用它),可以使用映射到@EmbeddedId
的对象上的Embeddable
或EXTRA_PROPS
通过组合键表示。然后,您可以使用LOGDATA_HAS_EXTRA_PROPS
作为关联表的多对多关系。