设计数据库的一部分以及它们之间的关系时遇到了麻烦。
我的实体是:
选项A:
创建2个表
车辆表
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid |
| brand | varchar |
| model | varchar |
| attribute1 | varchar |
| price | float |
| discount float | |
| locale varchar | |
+----------------+---------+
自行车桌
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid |
| vendor | varchar |
| attribute1 | varchar |
| attribute2 | varchar |
| attribute3 | varchar |
| price | float |
| discount float | |
| locale varchar | |
+----------------+---------+
选项B
创建3个表
车辆表
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid |
| brand | varchar |
| model | varchar |
| attribute1 | varchar |
+----------------+---------+
自行车桌
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid |
| vendor | varchar |
| attribute1 | varchar |
| attribute2 | varchar |
| attribute3 | varchar |
+----------------+---------+
价格表
+----------------+-------+
| NAME | TYPE |
+----------------+-------+
| vehicle_id | FK |
| bike_id | FK |
| price | float |
| discount float | |
| locale varchar | |
+----------------+-------+
选项C
创建4个表
车辆表
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid |
| brand | varchar |
| model | varchar |
| attribute1 | varchar |
+----------------+---------+
VEHICLES_PRICES表
+----------------+-------+
| NAME | TYPE |
+----------------+-------+
| vehicle_id | FK |
| price | float |
| discount float | |
| locale varchar | |
+----------------+-------+
自行车桌
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid |
| vendor | varchar |
| attribute1 | varchar |
| attribute2 | varchar |
| attribute3 | varchar |
+----------------+---------+
BIKE_PRICES表
+----------------+-------+
| NAME | TYPE |
+----------------+-------+
| bike_id | FK |
| price | float |
| discount float | |
| locale varchar | |
+----------------+-------+
注意:我确实简化了车辆和自行车表(我无法将两者合并在一个表中,例如“产品”)
从性能和模式的角度来看,我们将是最好的设计?
答案 0 :(得分:0)
我会选择选项B,因为您不能将两者合并。这样,您可以拥有多个价格和/或保留未来价格变化的记录。
答案 1 :(得分:0)
如果您可以将ID范围分为两部分(例如,自行车小于50000000,车辆大于50000000,请选择选项B。这样可以避免创建未使用的空列。
否则,选项C会为更改提供更好的灵活性,因为自行车和汽车所需的数据将来会有所不同。
还可以通过在价格表中添加其他DateTime列来保留价格历史记录。
答案 2 :(得分:0)
如果您需要将所有价格都放在一个表中(以进行排序等),那么选项B很好,尽管您可能希望对价格表进行约束,使每一行都精确地引用车辆或自行车,但两者都不是。
请注意,这里您可能拥有没有价格的车辆或自行车。
另一种方法是反转外键关系,并具有三个这样的表:
PRODUCTS TABLE
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| product_id | uuid |
| price | float |
| discount | float |
| locale | varchar |
+----------------+---------+
VEHICLES TABLE
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid,FK |
| brand | varchar |
| model | varchar |
| attribute1 | varchar |
+----------------+---------+
BIKES TABLE
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid,FK |
| vendor | varchar |
| attribute1 | varchar |
| attribute2 | varchar |
| attribute3 | varchar |
+----------------+---------+
现在您可以拥有既不是自行车也不是车辆的产品,并且可以同时具有既不是自行车又不是车辆的产品。缺点是对于给定的产品,您不知道它是什么。
另一方面,该方案可以强制要求每辆车和每辆自行车都有价格。
由于您询问的是模式观点,因此从这方面出发,解决方案是使用composite type for your prices。价格不是一个实体(具有自己的标识),它只是自行车和车辆使用的一个值。这里我们只有两个表:
PRICE _TYPE_
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| value | float |
| discount | float |
| locale | varchar |
+----------------+---------+
VEHICLES TABLE
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid,FK |
| brand | varchar |
| model | varchar |
| attribute1 | varchar |
| price | price |
+----------------+---------+
BIKES TABLE
+----------------+---------+
| NAME | TYPE |
+----------------+---------+
| Id | uuid,FK |
| vendor | varchar |
| attribute1 | varchar |
| attribute2 | varchar |
| attribute3 | varchar |
| price | price |
+----------------+---------+
这将与您的解决方案A等效,尽管代码重用性更高。此外,price
字段现在可以作为完整结构而不是在其各个部分上为空。
但是,从性能和可用性的角度来看,我建议避免使用复合类型,使用它们很麻烦。您宁愿使用解决方案A,并手动保持与价格相关的列定义同步。