简体   繁体   中英

What is the best way to handle these MySQL database relationsships?

I'm building a small website that let users recommend their favourite books to eachother. So I have two tables, books and groups. A user can have 0 or more books in their library, and a book belongs to 1 or more groups. Currently, my tables look like this:

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      |
|----------|------------|---------------|---------|

As you can see, the relationsships between users+books and books+groups are defined in the tables. Should I define the relationsships in their own tables instead? Something like this:

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      |
|----------|---------|

Thanks for your time.

The second form with four tables is the correct one. You could delete rel_id from books_users_relationsship as primary key might be composite with both user_id and book_id , just like in groups_books_relationsship table.

You do not need a "relationship table" to support a relationship. In Databases, implementing a Foreign Key in a child table defines the Relation between the parent and the child. You need tables only if they contain data, or to resolve a many-to-many relationship (and that has no data other than the Primary Keys of the parents).

The second problem you are facing, the reason the Relations become complex, and even optional, is due to the first two tables not being Normalised. Many problems ensue from that.

  • if you look closely at book , you may notice that the same book (title) gets repeated

  • likewise, There is no differentiation between (a) a book in terms of its existence in the world and (b) a copy of a book, that is owned by a member, and available for borrowing

    • eg. the review is about an existing book , once, and applies to all copies of a book ; not to an owned book .
      .
  • your "relationship" tables also have data in them, and the data is repeated.

  • All this repeated data needs to be maintained and kept in synch.

  • all those problems are eliminated if the data is Normalised.

Therefore (since you are seeking the "best way"), the sequence is to normalise the data first, after which (no surprise) the Relations are easy and not complex, and no data is repeated (in either the tables or the relations).

  • when Normalising, it is best to model the real world (not the entire real world, but whatever parts of it that you are implementing in the database). That insulates your database from the effects of change, and functional extensions to it in future do not require the existing tables to be changed.

  • It is also important to use accurate names for tables and columns, for the same reason. group in non-specific and will cause a problem in future when you implement some other form of grouping.

  • The relations can be now defined at the correct "level", between the correct tables.

  • The need to stick an Id column on everything that moves severely hinders your ability to understand the data and thus the Normalisation process, and robs the database of Relational power.

    • Notice that the existing keys are already unique and meaningful, short and efficient, no additional surrogate keys (and their additional index) is required.

    • ReviewerId, OwnerId and BorrowerId are all MemberIds`, as Foreign Keys, showing the explicit Role in which they are used.

  • Note that your problem space is not as simple as you think, it is used as a case study and shipped with tutorials for SQL (eg. MS SQL, Sybase).

▶Social Library Data Model◀

Readers who are unfamiliar with the Standard for Modelling Relational Databases may find ▶IDEF1X Notational◀ useful.

I have provided the structure required to support borrowing, to again illustrate how easy it is to implement Relations on Normalised data, and to show the correct tables upon which borrowing depends (it is not between any book and any person; only owned book can be borrowed).

  • These issues are very important because they define the Referential Integrity of the database.
  • It is also important to implement that in the database itself, which is the Standard location (rather than in app code all over the place). Declarative Referential Integrity is part of IEC/ISO/ANSI Standard SQL. And the question has a database design tag.

  • Referential Integrity cannot be defined or enforced in the non-SQLs (sometimes it can be defined but it is not enforced, which is confusing and fraudulent). Nevertheless, you can design and implement whatever parts of a database your particular Non-SQL supports.

If there is anything you do not understand, feel free to ask questions, either as a comment, or as an edit to your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM