Database 数据库如何处理密集数据?

Database 数据库如何处理密集数据?,database,performance,Database,Performance,假设您有一个具有整数主键的密集表,其中您知道该表将包含从0到1000000的所有值的99% 实现这种表的一种超级高效的方法是数组(或磁盘上的平面文件),假设记录大小固定 有没有一种方法可以使用数据库实现类似的效率 澄清-当存储在一个简单的表/数组中时,对条目的访问是O(1)-只是内存读取(或从磁盘读取)。据我所知,所有数据库都将其节点存储在树中,因此它们无法实现相同的性能-访问一个平均节点需要几跳。如果您在一个数据库中有相当数量的记录(1毫米是相当不错的,实际上没有那么大),那么您就是朋友。您正

假设您有一个具有整数主键的密集表,其中您知道该表将包含从0到1000000的所有值的99%

实现这种表的一种超级高效的方法是数组(或磁盘上的平面文件),假设记录大小固定

有没有一种方法可以使用数据库实现类似的效率


澄清-当存储在一个简单的表/数组中时,对条目的访问是O(1)-只是内存读取(或从磁盘读取)。据我所知,所有数据库都将其节点存储在树中,因此它们无法实现相同的性能-访问一个平均节点需要几跳。

如果您在一个数据库中有相当数量的记录(1毫米是相当不错的,实际上没有那么大),那么您就是朋友。

您正在谈论的是旧的固定记录长度平面文件。是的,与数据库相比,它们是超级高效的,但就像结构/值数组与类一样,它们没有我们今天通常期望的那种特性

例如:

  • 在不同列/组合上搜索
  • 可变长度列
  • 可空列
  • 编辑性
  • 重组
  • 并发控制
  • 事务控制 等等等等

创建一个带有ID列和bit列的DB。对ID列使用聚集索引(ID列是主键)。插入所有1000000个元素(按顺序插入,否则会很慢)。这在空间方面有点低效(您使用的是nlgn空间而不是n空间)

我并不认为这是有效的,但它的存储方式与数组的存储方式类似


请注意,在大多数DB系统中,ID列可以标记为计数器,在这种情况下,您可以只插入1000000项,它将为您进行计数。我不确定这样的DB是否可以避免显式地存储计数器的值,但如果这样做了,那么您将只使用n个空格)

当您将主键作为整数序列时,最好使用。这种方法确保连续值在索引树中分散开来。
然而,有一个问题是,如果使用反向索引,您将无法进行范围搜索。

最大的问题是:什么是有效的

对于oracle,您的想法可能包括:

  • 按id读取访问:索引组织的表(这可能是您正在寻找的)
  • 仅插入,无更新:无索引,无备用空间
  • 读取访问完整表扫描:压缩
  • id来自序列时的高并发写入:反向索引
  • 对于实际问题,正如所问的那样:将所有行写入一个blob(表中包含一列,一行。您可能可以像数组一样访问它,但我不确定,因为我不知道blob上可以执行哪些操作。即使它起作用,我认为这种方法在任何实际场景中都不会有用

    • 也许我不理解你的问题,但数据库是用来处理数据的。我整天都在处理数百万行的数据库。它们的效率足够高

      我不知道你对“使用数据库实现类似的效率”的定义是什么意思。在数据库中(根据我的经验),你到底想做什么与性能有关

      如果您只需要基于主键的单个记录,那么假设数据库的结构正确(例如,3NF),那么数据库的效率自然应该足够高

      再次,您需要设计数据库以满足您所需要的。此外,考虑如何在给定结构中对数据库编写查询。

      在我的工作中,通过优化连接、where子句和整体查询结构,我能够将查询执行时间从>15分钟缩短到1或2秒。显然,适当的索引也很重要

      也考虑一下你要使用的数据库引擎。我一直在假设SQL Server或MySQL,但是那些可能不正确。我听说过(但从来没有测试过这个想法)SQLite是非常快的-比前面提到的任何一个都快。当然,还有很多其他的选项。 更新根据你在评论中的解释,我想说不——你不能。你问的是为两种完全不同的事情设计的机械化。数据库会长期保存数据,并且通常会针对许多连接和数据读/写进行优化。在你的描述中,arra中的数据y、 内存是供单个程序访问的,并且该程序拥有内存。它(通常)不是共享的。我不知道如何实现相同的性能


      另一个想法:在SQL server中,最接近这一点的是使用。表变量(理论上)仅保存在内存中。我听说人们将表变量称为SQL server的“数组”。任何常规的表写入或创建语句都会提示RDM写入磁盘(我认为,首先是日志,然后是数据文件)。而大数据读取也会导致数据库写入专用临时表以存储数据以备将来使用。

      要指定数据在数据库中的物理存储方式,您可以做的不多。您可以做的最多是指定数据和索引是分开存储还是存储在一个索引树中(如Brian所述的聚集索引)

      但在您的情况下,这根本不重要,因为:

    • 所有数据库都大量使用缓存。1.000.000条记录几乎不能超过1GB的内存,因此整个数据库将很快缓存在数据库缓存中
    • 若您一次读取一条记录,您将看到的主要开销是通过数据库协议访问数据。过程如下:
      • 连接到数据库-打开通信通道
      • 将SQL文本从应用程序发送到数据库
      • <