Reputation: 2200
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:
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?
Upvotes: 0
Views: 197
Reputation: 11879
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/
Upvotes: 1
Reputation: 713
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?
Upvotes: 2