这里有一些通用表,我试图完全理解如何正确设置数据库表。这些设置是否正确?我希望能够尽快查找用户的项目和项目详细信息。此示例的FYI ItemDetailsX不共享相同的数据字段。
我有点卡在外键和辅助键上。什么时候使用辅助密钥和外键?
tbl_Users 1:* tbl_Item // relationship
tbl_Item 1:1 tbl_ItemDetail1& tbl_ItemDetail2 // relationship
tbl_Item 1:N tbl_ItemDetail3 // releationship
tbl_Users
-UserID - PK
tbl_Item
-ItemID - PK
-UserID - FK
tbl_ItemDetail1
-ItemDetail1ID - PK //如果我有ItemID,我甚至需要这个吗?它与
的关系是1:1-ItemID - FK
-Count
-duration
- 频率
tbl_ItemDetail2
-ItemDetail2ID - PK //如果我有ItemID,我甚至需要这个吗?它与
的关系是1:1-ItemID - FK
-OnOff
- 温度
- 电压
tbl_ItemDetail3
-ItemDetail3ID - PK //具有1:N关系
-ItemID - FK
-Contrived Value1
-Contrived Valu2
编辑:
感谢您的回复,我已更新原始帖子以正确反映我的数据库。
在我创建的数据库中,Item有~9项详细信息。每个项目的详细信息是5-15列数据。
拥有100个列的1个表没有意义......?
答案 0 :(得分:7)
数据库强制执行3种声明完整性:
键唯一标识表中的行。所有密钥在逻辑上都是等价的,但出于实际原因,其中一个被选为“主要”,其余的被认为是“备用”(有一些涉及NULL的并发症,但我们不在这里讨论)。
另一方面,FOREIGN KEY是一种从一个表到另一个表的“指针”,DBMS本身保证这个“指针”永远不会"dangle"。外键引用“父”表中的(主要或备用)键,但“子”端点本身不需要是键(通常不是)。
约束会更改数据的含义。另一方面,索引不会改变数据的含义 - 它们纯粹是出于性能的原因。有些数据库甚至可以让你拥有一个没有底层索引的密钥,尽管这在性能方面通常是一个坏主意。主键下面的索引称为“主索引”,所有其他索引都是“辅助索引”。
顺便说一下,有“二级索引”并且有“备用密钥”,但没有“二级密钥”这样的东西。我不太确定你的设计目标是什么,但我猜这样的事情将是一个不错的起点:
我认为没有任何目的可以将细节提取到单独的表如果,它们始终与项目保持1:1的关系。
在能够达到最佳数据库设计之前,您需要先问自己一些问题:
项目与细节之间是否存在真正的1:1关系,还是实际上是1:0..1(即某些细节是可选的?)。
是否预先确定了所有详细信息(即您是否可以放心地说,您不需要在应用程序生命周期的后期添加任何新的种细节)?
您还可以考虑将所有细节概括为名称/值对,并在单个1:N表中表示它们(此处未显示)。这是非常灵活和“可演化的”,但有其自身的一系列问题。
您打算如何查询数据?这是一个很大的问题,可能会影响是否采用“列”或“单独表格”方法,索引等...
顺便说一下,带有单独表格的1:0..1可以像这样建模......
......和1:1可以这样建模......
...但是这引入了循环依赖,必须以特殊方式处理(通常由deferring FOREIGN KEY之一。)
1:N细节当然是另一回事,并且通过单独的表自然建模。
由于你说“细节1”和“细节2”是1:(0 ..)1而“细节3”是1:N,你的“更新”数据模型可能看起来像这样:
顺便说一句,上面的模型使用识别关系,这导致更“自然”的关键。 非识别关系/代理键方法如下所示:
每种方法都有其优点,但这篇文章已经变得有点长了;)......
答案 1 :(得分:0)
您的问题无法在一篇简单的SO帖子中回答。创建数据库时需要考虑很多事情。我曾经做过的关于数据库以及如何创建它们的最好的事情是阅读Michael Hernandez撰写的一本名为“数据库设计为真人”的书。
See my post on Programmers问题您如何处理数据库设计?