当前有一个表..并且需要开始向其中添加新的数据列。
不是每条记录(即使是新记录也是如此)添加新数据列后的数据)将具有数据。因此,我想知道这是否更适合新表,因为它实际上是某些数据行的扩展,并且不适用于每一行。换句话说,由于会有很多那些新数据元素的未使用列,看来这将更适合于新表?
第一个表是页面浏览量的记录(当前为200万条记录)
- id - IP address - times viewed - created_at timestamp - date
每天为每个IP地址创建一条记录-并将连续的网页浏览量添加到每天的浏览次数中
其他字段用于原点跟踪(即Google Analytics(分析)来源/媒介/广告系列)
并非每次访问都具有该信息。
我假设大约10%的行将具有该数据(因为通常仅在首次访问时才归因)。
数据的主要用途是归因于人来自何处。这可能会被更频繁地使用(然后似乎可以将其用于单个表)
欣赏反馈-如果需要,可以添加更多信息
#1 楼
您正在努力的是垂直分区。这是一种提高性能的物理数据库设计技术。与任何物理数据库设计技术一样,其适用性取决于您要优化的特定查询以及该技术是否可以优化它们。从逻辑的角度来看,如果这些新字段取决于您实体的候选键,则它们是与之相关的事实。首先,您应该确保您完全了解这些新字段对候选键的功能依赖性,以验证它们确实是有关每日页面浏览量的事实。如果是这样,则决定将它们分区到另一个表中是一项性能优化,只有在达到您的性能目标时才应该这样做。通常,如果不经常查询这些新列,则垂直分区很有用。与原始表格中的其他列明显不同。通过将这些列放在与现有表共享相同PK的另一个表中,可以在需要这些新列时直接查询它,并获得更大的吞吐量,因为此新表在磁盘上每页将有更多行因为原始表中的所有列都不会位于这些行上。但是,如果您总是将这些列与原始表中的列一起查询,那么垂直分区就没有多大意义,因为您将始终必须进行外部联接才能获取它们。磁盘上的表中的页面独立进入DBMS的缓冲池,永远不会预先加入,因此即使数据固定在缓冲池中,每次执行查询时都必须进行加入。在这种情况下,将它们设置为原始表上的NULLABLE列将使DBMS存储引擎能够在NULL时有效地存储它们,并消除了在检索时进行联接的需求。
在我看来,您的用例是后者,然后将它们作为NULLABLE添加到原始表中是可行的方法。但是,与数据库设计中的所有其他内容一样,它取决于并且为了做出正确的决定,您需要知道预期的工作量以及做出好的选择取决于什么。垂直分区的正确用例的一个很好的例子是人员搜索面板,该应用程序的应用程序中包含一些关于人员的极少数填充信息,而有人可能想要搜索但很少有人搜索。如果将这些信息放在另一个表中,则可以选择一些性能指标。您可以编写搜索,以便有2个查询-一个仅使用主要的,始终填充的信息进行搜索(例如姓氏或ssn),而另一个仅在请求搜索时将外部不频繁填充的信息连接起来。或者
,如果它足够聪明,可以识别给定的一组主机变量不需要外部联接并且不会执行外部联接,则可以利用DBMS优化器,因此您只需创建一个查询。
您正在使用什么DBMS平台?平台处理NULL列存储,优化查询的方式以及稀疏列支持的可用性(SQL Server具有此功能)都会影响决策。最终,我建议在具有生产规模的数据和工作负载的测试环境中尝试这两种设计,并查看哪种设计可以更好地实现您的性能目标。
#2 楼
我个人倾向于将列添加到现有表中。新表并没有真正为您买任何东西:您并没有真正节省太多空间,因为原始表中的NULL值不占用任何空间,而新表表需要某种标识符,该标识符仍可以抵消任何节省。
您的查询变得更加复杂...
where newcolumn is not null
变为left outer join
在单个表中,这仅意味着您的行大小可以随页面的不同而不同-但这不应该影响您现有的许多页面,尤其是当您的聚集索引位于单调递增的列(标识或日期/时间)上时。
评论
由于表格目前不宽(根据您的描述),并且该数据不会太宽,我同意。
–HLGEM
2012年5月25日13:44
#3 楼
给定您提供的信息,并且仅以一般归一化为目标,我可能会简单地添加可为空的列,但您没有提供足够的信息以了解如何使用数据来了解最佳的数据建模方法是。取决于您实际使用此数据的方式,您可能需要考虑其他数据模型。如果要将这些数据用于报告,则可能需要研究一个维度模型,该模型对于某些类型的报告可能会更有效-例如,按日期和时间维度划分出来的每日时间分析效果很好。
为了回答分析性问题,例如“在X等广告系列中,哪一天是访问次数最多的时段”或“我们在广告系列的哪一天中看到的每小时访问次数最多”,因此只需一个数据-time列不能很好地工作(但是甚至可以在关系模型中拆分它),并且在很多情况下,您可能会将IP地址视为一个维度(也许在一个地理数据库中包含某种地理数据)雪花)。
评论
我不清楚“什么意思”的意思,但是,如果始终将这些列与原始表中的列一起查询,那么垂直分区就没有多大意义,因为您将始终必须进行外部联接才能获得它们。 ,则仅在希望主要列(无论次要列是否可用)时才需要进行外部联接,否则,您将使用INNER JOIN,这在大多数情况下是有益的(减少查看的行数) )。
– jmoreno
2012年5月25日21:00
感谢您在这里提供的所有帮助。.实际上,我确实添加了字段,但经过仔细考虑之后,我发现我应该再使用几个其他表来更好地识别所有内容。最终到达的是visitor visitor_visits(具有一个visitor_id并包含源)page_views(具有vistor_id和visitor_visit_id),因为我想确切地知道哪个page_view归因于该访问,所以我添加了该链接。我努力了一下,但我认为这是正确的决定
– cgmckeever
2012年5月25日在21:47