4

我正在设计一个数据库,并且正在考虑需要一对多的关系。传统上我已经完成了正常的 PK(作为 GUID)并建立了关系,但我想知道如果这样做为什么不使用按位标志作为 PK。

这种关系会丢失,但数据本身会描述这种关系。

示例 - 我有一个组表和一个用户表。用户可以有 1 个或多个组:

+------------------------+
| Groups                 |
+------------------------+
| PK      | Display Name |
+---------+--------------+
| 1       | Group A      |
| 2       | Group B      |
| 4       | Group C      |
+---------+--------------+

+------------------------+
| Users                  |
+------------------------+
| Name    | Groups       |
+---------+--------------+
| Fred    | 1            | // Fred is only in Group A
| Jim     | 3            | // Jim is in Groups A & B
| Sam     | 7            | // Sam is in all Groups
+---------+--------------+

请问对此设计有什么想法、意见和建议?

4

6 回答 6

5

我不鼓励使用这样的位标志。一方面,您破坏了轻松加入这些表的能力,因此确定组成员身份将 a) 花费更长的时间,b) 更加困难,并且 c) 可能涉及更多的全表扫描或至少索引扫描。

于 2009-07-09T12:31:42.587 回答
4

你很快就会用完数字。如果您有 64 个组,则您已经在使用 64 位。如果你有一百万个组,我不禁想到会发生什么。

另一个问题是,如果你删除一个组,你会失去一点。您可以稍后重用该位,但这可能不是您想要的方式。

于 2009-07-09T12:31:59.653 回答
2

好主意,但看不到在关系数据库中完成它会如何受益。我认为如果您使用 SQL,您几乎必须使用标准键,否则您拥有的昂贵存储有什么意义?

也许它更适合基于文件的存储,其中每个表都在不同的文件中。或者,将其作为附加列,但不要在其上放置主键。

PS 如果两个用户在同一个组中,它不会倒下吗?

瑞安

于 2009-07-09T12:29:59.827 回答
2

海事组织不好。这是典型的多对多关系。如果 PK 是 32 位,则一个用户最多可以在 32 个组中。为什么要限制设计?

// Sam 在所有组中。

假设您修改设计并使 PK 4 位插入 3。现在 Sam 是在“所有组”中还是仅在组 0-7 中?

有什么收获?

您将如何编写查询(连接)?我认为你会遇到这种设计的问题。

于 2009-07-09T12:37:42.853 回答
2

坏主意...索引将如何工作?它必须扫描并对每个值进行计算......

假设您想知道 X 组中的所有用户...您必须在每一行上运行一个函数来确定他们是否在该组中,而不是仅仅通过非常快速的索引搜索来找到您的答案.

编辑:简单地...给我写一个查询,它使用表上的索引来查找 B 组中的所有用户...无论如何,您将进行计算,这将迫使它进行后期过滤扫描

于 2009-07-09T16:15:58.910 回答
0

我最近经常看到 GUID 用作主键,我认为这是一个可怕的想法。GUID 代表“全球唯一 ID”,也就是说,它是一个标识符,其被复制的机会是,错误地引用了 Brockmeyer 在他的 OLE 书中的话“就像一堆原子在空旷的空间中聚集在一起形成一个小核桃”。

如果您确实需要全局唯一的东西,那么使用 GUID 有充分的理由,但大多数数据库键只需要相对于相关数据库是唯一的。在这种情况下,一个顺序生成的整数键通常就足够了,而且它在资源上的消耗要少得多。实际上,序列 ID 或 GUID 都没有任何内在含义,因此,如果可以的话,最好使用真正将相关对象标识为主键的项目(尽管有一种观点认为所有项目应该有一个与内容无关的键,例如序列甚至 GUID)。

位域作为主键有几个责任。如前所述,您可能会决定需要额外的位。你最终可能会发生碰撞。即使在那时,数据库也往往在按位功能方面很差并且不可移植。最后,您选择的数据库的索引算法可能无法很好地优化 bitset 键。

于 2009-07-09T12:47:04.323 回答