2012-07-19 66 views
0

我们有一个数据库表,有太多的行。为了加快性能,我们正在尝试创建一个汇总表。这对于一对一的关系非常有用。例如假设furniture有一个type和一个manufacturer_id,您可以拥有一个包含这两列和一个counts列的表。查询该表很容易,并能很快得到给定类型的家具数量。有没有办法为多对多关系创建一个汇总表?

但是,如果存在多对多关系呢?所以每件家具也可以有一个或多个colors以及一个或多个distributors。那么会发生什么?有什么方法可以总结这些数据,这样我就可以快速找到有多少家具是绿色的?或多少蓝色和黄色?

显然这只是一个编造的例子。但给了一个巨大的数百万和数百万行的数据库表,我如何创建一个汇总表来快速查找汇总信息?

回答

0

多个表应该保持较小的尺寸......良好的数据库系统应该保持性能。

在我看来,保留一个单独的“汇总表”会产生很多开销和维护问题,并且只有反复使用相同的汇总信息才会非常有用(例如,有多少家具是绿色的,许多是蓝色的,多少是黄色的,蓝色和黄色的多少等等,等等。)

我会做的是:

表1:家具

  • 1列:UNIQUEID
  • 2列:命名

表2:经销商

  • 第1列:uniqueID
  • 第2栏:名称

表3:色

  • 第1栏:UNIQUEID
  • 第2栏:命名

表4:家具分配器

  • 第1栏:furnitureUn iqueIDvalue
  • 2列:distributorUniqueIDvalue

表5:家具颜色

  • 1列:furnitureUniqueIDvalue
  • 2列:colorUniqueIDvalue

多少家具是绿色:

SELECT COU NT(*)FROM furniture-color WHERE colorUniqueIDvalue ='green ID';

多少家具都是蓝色和黄色:

SELECT COUNT(*)FROM家具颜色为T1 INNER JOIN家具颜色为t2 ON t1.furnitureUniqueIDvalue = t2.furnitureUniqueIDvalue AND t1.colorUniqueIDvalue =“蓝ID'AND t2.colorUniqueIDvalue ='yellow ID';

通过正确的SQL语句(留给读者的练习),可以获得蓝色和黄色家具的分销商列表,或者来自特定分销商的家具或绿色或红色的家具,或大多数其他物品。

+0

因此,如果我的理论家具企业拥有2亿件家具,会发生什么?那么家具分销商和家具的颜色将甚至超过2亿行,并试图查询哪些家具来自经销商'ikea',而'红色'和'黄色'将永远(或更长)。因此汇总表...能够快速查询汇总数据的原因。 – user1315943 2012-07-19 18:32:29

+0

生成汇总表可能是您需要的解决方案,但请记住,您有创建和维护它们的开销,并且您将不得不提前猜测多对多关系的每种可能组合。我还会指出,家具分销商和家具色表每个只有两个领域。即使你有十亿条记录,所需的磁盘空间仍然会小于我上周末在航展上拍摄的数字照片的空间。 – LavaSlider 2012-07-25 05:33:01

+0

这不是我担心的磁盘空间..它正在查询一张有十亿条记录的表 – user1315943 2012-07-25 21:11:54

1

假设你知道你在做什么,并知道这是一个真正的瓶颈:你现在有衡量表现吗?你知道从哪里开始花时间吗?

无论如何,您将不得不查询数据库以获取该数据。因此,您可以将其存储在单独的表格中,如颜色计数和分配器计数。另一个解决方案是将这些查询的结果缓存在缓存系统中。例如,如果你有memcached或其他一些工具已经在使用。

最简单的,当你只是有一个数据库仅仅是创建一个表:

table color count 
color_id 
amount 

这是一个非常简单的查询。您可以非常好地编制索引,不需要连接。

更新可以使用触发器,使用cron或在更新多对多表格时完成。取决于你的需求和能力。考虑到更新记录也需要时间,所以用它来优化读取,这就是我在你的问题中读到的内容。

+0

颜色计数表可以在一对一的情况下完美运行(我们实际上已经这样做了)。但它对许多人来说又是如何工作的?我怎么能够找到蓝色和黄色的家具? – user1315943 2012-07-19 18:35:35

+0

如果你需要寻找真正的记录,那么不是蓝色和黄色家具的数量,那么你将不得不加入原始记录。如果您只需要计数,则可以将其存储在例如2个字段中:color1_id color2_id。然后,您先订购最小的颜色代码。所以你可以搜索:SELECT amount FROM colorcount WHERE color1_id = 222 AND color2_id = 333。无需加入,分组或任何其他。但首先,在设定之前考虑一下真正有必要的东西。 – 2012-07-20 11:00:08

+0

但这是一个*多对多的关系。一件家具有很多颜色。如果我想检查家具是如何变成绿色,红色,蓝色和黄色......那么......我需要4色的cols? – user1315943 2012-07-23 18:33:16

0

您需要区分计算不同类型的家具(不同的家具编号)和计算实际家具的数量。

如果您有分配器颜色表,那么您可以计算实际的家具。但是,您无法计算不同类型的家具。这是OLAP术语中加法事实和非加法事实之间的区别。如果您对这个主题感兴趣,请查看Ralph Kimball和他的经典着作“数据仓库工具包”。

要计算家具类型,您需要将其包含在您的表格中。所以,你需要一个分配器颜色家具表。我们得到总的经销商,你可以使用:

select distributor, count(distinct furnitureid) 
from dcf 
group by distributor 

也是类似的颜色。

您似乎想要将您的原始数据转换为事实数据表中的每个报告。这对于开发数据集市来说是一个非常好的标准理念。你的数据集市可以有两个事实表。每种类型的家具一个(所以你可以轻松地处理制造问题)和其他分配器颜色家具(用于更难的问题)。

某些数据库(如Oracle和SQL Server)支持这些类型的数据结构。你所说的更像是一个新的“系统”,而不仅仅是一个新的“表格”。您需要考虑事实表的维度,更新以及您需要的报告类型。

0

将会有2^n颜色汇总表中的可能行,其中'n'是颜色的数量。如果减少颜色为位图,并指定每个颜色的位置(红色= 0,橙= 1,黄色= 2,绿色= 3,等等),那么你的颜色汇总表可能是:

Color Count 
0x0001 256 
0x0002 345 
0x0003 23839 
etc. 

256只有红色,345只有橙色,23,839有红色和橙色。要计算有多少红色,但可能有其他颜色,则需要对位置0设置的行进行求和。另外一个单独的汇总表可以设置为只有'n'条目,每种颜色一个,以避免汇总行。

如果你想要汇总表来管理分销商和颜色,那么我认为它会有2^n * 2^m行(其中'm'是分销商的数量)具有所有多重组合可能有多种颜色的多件家具的分销商。

相关问题