0

假设我正在建立一个关于汽车的网站。汽车实体有很多类似枚举的属性:

  • 传输(手动/自动)
  • 燃料(汽油/柴油/生物乙醇/电力)
  • 车身风格(轿跑车/轿车/敞篷车/...)
  • 空调(无/简单/双区)
  • 外观颜色(黑/白/灰/蓝/绿/...)
  • 内饰颜色(黑/白/灰/蓝/绿/...)
  • 等等

这些属性的列表将来可能会发生变化。在数据库中建模它们的最佳方法是什么?我可以想到以下选项,但无法真正决定:

  • car表中的字段与枚举值一起 使用
    • 以后很难添加更多列,可能是最快的
  • 使用car表中作为外键引用查找表的字段
    • 以后很难添加更多的列,有点慢
  • 为存储可能值的每个属性创建单独的表,并创建另一个表来存储汽车和属性值之间的连接
    • 以后容易添加更多可能的值,甚至更慢,似乎太复杂了
4

6 回答 6

1

理想的是创建一个关系数据库。DB 中的每个表都应该由一个类表示,就像在 hibernate 中一样。您应该为汽车制作 2 张桌子。一个用于内部,一个用于汽车外部。如果您想添加额外的功能,您只需添加更多列。

于 2012-11-16T22:53:28.110 回答
1

现在这是一个(非常基本的)EAV模型:

DROP TABLE IF EXISTS example.zvalue CASCADE;
CREATE TABLE example.zvalue
        ( val_id SERIAL NOT NULL PRIMARY KEY
        , zvalue varchar NOT NULL
        , CONSTRAINT zval_alt UNIQUE (zvalue)
        );
GRANT SELECT ON TABLE example.zvalue TO PUBLIC;

DROP TABLE IF EXISTS example.tabcol CASCADE;
CREATE TABLE example.tabcol
        ( tabcol_id SERIAL NOT NULL PRIMARY KEY
        , tab_id BIGINT NOT NULL REFERENCES example.zname(nam_id)
        , col_id BIGINT NOT NULL REFERENCES example.zname(nam_id)
        , type_id varchar NOT NULL
        , CONSTRAINT tabcol_alt UNIQUE (tab_id,col_id)
        );
GRANT SELECT ON TABLE example.tabcol TO PUBLIC;

DROP TABLE IF EXISTS example.entattval CASCADE;
CREATE TABLE example.entattval
        ( ent_id BIGINT NOT NULL
        , tabcol_id BIGINT NOT NULL REFERENCES example.tabcol(tabcol_id)
        , val_id BIGINT NOT NULL REFERENCES example.zvalue(val_id)
        , PRIMARY KEY (ent_id, tabcol_id, val_id)
        );
GRANT SELECT ON TABLE example.entattval TO PUBLIC;

顺便说一句:这是为支持系统目录而定制的;您可能需要进行一些更改。

于 2012-11-16T23:14:40.137 回答
1

这实际上是此 dba.SE 帖子的副本:

https://dba.stackexchange.com/questions/27057/model-with-variable-number-of-properties-of-different-types

使用 hstore、json、xml、一种 EAV 模式……请参阅我在那篇文章中的回答。

于 2012-11-17T00:00:33.550 回答
0

根据查询的数量和数据库的大小,您可以:

  1. 制作宽桌子
  2. 创建一个属性表和一个 car_attributes 表,其中:汽车 -> car_attributes -> 属性

#1 由于更少的连接,将进行更快、更简单的查询,但 #2 更灵活

于 2012-11-16T22:58:49.990 回答
0

这取决于您需要支持的管理 UI:

  • 如果有一个接口来管理例如传输的类型,您应该将其存储在一个单独的实体中。(您的选择 3)
  • 如果没有这样的接口,最好的办法是存储类似的可枚举类型值。当您需要另一个(例如用于传输的“半自动”)时,您将只在 DB 模式中添加它,事实上这将是最容易支持和最快执行的
于 2012-11-16T23:00:53.710 回答
0

我将创建具有列 AttributeID、CarID、PropertyName、PropertyValue 的表 CarAttributes。当返回 reslut 集时,我们将其保存在 IDictionary 中。它将允许您根据需要添加尽可能多的行,而无需添加新列。

于 2012-11-16T23:51:59.253 回答