6

我有一些数据需要放入 PostgreSQL 数据库。这些数据与学校有关。所以有很多与学校相关的属性,主要是小整数、浮点数或小文本。并且所有数据每年都在变化。所以我正在创建一个名为的实体YearlyData并将属性放在那里。但问题是,属性的​​数量在 50-60 左右。现在这些不能被规范化,因为它们是学校本身的简单属性。所以我在道德上不能将它们分成表格。但我不确定这是否会损害我的表现。

我可以尝试对这些数据进行分类并将它们放在单独的表中并从表中指向它们YearlyData。但是然后尝试使用 20-30+ 参数搜索学校会导致疯狂的连接数量,我猜。我也不确定这是否会损害我的表现。

有什么专家建议吗?

4

2 回答 2

3

PostgreSQL 将行存储在大小为 8kb 的所谓数据页上。您可以将这些视为具有有限大小限制的存储桶。宽行的缺点是数据库可以在数据页上容纳较少的行。数据库引擎从一页带回 1,000 行比带回分布在多个页面上的 1,000 行要快。在这种情况下,一次读取与 1,000 次读取相比,磁盘 IO 是您的敌人。这是要注意不要避免的事情。通常需要宽桌子,您可以忍受开销。在您的情况下,您将大致每行使用 240 个字节(每个整数 4 个字节 * 60 行)。

于 2013-07-28T03:19:12.803 回答
3

这里有几点需要考虑:

  • 属性列表是否随时间显着变化
  • 属性列表是否需要自定义用户定义属性
  • 不同学校是否有不同的属性(即许多属性只适用于一所或几所学校)?

如果其中任何一个是正确的,您可能会考虑使用属性存储方法,例如 EAV、hstore、json 字段、xml 字段等

如果没有——如果你有一个相当静态的属性列表,其中大多数属性对大多数行有意义——那么将它们作为 60 个单独的列并没有真正的问题。为通常搜索的属性集添加索引会更容易,包括部分索引和复合索引等,并且搜索 - 特别是针对许多不同属性的搜索 - 会更快

另请参阅:数据库设计 - 我应该使用 30 列还是 1 列来包含 JSON/XML 形式的所有数据?

您还可以使用一个折衷选项:一个主表,其中包含您经常查找的最重要的详细信息,以及用于属性逻辑分组的侧表。说:

yearly_summary (
    yearly_summary_id serial primary key,
    school_id integer,
    total_students integer,
    ...
) 

yearly_student_stats(
    yearly_summary_id integer primary key references yearly_summary(yearly_summy_id) on delete cascade,
    ...
)

等等。integer primary key这也foreign key意味着您与另一个表具有强制的 1:1(可选)关系。如果您有一些属性的逻辑分组可以聚集到边表中,这种方法会很有用。

如果多一点思考并没有揭示对正常化有意义的事情,我也会感到惊讶。你有year7_blah, year8_blah, year9_blahetc 列吗?如果是这样:标准化的绝佳候选者。

于 2013-07-28T10:03:51.143 回答