我被要求为某个站点优化(大小)统计系统,我注意到它们在一个表中存储了2组统计数据。这些集合是搜索列表上的产品显示和产品页面上的访问。每行都有产品ID,统计日期,统计计数和统计标志列。标志列指示它是搜索列表显示还是页面访问统计。统计数据每天存储,产品ID,统计日期(实际上与产品ID和统计类型相结合)和统计数据都有索引。
我想知道将这两个集合存储为单独的表或将它们保存为单个表是否更好(大小方面)。我认为产生差异的部分将是标志列(比如它的1字节TINYINT)和索引。我特别感兴趣的是索引占用的空间如何在2表格场景中发生变化。有问题的表已有几百万条记录。
当我有更多时间时,我可能会做一些测试,但我想知道是否有人已经挑战了类似的问题。
答案 0 :(得分:1)
通常,如果两种观察结果一致,最好将它们保存在一个表中。通过“顺应”,我的意思是他们的基本数据是相同的。
您的观察结果似乎确实符合要求。
为什么会这样?
首先,您可以轻松地添加更多符合要求的观察结果。例如,您可以通过向标志列添加新值来向搜索列表和产品页面视图添加销售。
其次,您可以很容易地报告各种观察的组合。如果将这些内容分成不同的表,那么当你想要将它们重新组合在一起时,你将会进行UNIONs或JOIN。
第三,正确完成索引时,访问时间基本相同。
第四,磁盘空间使用量的差异很小。在任何一种情况下都需要索引。
第五,磁盘空间成本的差异是微不足道的。你有几百万行,换句话说,有十几个千兆字节。最高质量的亚马逊网络服务存储每年每GB大约需要1.00美元。这比你花在重构这些东西的那一天花费的办公室热量还要少。随它去。
答案 1 :(得分:0)
最后我有时间进行测试。这只是一个小规模的测试,有12k和48k的记录。
存储两种类型数据的表具有以下结构:
CREATE TABLE IF NOT EXISTS `stat_test` (
`id_off` int(11) NOT NULL,
`stat_date` date NOT NULL,
`stat_count` int(11) NOT NULL,
`stat_type` tinyint(11) NOT NULL,
PRIMARY KEY (`id_off`,`stat_date`,`stat_type`),
KEY `id_off` (`id_off`),
KEY `stat_count` (`stat_count`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2;
另外两个表格具有以下结构:
CREATE TABLE IF NOT EXISTS `stat_test_other` (
`id_off` int(11) NOT NULL,
`stat_date` date NOT NULL,
`stat_count` int(11) NOT NULL,
PRIMARY KEY (`id_off`,`stat_date`),
KEY `id_off` (`id_off`),
KEY `stat_count` (`stat_count`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2;
在12k记录的情况下,2个单独的表实际上比存储所有内容的表略大,但是对于48k记录,两个表更小并且具有明显的值。
最后我没有将数据分成两个表来解决我的初始空间问题。通过删除冗余的id_off
索引并调整数据类型(大多数情况下unsigned smallint
足以存储我需要的所有值),我设法大大减小了数据库的大小。请注意,最初的stat_type
也属于int
类型,此列unsigned tinyint
已足够。总而言之,这将数据库的大小从1.5GB减少到600MB(我的数据库限制只有2GB)。这个解决方案的另一个优点是我不需要修改一行代码就可以使一切工作(因为该网站是由其他人编写的,我没有花费数小时试图理解源代码)