对于多对多关联,是否有加入 table 的任何选项?

Are there any options to a join table for many-to-many associations?

假设我有两个 tables 的数据不应该通过使用我的应用程序(即域 tables)来改变 汽车型号和汽车颜色。

models table 列出了现有的不同类型的汽车模型。

colors table 列出了汽车可以进来的不同类型的颜色。

现在,可能不是很明显,但两者之间存在关系。 颜色 可能仅适用于特定型号,或者更有可能是同一品牌的多个型号。 模型当然没有特定的颜色,但它确实带有我想存储在数据库中的颜色选择。

因此它们之间存在多对多关系,这表明我应该将这种关系的详细信息存储在连接 table 中。所以,如果你原谅我自己的符号,它看起来像这样:

Volvo V70 <-> Pearl White
Volvo V70 <-> Emerald Green
Volvo V70 <-> Night Black
Volvo V70 <-> Salmon Pink
Volvo V70 <-> Ocean Blue
Volvo V70 <-> Raspberry Red

Volvo V60 <-> Pearl White
Volvo V60 <-> Emerald Green
Volvo V60 <-> Night Black
Volvo V60 <-> Salmon Pink
Volvo V60 <-> Ocean Blue
Volvo V60 <-> Raspberry Red

...

这是很多重复的文字。如果我能做到会更容易

[Volvo V70, V60, S60, S40] <-> [Pearl White, Emerald Green, Night Black, Salmon Pink, Ocean Blue, Raspberry Red]

然后转到下一个车型和一组颜色。

常规联接是否有任何选项 table 可以以任何方式简化此过程?

如 Kleskowy 在评论中所述,在为多对多关系建模时,每个关系(模型 <-> 颜色)需要一个连接条目 table。

您可以通过以下方式重现您的示例:

CREATE TABLE car_model(car_model_id serial NOT NULL PRIMARY KEY, model_name text NOT NULL);
CREATE TABLE car_color(car_color_id serial NOT NULL PRIMARY KEY, color_name text NOT NULL);
CREATE TABLE join_model_color(
  car_model_id int NOT NULL REFERENCES car_model(car_model_id),
  car_color_id int NOT NULL REFERENCES car_color(car_color_id),
  CONSTRAINT model_color_unique_entries UNIQUE(car_model_id, car_color_id)
);

然后插入您的数据:

INSERT INTO car_model(model_name) SELECT 'Volvo V70' UNION SELECT 'Volvo V60';
INSERT INTO car_color(color_name) SELECT 'Pearl White' UNION SELECT 'Emerald Green' UNION SELECT 'Night Black' UNION SELECT 'Salmon Pink' UNION SELECT 'Ocean Blue' UNION SELECT 'Raspberry Red';
INSERT INTO join_model_color SELECT car_model_id, car_color_id FROM car_model, car_color WHERE model_name = 'Volvo V70' AND color_name IN ('Pearl White', 'Emerald Green', 'Night Black', 'Salmon Pink', 'Ocean Blue', 'Raspberry Red');
INSERT INTO join_model_color SELECT car_model_id, car_color_id FROM car_model, car_color WHERE model_name = 'Volvo V60' AND color_name IN ('Pearl White', 'Emerald Green', 'Night Black', 'Salmon Pink', 'Ocean Blue', 'Raspberry Red');

然后您可以像这样查询您的数据:

SELECT color_name FROM car_model NATURAL INNER JOIN join_model_color NATURAL INNER JOIN car_color WHERE model_name = 'Volvo V70';
SELECT model_name FROM car_model NATURAL INNER JOIN join_model_color NATURAL INNER JOIN car_color WHERE color_name = 'Emerald Green';
  • 如果模型不共享颜色组,那么设计将是一个 table:

    model [model] comes in color [color]
    
  • 如果模型共享颜色组,则有两个 table:

    model [model] comes in the colors of group [group]
    group [group] has color [color]
    

    这些 tables 与投影连接到第一个 table:

    SELECT model, color FROM model_group NATURAL JOIN group_color
    
  • 如果一个模型可以有异常可用的 and/or 不可用颜色作为一组的补充或代替组,那么就会有异常 tables。 table 的组现在是其 默认 颜色(如果有):

    model [model] has default color group [group]
    group [group] has color [color]
    model [model] is exceptionally available in color [color]
    model [model] is exceptionally unavailable in color [color]
    

    然后异常 tables 分别与 JOIN-plus-PROJECT/SELECT 中的 MINUSed/EXCEPTed 联合并给出第一个 table:

    SELECT group, color FROM model_default NATURAL JOIN group_colour
    EXCEPT SELECT * FROM model_unavailable
    UNION SELECT * FROM model_available
    

"Redundancy" 与出现在多个地方的值无关。它是关于多行说明应用程序的相同内容。

每个 table(和查询表达式)都有一个关联的填空(命名)语句模板(又名谓词)。作出正确陈述的行进入 table。如果你有两个独立的谓词,那么你需要两个 table。相关值位于每个值的行中。

有关应用程序的重新行声明请参阅 this. (And search my other answers re a table's "statement" or "criterion".) Normalization helps because it replaces tables whose rows state things of the form "... AND ..." by other tables that state the "..." separately. See this and this

如果您共享组并且只使用一个两列 table 来表示型号和颜色,那么它的谓词是:

FOR SOME group
    model [model] comes in the colors of group [group]
AND group [group] has color [color]

因此第二个项目符号从此谓词中删除了一个 "AND",即 "multivalued dependency" 的来源。否则,如果您更改模型的组或组的颜色,则必须同时一致地更改多行。 (重点是减少冗余的错误和复杂性,而不是保存space。)

如果你不想重复 strings 出于实现(依赖)的原因(space 采取或以更多连接为代价的操作速度)然后添加名称 ID 和字符串的 table,并用 ID 列和值替换旧名称列和值。 (这不是规范化,这是为了依赖于实现的数据优化权衡而使您的架构复杂化。您应该证明这是需要的并且有效。)