【问题标题】:Do I have to create a surrogate key if I want to save space?如果我想节省空间,是否必须创建代理键?
【发布时间】:2013-02-12 13:47:59
【问题描述】:

假设我有一张很大的桌子,里面有这样的车主:

OWNERSHIP
owner    | car
---------------
steven   | audi
bernahrd | vw
dieter   | vw
eike     | vw
robert   | audi
... one hundred million rows ...

如果我将其重构为:

OWNERSHIP
owner    | car <-foreign key TYPE.car_type
---------------
steven   | audi
bernahrd | vw
dieter   | vw
eike     | vw
robert   | audi
...


TYPE
car_type      |
---------------
audi
vw

我是否在空间或速度方面赢得了任何东西,或者我是否需要为此在 car_type 上创建一个 INTEGER 代理键?

【问题讨论】:

    标签: postgresql foreign-keys


    【解决方案1】:

    整数将占用 4 个字节,即one more byte than "vw" will。碰巧,PostgreSQL enums take up 4 bytes too,因此您不会通过切换到此表示来获得任何存储方面的东西(除了它对更改枚举本身造成的困难)。无论哪种方式,查询都一样快,因为对于这样大小的表,您无论如何都会查询索引。数据库性能,尤其是当表变大时,本质上是 I/O 问题,而不是 CPU 性能问题。我不相信整数索引会比短字符串索引更小或更快,尤其是当您有大量行引用非常小的可能值集时。它肯定不会成为您应用程序的瓶颈。

    即使我们假设您能够通过使用人工密钥恢复 4 个字节,您要节省多少存储空间? 4 字节乘以 1 亿行理想情况下约为 400 MB。您是否如此迫切地需要存储,以至于您需要在您的 honkin' 数据库服务器上获取少量这样的存储空间?这是假设您将其重构为自己的表并使用正确的外键。

    当然,回答这个问题的正确方法是根本不从第一原则争论。拿你的 1 亿行表来双向工作。然后自己检查尺寸,如下所示:

    SELECT pg_size_pretty(pg_total_relation_size('ownership')));
    SELECT pg_size_pretty(pg_total_relation_size('ownership2')));
    

    使用 EXPLAIN ANALYZE 进行测试查询,如下所示:

    EXPLAIN ANALYZE SELECT * FROM ownership WHERE car = 'audi';
    EXPLAIN ANALYZE SELECT * FROM ownership2 WHERE car_id = 1;
    

    更多地关注实际花费的时间而不是成本,但要看看成本。如果可能,在与您的生产相同的数据库服务器上执行此操作;如果不是,请使用具有相同 PostgreSQL 配置的类似机器。然后你就会有硬性的数字来告诉你你付出了什么,你得到了什么。我的怀疑是,您会发现使用人工密钥的空间使用率稍差,性能相当。

    如果您发现了这种情况,请执行关系操作并使用自然键,而不必再担心优化物理存储。空间是您拥有的最便宜的商品。

    【讨论】:

      【解决方案2】:

      使用两个表和字符串外键当然会比使用一个使用更多的空间。多少取决于您拥有多少种汽车。

      你应该使用整数car_id:

      • 如果大量汽车名称重复,则使用整数键可以节省空间。

      • 如果您需要索引car 列,则更是如此,因为整数索引远小于字符串索引。

      • 同样比较整数比比较字符串快,所以汽车搜索也应该更快。

      • 较小的表意味着较大的部分可以放入缓存中,因此访问它也应该更快。

      【讨论】:

      • 算了——我错了。文本索引占用与整数索引几乎相同的空间量。在 1M 行中对 40k 个不同的单词(最多 5 个字符)进行了测试。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多