2010-06-02 49 views
2

我正在存储一些非常基本的信息“数据源”进入我的应用程序。这些数据源可以是文档(例如PDF等),音频(例如MP3等)或视频(例如AVI等)的形式。比方说,我只对数据源的文件名感兴趣。因此,我有下表:具有属性的实体的数据建模

DataSource 
Id (PK) 
Filename 

对于每个数据源,我还需要存储它的一些属性。 PDF示例将是“页数”。音频示例将是“比特率”。视频示例将是“持续时间”。每个DataSource对于需要存储的属性都有不同的要求。所以,我仿照“数据源属性”是这样的:

DataSourceAttribute 
Id (PK) 
DataSourceId (FK) 
Name 
Value 

因此,我会像这样的记录:

DataSource->Id = 1 
DataSource->Filename = 'mydoc.pdf' 

DataSource->Id = 2 
DataSource->Filename = 'mysong.mp3' 

DataSource->Id = 3 
DataSource->Filename = 'myvideo.avi' 

DataSourceAttribute->Id = 1 
DataSourceAttribute->DataSourceId = 1 
DataSourceAttribute->Name = 'TotalPages' 
DataSourceAttribute->Value = '10' 

DataSourceAttribute->Id = 2 
DataSourceAttribute->DataSourceId = 2 
DataSourceAttribute->Name = 'BitRate' 
DataSourceAttribute->Value '16' 

DataSourceAttribute->Id = 3 
DataSourceAttribute->DataSourceId = 3 
DataSourceAttribute->Name = 'Duration' 
DataSourceAttribute->Value = '1:32' 

我的问题是,这似乎并没有成比例的。例如,说我需要为所有的PDF文档与thier总页数以及查询:

Filename, TotalPages 
'mydoc.pdf', '10' 
'myotherdoc.pdf', '23' 
... 

的加入需要产生以上结果实在太昂贵。我应该如何解决这个问题?

回答

0

缩放是与EAV(实体 - 属性 - 值)的数据结构中最常见的问题之一。总之,你必须要求元数据(即找到属性)来获取数据。然而,这里是一个查询,你可以用它来得到你想要的数据:

Select DataSourceId 
    , Min(Case When Name = 'TotalPages' Then Value End) As TotalPages 
    , Min(Case When Name = 'BitRate' Then Value End) As BitRate 
    , Min(Case When Name = 'Duration' Then Vlaue End) As Duration 
From DataSourceAttribute 
Group By DataSourceId 

为了提高性能,你会想在的DataSourceID的指数,或许命名为好。要获得您发布的结果,您应该这样做:

Select DataSource.FileName 
    , Min(Case When DataSourceAttribute.Name = 'TotalPages' Then Value End) As TotalPages 
    , Min(Case When DataSourceAttribute.Name = 'BitRate' Then Value End) As BitRate 
    , Min(Case When DataSourceAttribute.Name = 'Duration' Then Vlaue End) As Duration 
From DataSourceAttribute 
    Join DataSource 
     On DataSource.Id = DataSourceAttribute.DataSourceId 
Group By DataSource.FileName 
0

看起来好像你想要的东西比典型的关系数据库更有损失。听起来像是LuceneMongoDB的好候选人。 Lucene是一个索引引擎,它允许存储和索引任何类型的文档。 MongoDB处于RDBMS和自由格式文档存储之间。 JSON以某种形式或其他(MongoDB就是一个很好的例子)应该很好地适应。

+0

我不确定是否准备向应用程序中引入其他技术。现在,我想通过适当的数据建模来解决这个问题。 – StackOverflowNewbie 2010-06-02 23:04:42

0

这可能会实现,但定义过于昂贵...

select 
datasource.id, 
d1.id as d1id, 
d1.value as d1filename, 
d2.id as d2id, 
d2.value as d2totalpages 

from datasource 
inner join datasourceattribute d1 
on datasource.id = d1.datasourceid and d1.name = 'filename' 
inner join datasourceattribute d2 
on datasource.id = d2.datasourceid and d2.name = 'totalpages' 
having d1filename like '%pdf' 
+0

@Zak:我的查询基本上和你的一样。我跑了388个查询,执行了255.7976秒。对于如此少量的记录,这已经超过4分钟了,不是吗? – StackOverflowNewbie 2010-06-02 23:09:36

+0

你的表格索引是什么样的? – Zak 2010-06-02 23:11:16

+0

也,前缀这个查询与“解释”,然后在你的命令行中运行,然后发布结果... – Zak 2010-06-02 23:12:03

相关问题