我正在建立一个小网站,让用户可以互相推荐自己喜爱的书籍。所以我有两张桌子,书籍和小组。用户可以在其库中拥有0本或更多书籍,并且书籍属于1个或多个组。目前,我的表格如下:
books table
|---------|------------|---------------|
| book_id | book_title | book_owner_id |
|---------|------------|---------------|
| 22 | something | 12 |
|---------|------------|---------------|
| 23 | something2 | 12 |
|---------|------------|---------------|
groups table
|----------|------------|---------------|---------|
| group_id | group_name | book_owner_id | book_id |
|----------|------------|---------------|---------|
| 231 | random | 12 | 22 |
|----------|------------|---------------|---------|
| 231 | random | 12 | 23 |
|----------|------------|---------------|---------|
如您所见,用户+书籍和书籍+组之间的关系在表格中定义。我应该在他们自己的表中定义关系吗?像这样:
books table
|---------|------------|
| book_id | book_title |
|---------|------------|
| 22 | something |
|---------|------------|
| 23 | something2 |
|---------|------------|
books_users_relationsship table
|---------|------------|---------|
| rel_id | user_id | book_id |
|---------|------------|---------|
| 1 | 12 | 22 |
|---------|------------|---------|
| 2 | 12 | 23 |
|---------|------------|---------|
groups table
|----------|------------|
| group_id | group_name |
|----------|------------|
| 231 | random |
|----------|------------|
groups_books_relationsship table
|----------|---------|
| group_id | book_id |
|----------|---------|
| 231 | 22 |
|----------|---------|
| 231 | 23 |
|----------|---------|
感谢您的时间。
答案 0 :(得分:2)
具有四个表的第二个表格是正确的。您可以从rel_id
删除books_users_relationsship
,因为主键可能与user_id
和book_id
合并,就像在groups_books_relationsship
表中一样。
答案 1 :(得分:1)
您不需要“关系表”来支持关系。在数据库中,在子表中实现外键定义父和子之间的关系。只有在包含数据的情况下才需要表,或者只需要解析多对多关系(并且除父项的主键之外没有其他数据)。
你面临的第二个问题,关系变得复杂,甚至是可选的原因是由于前两个表没有被标准化。由此产生了许多问题。
如果仔细查看book
,您可能会发现相同的book
(标题)会重复出现
同样,(a)一本书在世界上的存在与(b)一本书的副本之间没有区别,这本书由一名成员拥有,可供借用
book
,一次,适用于book
的所有副本;不是拥有book
。 您的“关系”表中还包含数据,数据会重复出现。
所有这些重复的数据都需要保持并保持同步。
如果数据已标准化,则会消除所有这些问题。
因此(因为您正在寻找“最佳方式”),顺序是首先规范化数据,之后(毫不奇怪)关系容易且不复杂,并且不重复任何数据(在表格中或关系)。
规范化时,最好对现实世界进行建模(不是整个现实世界,而是在数据库中实现的任何部分)。这使您的数据库与变更的影响隔离开来,将来对它的功能扩展不需要更改现有的表。
出于同样的原因,对表和列使用准确的名称也很重要。 group
非特定,并且在您实施其他形式的分组时将来会出现问题。
现在可以在正确的表格之间的正确“级别”定义关系。
需要在严重移动的所有内容上粘贴Id
列,这会妨碍您理解数据的能力,从而影响规范化过程,并破坏关系数据库。
请注意,现有密钥已经是唯一且有意义,简短而有效,不需要额外的代理密钥(及其附加索引)。
ReviewerId, OwnerId
和BorrowerId are all
MemberIds`,作为外键,显示使用它们的显式角色。
请注意,您的问题空间并不像您想象的那么简单,它被用作案例研究并附带SQL教程(例如MS SQL,Sybase)。
不熟悉关系数据库建模标准的读者可能会发现▶IDEF1X Notational◀有用。
我提供了支持借用所需的结构,再次说明了在规范化数据上实施关系是多么容易,并且显示了借用所依赖的正确表格(它不在任何书籍和任何人之间;只是拥有本书可以借用。)
在数据库本身实现它也很重要,这是标准位置(而不是整个地方的应用程序代码)。声明性参照完整性是IEC / ISO / ANSI标准SQL的一部分。这个问题有一个数据库设计标签。
无法在非SQL中定义或强制执行参照完整性(有时可以对其进行定义,但不会强制执行,这会造成混淆和欺诈)。不过,您可以设计和实现特定非SQL支持的数据库的任何部分。
如果您有任何不明白的地方,请随时提出问题,作为评论,或作为对您问题的修改。