单独的 id 字段的单独列?
假设我们有表 A、B 和 C,然后我们希望表 Z 包含列 TYPE
,该列告诉我们 Z 中的记录与 A、B 和 C 的哪个表关联。
为了使用索引,是否为每个表拥有一个单独的列(例如 A_ID
、B_ID
和 C_ID
列)更好?
或者是否有某种原因可以解释为什么使用通用列 TYPE_ID
可能会提高性能?
Say we have tables A, B, and C and then we want table Z to contain column TYPE
which tells us which table of A, B, and C the record in Z is associated with.
Is it better to have a separate column for each table like columns A_ID
, B_ID
, and C_ID
in order to use indexing?
Or is there some reason why using a generic column TYPE_ID
might be better performance-wise?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 type_id 然后使用 fk_id 效果并不好,因为索引的选择性为 33%,这太高了,没有任何用处。您将始终在 fk_id 上建立索引(链接到 A、B、C) - 这可能需要 3 个值之间的平局(如果 id 被所有 3 种类型使用)。
在存储方面,索引从不存储空值,因此存储在索引中的项目的绝对数量,无论是单个 (fk_id) 还是多个 (a_id,b_id,c_id) 都会相似。
如果您从确切的 fk_id(来自 A、B、C)进入,则按该顺序使用 (fk_id,type_id) 上的唯一索引可以快速识别所需的记录。
为了简单起见,这里两列比三列更好。
Using a type_id and then a fk_id won't be good because selectivity on the index is 33%, which is too high to be of any use. You would always be indexing on the fk_id instead (that which links to A,B,C) - which may require tie breaking between 3 values (if the id is used by all 3 types).
Storage wise, an index never stores nulls, so the absolute number of items stored in the indexes, whether a single (fk_id) or multiple (a_id,b_id,c_id) will be similar.
If you are coming in from the exact fk_id (from either A,B,C), then using a unique index on (fk_id,type_id) in that order can quickly identify the record required.
It would seem for simplicity and brevity, two columns are better than 3 here.
这有时是架构代码的味道。
如果您考虑将其作为 Z 中的单个列,这是否意味着 A、B、C 中只有一个可以适用于 Z?
在我做出决定之前,我真的想说我必须更多地了解该实体和使用模式。访问是来自已知的 A、B 或 C,还是来自 Z 方的补充信息?如果它是从 Z 端驱动的,您是否想要获取所有 A、B 和 C 列,然后从应用程序中选择性地使用它们,或者只是 Z 与 As 或 Z 与 B - 即您通常知道子类型吗?另外,如果 A、B 和 C 都是 1-1,则它们是否有足够的列值得从 Z 行中分离出来(即您可以在 Z 中拥有列并且只是 NULL)。
为了完整性,另一种可能性为您提供了更具参照完整性(因为使用单列,您不能成为三个表之一的 FK)是拥有表 Z_A、Z_B、Z_C:
使用模式:
每个表中的所有 ID 都是唯一的,这很好地限制了一切,除了没有任何声明可以在没有触发器的情况下阻止 Z 位于多个表中(您无法在 SQL Server 中的 UNION ALL 上对索引视图进行唯一约束)。
虽然它似乎增加了表的数量,但它们通常可以包含在视图中。
This is sometimes a schema code smell.
If you are considering putting this as a single column in Z, does that mean that only one of A, B, C can be applicable to Z?
Before I decide, I'd really say I have to know more about the entity and the usage pattern. Is access coming from known A, B, or C, or is the supplemental info driven from the Z side? If it is driven from the Z side, do you want to get all the A, B and C columns and then use them selectively from the application, or just Zs with As or Zs with Bs - i.e. do you usually know the subtype? Also, do A, B, and C have enough columns to merit the separation out of Zs row if they are each 1-1 (i.e. you could have the columns in Z and just be NULL)
Just for completeness, another possibility which gives you more referential integrity (because with a single column, you can't be an FK to one of three tables) is to have tables Z_A, Z_B, Z_C:
With schemas:
With all IDs unique in each table, this constrains everything pretty nicely, except there is nothing declarative to stop Z lying in multiple tables without a trigger (you cannot make a unique constraint on an indexed view over a UNION ALL in SQL Server).
While it seems to multiply the number of tables, these can usually be wrapped up into views.