一对一或一对多:一个表有100列或移动列到额外的表

时间:2014-06-19 10:45:56

标签: sql postgresql symfony database-design doctrine-orm

我正在尝试为以下问题找到最佳数据库设计。

我有20000个数据集,如下所示:

1. id, name, color, width, xxxx ... 150 attributes
2. id, name, color, width, xxxx ... 150 attributes
3. ...

这意味着我每个都有20000个实体和150个属性,如颜色,宽度等。

我需要所有这些属性,并且可能比其他人使用更多。这是在Web应用程序中使用它必须执行。

我想到的解决方案:

  1. 规范化两个表的方法:

    • id,name和一个主表中的一些“更重要”的属性
    • 在另一个表中(一对一关系):id和其他不太重要的属性,每个列在不同的列中
  2. 一个怪物表中的所有内容:

    • id,name,color,width ...
  3. 规范化两个表格方法(一对多):

    • 主表:id和name
    • 另一个表中的
    • (一对多关系):其他表:id,attr_name,value
  4. 我最喜欢[3],但我不确定如果我需要大量数据,这将会执行,因为每个“id”都有150个值。我会有像

    这样的事情
    SELECT mt.id, mt.name, at.attr_name, at.value
    FROM main_table mt
    INNER JOIN attr_table at ON at.id = mt.id
         AND at.attr_name IN ('width', 'color', 'a', 'b', 'c' .....)
         AND at.id IN (1,3,9...)
    ORDER BY 1
    

    在“attr_name IN(...)”中可能有15-20个不同的值看起来不是最佳的。如果我需要10-30个不同的数据集(我通常这样做),它看起来更不吸引人。

    输出可能是200-300行,我必须在代码中规范化这个输出。

    [2]非常肮脏和简单,但我不确定它是如何表现的。并且在一个怪物表中有150列也看起来不是最佳的。

    我喜欢这种方法,我可以在sql中做很多事情而不是后来的代码如:attr1 - attr2 ...(比如“max_width - width”或weight - max_weight / 4)。

    [1]我不喜欢这个,因为在一个表中具有“某些”属性并且在另一个表中具有相同类型的所有其他属性看起来并不干净

    针对此特定问题的最佳解决方案是什么?

    我发现了一些类似但不相同的问题: Best to have hundreds of columns or split into multiple tables? Is it better to have many columns, or many tables?

1 个答案:

答案 0 :(得分:0)

由于行数太少而不足20,000,我对于完全正常化将毫无疑问。在我看来,即使有更多行,我仍然会这样做,而不是额外的JSON全新的问题和弱点。

输出可能是200-300行,我必须在代码中规范化此输出

创建一个视图,不必在每个查询中进行连接

create view the_view as
select id, mt.name, at.attr_name, at.value
from
    main_table mt
    inner join
    attr_table at using (id)

选择时过滤

select *
from the_view
where
    attr_name = 'color' and "value" = 'red'
    and
    attr_name = 'width' and "value" = '30'
    and
    id in (1, 3, 9)

150列表明属性列表不稳定。如果创建包含150列的表,则必须始终更改表以添加新列。规范化方法是灵活的。您可以通过向表中添加行来简单地创建属性。

应该有3张桌子; main_tablemain_table_attr_tableattr_tablemain_table_attr_table是另外两个之间的n到n连接。