我目前正在探索HDF5。我已经阅读了“评估 HDF5 ”线程中的有趣评论,并且我知道 HDF5 是存储数据的首选解决方案,但是您如何查询它呢?例如,假设我有一个包含一些标识符的大文件:有没有办法快速知道文件中是否存在给定的标识符?
4 回答
我认为答案是“不直接”。
以下是我认为您可以实现该功能的一些方法。
使用组:
可以以基数树的形式使用组的层次结构来存储数据。不过,这可能无法很好地扩展。
使用索引数据集:
HDF 有一个引用类型,可用于从单独的索引表链接到主表。写入主数据后,可以使用在其他带有引用的键上排序的其他数据集。例如:
MainDataset (sorted on identifier)
0: { A, "C", 2 }
1: { B, "B", 1 }
2: { C, "A", 3 }
StringIndex
0: { "A", Reference ("MainDataset", 2) }
1: { "B", Reference ("MainDataset", 1) }
2: { "C", Reference ("MainDataset", 0) }
IntIndex
0: { 1, Reference ("MainDataset", 1) }
1: { 2, Reference ("MainDataset", 0) }
2: { 3, Reference ("MainDataset", 2) }
为了使用上面的二进制搜索,在索引表中查找字段时必须编写二进制搜索。
内存索引:
根据数据集的大小,使用诸如“boost::serialize”之类的方式读取/写入其自己的数据集的内存索引可能同样容易。
HDF5-快速查询:
在 HDF5 1.8.0 中为此引入了H5Lexists :
http://www.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Exists
您还可以使用H5Literate遍历 HDF5 文件中的内容:
http://www.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Iterate
但是您也可以通过尝试打开数据集来手动检查以前的版本。我们使用这样的代码来处理任何版本的 HDF5:
bool DoesDatasetExist(const std::string& rDatasetName)
{
#if H5_VERS_MAJOR>=1 && H5_VERS_MINOR>=8
// This is a nice method for testing existence, introduced in HDF5 1.8.0
htri_t dataset_status = H5Lexists(mFileId, rDatasetName.c_str(), H5P_DEFAULT);
return (dataset_status>0);
#else
bool result=false;
// This is not a nice way of doing it because the error stack produces a load of 'HDF failed' output.
// The "TRY" macros are a convenient way to temporarily turn the error stack off.
H5E_BEGIN_TRY
{
hid_t dataset_id = H5Dopen(mFileId, rDatasetName.c_str());
if (dataset_id>0)
{
H5Dclose(dataset_id);
result = true;
}
}
H5E_END_TRY;
return result;
#endif
}
也许这篇论文对你很有帮助。 http://www.cse.ohio-state.edu/~wayi/papers/HDF5_SQL.pdf
这是你需要的吗?您可以使用声明性语言 SQL 查询 HDF5 数据。
与 FastQuery 不同的是,这项工作没有索引,但我们组也提供了一个带有位图索引的开源版本。
而且,如果要实时完成查询(尤其是聚合),应该考虑近似聚合或者在线聚合。我还开发了一些直接在 HDF5 上工作的产品。
此外,一些基于 HDF5 的查询可能比您在关系数据库中看到的要复杂得多。有些查询是面向数组的,而不是面向关系表的。只需谷歌“SciQL”,您就可以找到一些复杂且独特的基于数组的数据模型的查询类型,这当然可以应用于 HDF5。您是否需要执行此类查询?我还开发了一个产品来支持那里的一些复杂查询类型。
标识符是什么意思?如果您指的是属性,请查看本教程。在 C 中:
status = H5Aread(attr_id, mem_type_id, buf);
status = H5Awrite(attr_id, mem_type_id, buf);