我有一个'用户'表,其中有一堆关于我的用户的具体“确定”属性,所有这些属性必须在那里,并且它们的准确性是肯定的,然后我有一个单独的表'users_derived',其中包含此表中的所有数据是由机器学习模型猜测的我的用户的派生属性。例如:'age'可能是某种属性,因为它们提供给我,'height'或'hair color'可能是派生属性,因为ML模型从图片中猜到了它。主要区别在于'用户'表中的所有属性都是由用户自己提供给我的,并且具有完全的确定性,而'user_derived'表中的所有属性都具有与之相关的值和确定性,并且由我的系统猜测。另一个区别是'users'表的所有属性都适用于每个用户,而'users_derived'表中的任何属性可能也可能不存在。我不时会添加新的ML模型来猜测用户的更多属性。
我的问题是如何为'users_derived'表格执行架构。我可以这样做:
userid | prop1 | certainty1 | prop2 | certainty2 | prop3 | etc ...
123 7 0.57 5'8'' 0.82 red
124 12 0.6 NULL NULL black
125 NULL NULL 6'1'' 0.88 blonde
或者我可以这样做,索引略有不同:
userid | property | value | certainty
123 1 7 0.57
123 2 5'8'' 0.82
124 1 12 0.60
123 3 red 0.67
124 3 black 0.61
125 2 6'1'' 0.88
etc ....
所以权衡看起来像第二种方式它不是规范化的,可能稍微难以查询,但你不必提前知道你关心的所有属性 - 这就是我想要添加新属性没有架构更改。此外,不必有任何NULL点,因为如果我们没有该属性,但我们只是没有一行。我错过了什么?第一种方式有什么好处?我是否可以针对第二个模式中难以或不可能的第一个模式进行查询?第二种方式是否需要更多的索引空间以使其快速?
答案 0 :(得分:2)
第二种方式是更多规范化。表和索引都可能更紧凑,特别是如果第一种形式相对稀疏地填充。尽管这两种形式对于不同的查询具有不同的权衡,但通常第二种形式更灵活并且更适合于各种各样的查询。如果要将数据从规范化表单转换为交叉表格,Postgres中有my_list = [(1, 2, 4), (2, 4, 1), (1, 5, 2), (1, 4, 1)]
results = []
for position in my_list:
for check in my_list:
if not (position[0] == check[0] and position[1] < check[1] and position[2] < check[2]):
results.append(position)
results
>[(1, 2, 4), (2, 4, 1), (1, 5, 2)]
函数。可用于此目的的crosstab
扩展名。规范化交叉表数据将更加困难,特别是如果列数不确定 - 但您可能需要对某些类型的查询执行此操作。