[英]What is the best way to handle these MySQL database relationsships?
我正在建立一个小型网站,允许用户向彼此推荐自己喜欢的书。 所以我有两个表,书和组。 用户在其图书馆中可以拥有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 |
|----------|---------|
谢谢你的时间。
具有四个表的第二种形式是正确的。 您可以从books_users_relationsship
删除rel_id
,因为主键可能与user_id
和book_id
组合在一起,就像在groups_books_relationsship
表中一样。
您不需要“关系表”来支持关系。 在数据库中,在子表中实现外键可定义父级与子级之间的关系。 仅当表包含数据或要解决多对多关系(并且除了父级的主键之外没有其他数据)时,才需要表。
您面临的第二个问题是,关系变得复杂甚至是可选的原因是由于前两个表未规范化。 随之而来的是许多问题。
如果您仔细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中定义或强制执行(有时可以定义但不能强制执行,这会造成混淆和欺诈)。 但是,您可以设计和实现特定的Non-SQL支持的数据库的任何部分。
如果您不了解任何内容,请随时提出问题,作为评论或对问题的编辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.