处理这些MySQL数据库关系的最佳方法是什么?

时间:2011-01-22 12:43:59

标签: mysql relational-database

我正在建立一个小网站,让用户可以互相推荐自己喜爱的书籍。所以我有两张桌子,书籍和小组。用户可以在其库中拥有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      |
|----------|---------|

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

具有四个表的第二个表格是正确的。您可以从rel_id删除books_users_relationsship,因为主键可能与user_idbook_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)。

▶Social Library Data Model◀

不熟悉关系数据库建模标准的读者可能会发现▶IDEF1X Notational◀有用。

我提供了支持借用所需的结构,再次说明了在规范化数据上实施关系是多么容易,并且显示了借用所依赖的正确表格(它不在任何书籍和任何人之间;只是拥有本书可以借用。)

  • 这些问题非常重要,因为它们定义了数据库的参照完整性。
  • 在数据库本身实现它也很重要,这是标准位置(而不是整个地方的应用程序代码)。声明性参照完整性是IEC / ISO / ANSI标准SQL的一部分。这个问题有一个数据库设计标签。

  • 无法在非SQL中定义或强制执行参照完整性(有时可以对其进行定义,但不会强制执行,这会造成混淆和欺诈)。不过,您可以设计和实现特定非SQL支持的数据库的任何部分。

如果您有任何不明白的地方,请随时提出问题,作为评论,或作为对您问题的修改。