简体   繁体   中英

Django MySQL database design

I'm trying to optimize the MySQL DB on a Django app that provides search results for items for users to buy. It has been recommended to me that one option was to vertically split my Items table into multiple tables. After some thought, I've realized I'm using the table for three separate purposes:

  1. Query rows for results relevant to some search term.
  2. Display paginated results that are relevant to the search term.
  3. Direct a user to any external pages they click.

So as far as I can tell, my best option is to split the table according to these needs (Is this a correct assumption?).

At the moment my model looks like this:

class Items(models.Model):
    categories = models.CharField(max_length=64)
    title = models.CharField(max_length=128)
    description = models.CharField(max_length=1024)
    thumb = models.CharField(max_length=255, unique=True)
    vendor = models.CharField(max_length=16)
    url = models.CharField(max_length=255, unique=True)

After a horizontal split, the tables would look something like this:

# Query all fields in this table for the search term
class ItemSearch(models.Model):

    categories = models.CharField(max_length=64)
    title = models.CharField(max_length=128)
    description = models.CharField(max_length=1024)

# Once a set of relevant results has been compiled, query this table to get all information needed to display it on the page.
class ItemDisplay(models.Model):

    title = models.CharField(max_length=128)
    thumb = models.CharField(max_length=255, unique=True)
    vendor = models.CharField(max_length=16)
    # foreign_key referencing ItemSearch.id?

# Once a user clicks on an item they want, send them to a RedirectView associated with the products ItemDisplay.id: r'^item/(?P<item_id>[0-9]+)$' 
class ItemOut(models.Model):

    url = models.CharField(max_length=255, unique=True)
    # foreign_key referencing ItemDisplay.id?

Obviously these tables are not currently linked, so once I query ItemSearch , I have no way of finding the associated rows in ItemDisplay , and subsequently doing the same thing for ItemOut .

How can I associate these tables with each other?

You should not split your tables by "purpose". You should split the table if this removes duplication or eliminates redundancy. This process is called "Database Normalisation".

I can't really see why you would do this at this point in time as i can't spot any redundancy. Also in Django it is easy to do this at a later point in time with Django Migrations.

There is a good example of "Database Normalisation" here to understand the concept: Django - how to normalize database?

Database tables should be split based on their relationships not by purpose (once things start getting big enough not to fit onto one server then there can be exceptions to that rule).

"One item may belong to many categories" for example, or instead "many items belong to many categories" - these would have different table structure to reflect the cardinality of the relationship.

Having read your comment in the other reply about increasing performance, splitting the table is unlikely to bring much benefit.

If you only want to return specific fields to reduce the amount of network traffic, try using values() , or values_list() methods on your queryset. This will have the same effect as using smaller tables.

https://docs.djangoproject.com/en/1.11/ref/models/querysets/#values

The obvious way to increase performance would be to add some indexes, as you don't seem to have many. The first column to add these to would be the ones that are being searched.

This is a really good resource to learn about indexing. http://use-the-index-luke.com/

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