我在描述实体的数据库中有一个表。需要为该实体的某些实例存储额外信息。在这种情况下,此附加信息将出现在极少数记录(约 5%)中,其余记录为 NULL。需要这些附加信息的请求也不会很多。
我正在考虑两种选择:
- 向现有表中添加一个额外的列。
- 创建一个新表,其中一列包含第一个表中的 ID,一列包含必要的附加信息。
对此,我有一个疑问:创建一个保证大部分行为空的列有多大用处?这不会导致表格不必要地膨胀吗?这会不会影响那些与本栏信息无关的查询的执行速度?这两种选择的其他优点、缺点和陷阱是什么?
在此任务的框架内,我对 PosgreSQL 的答案和具有 UUID 数据类型的列感兴趣。但有关此问题的更多一般信息也很有趣。
它适用于 postgresql。
NULL 不需要任何存储成本。事实上,什么都没有。NULL 值是行标题中的一位,其中 NULL 位掩码始终存在等等。
读取字符串中数据的性能 - NULL 仅影响一个优化:如果在字符串的开头只有固定宽度的数据而不是 null,那么您可以从标题偏移一个字节偏移到所需的字段。否则,阅读整行。当然,优化不再适用于可变长度的数据,或者如果它们前面已经有值,可能包含 null。是的,这些是 CPU 时间的碎片。并且基础通常依赖于磁盘,而不是 CPU。
单独的桌子将占用更多空间。只有两个 bigint 字段的表中的每一行将占用 40 个字节(甚至 44,不确定对齐方式),每行的标题占用 23 个字节。而且这还没有考虑外键上的索引,从每个条目 14 个字节开始(更多,我不知道这里的字节分布)。DBMS 连接也可以做得又好又快,但是所有作为调度程序的机器、MVCC 处理、连接本身的执行、额外的索引扫描都无法与访问同一行中的字段进行比较。
为了不按字段扩充索引,您可以通过 使其部分化
where fieldname is not null
。只需要检查调度程序是否可以按条件自动执行where fieldname = ?
或仅按where fieldname = ? and fieldname is not null
. 好吧,如果is not null
需要一个条件,那么只有 5% 的填充字段,它仍然不会被使用。