0

我正在为一个网站设计一个数据库,其中性能是重中之重。

关键功能基于两个表。

并且这些表具有多对多关系。

为了拆分它,我添加了一个额外的表 Table1_Table2,然后在每个关系的基础上保存两个表主键的组合。

例如,我将所有汽车都放在 Car 表中,并将所有颜色都放在颜色表中

车桌


ID(PK) - 姓名


1 - 宝马
2 - 梅赛德斯
3 - 大众
4 - 奥迪


颜色表


ID(PK) - 颜色


1 - 蓝色
2 - 绿色
3 - 黑色
4 - 黄色


对于多对多关系,我这样做了:

Car_ColorTable


ID(PK) - CarID - ColorID


1 - 1 - 2
2 - 1 - 4
3 - 2 - 4
4 - 3 - 1
5 - 4 - 1
6 - 4 - 3
7 - 4 - 3


这是一个好的设计考虑:

1)性能是重中之重。

2)表会有大量数据(两个表都有超过100万条记录,你可以想象Car_ColorTable最终会有多少行。

如果上述设计不是解决方案,我应该如何设计?

4

5 回答 5

3

它应该是 Car_ColorTable

CarID (PK) - ColorID (PK)

你不希望 id 列在那里,
主键应该有两列
你可以创建类似的非聚集索引,列的顺序相反,意思是(ColorID,CarID)
,就是这样

于 2013-01-28T14:30:14.283 回答
2

这是映射关系的最佳方式。只需确保您知道通常会尝试从哪个对象接近关系并将聚集索引放在该列上。

您也可以选择创建组合 PK,但不能使用任何重复项。

于 2013-01-28T14:33:40.997 回答
1

您可能的意思是说 SELECT 性能是最重要的。但是您不能让 SELECT 性能胜过数据完整性。快速得到错误的答案从来都不是一个好的要求。

如果您使用代理键(整数),您的主键应该是primary key (car_id, color_id). 额外的代理键“ID”在这里没有用,通常会损害 SELECT 的性能。(更多的列,更宽的行,磁盘上每个数据页的更少行,更多的磁盘 I/O。)

您应该使用自然键(汽车名称和汽车颜色)代理键进行测试。每个查询的代理键都需要两个连接;自然键不需要连接。使用代理键(汽车、颜色)的表仍然需要对名称进行唯一约束。您不想以后发现“蓝色”有 13 个不同的 ID 号。

花一两个小时编写一个脚本来生成几百万行有和没有代理键,并比较性能。

于 2013-01-28T14:36:16.867 回答
1

你的设计看起来不错。要记住的事情:

  1. 索引是你的朋友。使用它们。
  2. 在谈论性能时,请记住,提高读取性能通常会导致小的更新/插入写入性能损失。

一百万条记录确实不算多,您可以进行快速查询。获得具有足够处理能力和内存的体面服务器,您应该没问题。

于 2013-01-28T14:37:24.550 回答
0

关于Car_ColorTable表格,除非您真的想允许同一辆车和颜色之间的多个连接,或者有其他特定原因,否则请放弃代理键{Id}并使用自然键,即汽车和颜色的组合。

具体如何执行取决于您需要运行的查询:

  • 如果您需要:“对于给定的汽车,给我颜色”,{CarID, ColorID}.
  • 如果您需要“给定颜色,给我汽车”,请在{ColorID, CarID}.
  • 如果两者都需要,请在 上创建一个主键{CarID, ColorID}和一个二级索引{ColorID, CarID}
    • 除非您没有向我们展示其他字段,否则请使 PK 集群化。
    • 如果您确实有其他字段,请使用非集群(即基于堆)表,或者使用这两个索引覆盖所有字段( INCLUDE关键字可能会派上用场)。
于 2013-01-28T21:06:05.233 回答