I am building an API using Django/DRF and Postgres for an application that takes reservations for spas, salons etc.
I expect to have a large number of providers (spas) who provide a menu of similar services, but at differing prices.
Provider 1 Menu
---------------
Pedicure ($50)
Manicure ($40)
Thai Massage ($100)
Balinese Massage ($120)
Provider 2 Menu
---------------
Pedicure ($60)
Manicure ($50)
Head Massage ($120)
...
Provider 35000 Menu
---------------
Pedicure ($25)
Manicure ($25)
Balinese Massage ($90)
I am trying to identify the appropriate models to represent this situation
This is what I have come up with:
class ServiceCategory(models.Model):
Category = models.CharField(max_length=100, blank=True)
def __unicode__(self):
return self.Category
class Service(models.Model):
Category = models.ForeignKey(ServiceCategory)
Name = models.CharField(max_length=100, blank=True)
def __unicode__(self):
return self.Name
class Provider(models.Model):
Manager = models.OneToOneField(User)
Category = models.ForeignKey(ServiceCategory)
Name = models.CharField(max_length=100, blank=True)
def __unicode__(self):
return self.Name
class MenuItem(models.Model):
Provider = models.ForeignKey(Provider)
Service = models.ForeignKey(Service)
Price = models.DecimalField(max_digits=9, decimal_places=2, db_index=True)
def __unicode__(self):
return self.Provider.Name + "-" + self.Service.Name
How will this structure perform to serve queries of the following types:
- Retrieve the entire menu for any one provider, with prices
- Retrieve a list of all providers (filtered by geo, sorted by price) that provide a class of services (say Massages)
- Retrieve a filtered list of all providers that provide a specified service (Thai Massage)
Intuitively I am concerned about the table for MenuItem
growing huge and slow in no time, say 1 to 4 million rows, that too accessed by AJAX and Mobile Apps via the API.
What would be a better way to model this for performance?
Maybe de-normalization, PostgreSQL settings, (mem)caching, or breaking up the table?
Retrieve the entire menu for any one provider, with prices
Retrieve a list of all providers (filtered by geo, sorted by price) that provide a class of services (say Massages)
Doing a reverse lookup like that will be hard, but you can a relatively efficient lookup like so:
Retrieve a filtered list of all providers that provide a specified service (Thai Massage)