【问题标题】:Storing vast amounts of (simple) timeline graph data in a DB在数据库中存储大量(简单)时间线图数据
【发布时间】:2010-07-14 21:54:06
【问题描述】:

我需要存储播客/音频文件每秒的播放次数。这将生成一个简单的时间线图(如 Google Analytics 中的“点击”图),x 轴为秒,y 轴为播放时间。

但是,这些播客可能会持续长达 3 小时,每秒播放 100,000 次并非不现实。那是 10,800 秒,每次播放多达 100,000 次。显然,将每个播放的秒数存储在自己的行中是不现实的(这将导致 1+ 十亿行),因为我希望能够快速获取这些原始数据。

所以我的问题是:如何最好地存储这些大量时间线数据?

我的一个想法是使用文本/blob 列,然后用逗号分隔剧本,每个逗号代表新的一秒(按顺序),然​​后是该秒播放次数的数字。因此,如果在第 1 秒中有 100,000 次播放,在第 2 秒中有 90,000 次播放,在第 3 秒中有 95,000 次播放,那么我会这样存储它:“100000,90000,95000,[...]” 在 text/blob 列中。

这是存储此类数据的可行方法吗?有没有更好的办法?

谢谢!

编辑:数据正在被跟踪到另一个来源,我只需要每 15 分钟左右更新一次原始图形数据。因此,快速读取是主要问题。

注意:由于这个项目的性质,必须单独跟踪每个播放的秒数(换句话说,我不能只跟踪每次播放的“开始”和“结束”)。

【问题讨论】:

    标签: database database-design data-structures timeline


    【解决方案1】:

    blob 存储的问题是您需要为所有更改更新整个 blob。这不一定是坏事。使用您的格式:(100000, 90000,...), 7 * 3600 * 3 = ~75K 字节。但这意味着您每秒都在为每次播放更新 75K blob。

    当然,blob 对 SQL 是不透明的,因此“哪一首歌的播放次数最多”将是 SQL 级别的不可能查询(这基本上是对所有数据的表扫描以了解这一点) .

    并且有很多解析开销将数据编组进出。

    另一方面。 Podcast ID(4 字节),秒偏移量(2 字节无符号允许 pod cast 长达 18 小时),播放次数(4 字节)= 10 字节每秒。因此,减去任何阻塞开销,一首 3 小时的歌曲是每首歌曲 3600 * 3 * 10 = 108K 字节。

    如果您将其存储为 blob,则与文本(长块)相比,4 * 3600 * 3 = 43K。

    因此,第二个/行结构“仅”是二进制 blob 大小的两倍(在理想情况下,请咨询您的数据库服务器以获取详细信息)。考虑到这在查询事物方面给您带来的额外好处,这可能是值得的。

    第二/每行的唯一缺点是,如果您需要进行大量更新(一首歌曲一次几秒钟),那么数据库的 UPDATE 流量会很大,而使用 blob 方法,这可能是单次更新。

    您的流量模式会影响到更多。

    【讨论】:

    • 感谢这个优点/缺点 - 非常有帮助!我将能够以 15 分钟的间隔接收跟踪数据(= 轻松 1,000 次更新),所以这绝对是 blob 方法的一个优点。另外,我只需要将此数据用于时间线图,因此能够查询数据并不重要。话虽如此,我确实发现单独行的灵活性很吸引人(看看答案,很多人似乎也有同样的感觉)。不过,blob 方法似乎确实可行,所以我将对这两种方法进行一些测试,看看哪一种在实践中效果最好。
    【解决方案2】:

    每秒使用会不会有问题,每秒播放多少次? 这意味着 10K 行,这还不错,您只需每秒使用当前数据插入一行。

    编辑:我想说的是,这种解决方案比在 TEXT 列中使用逗号分隔的内容要好......尤其是因为获取和操作数据(你说你想做的)会非常混乱。

    【讨论】:

    • 首先,感谢您的快速回复!我或许应该澄清一下,当数据结构本身如此简单时,我并不太关心更新逻辑,也不太关心更新频率(仅每 15 分钟更新一次是可以接受的)。据我所知,我需要三列:podcast_id、second 和 play。要检索图形数据,我需要检索 10K 条记录,根据外键查询并按整数排序。这不是需要一两秒钟来检索吗?
    【解决方案3】:

    我认为这是一个键值问题。

    for each second played
    
       Song[second] += 1
    
    end
    

    作为关系数据库 -

    song
    ----
    name | second | plays
    

    还有一个 hack psuedo-sql 来启动第二个:

    insert into song(name, second, plays) values("xyz", "abc", 0)
    

    另一个更新第二个

    update song plays = plays + 1 where name = xyz and second = abc
    

    一个 3 小时的播客将有 11K 行。

    【讨论】:

    • 感谢您的回复。如果我需要快速检索原始图形数据(最好大约 200 毫秒),每个播客 10-11K 行似乎很多。特别是因为需要查询和排序行。当在外键上查询并按整数列排序时,您是否有过检索 10-11K 行需要多长时间的经验?到目前为止,我一直在使用的大部分内容大约是 100 行(代表 CMS 中的页面),这是一个完全不同的故事!
    • 如果数据每15分钟才更新一次,那为什么需要200ms内检索原始数据呢?在 3 秒内检索它并缓存它直到下一次更新。
    • 第一次加载时必须等待 3 秒是不可取的。特别是因为大多数图表每天只会打开几次(这意味着大多数用户将体验 3 秒的加载时间)。我想我可以研究一下“预缓存”它(更新后立即生成缓存),但是,每 15 分钟就需要为所有更新的播客执行大量的计算能力。
    【解决方案4】:

    这真的取决于生成数据的内容..

    据我了解,您希望实现一个地图,其中键是第二个标记,值是播放次数。

    您正在加载的事件、工作单元或事务中的片段是什么?

    我可以假设您在播客名称、开始和停止时间上有一个播放事件吗 并且您想加载到地图中进行分析和展示?

    如果是这样,你可以有一张桌子

    • 播客ID
    • 秒偏移
    • 播放次数

    每个甚至都会更新开始和结束位置之间的行

    更新 设置 playCount = playCount +1 其中 podCastId = x 和 y 和 z 之间的 secondOffset

    然后接着插入以在开始和停止之间添加那些不存在的行,播放计数为 1,除非您用零预加载表。

    根据数据库,您可能能够设置不存储空列的稀疏表,从而提高效率。

    【讨论】:

      猜你喜欢
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      相关资源
      最近更新 更多