How to relate data correctly? - sql

I have this database where I am storing clothes from different retailers:
So each product has different colors
Each product also has different sizes
Each size has also different colors
Now for each product and for each different size and color, there could be different prices.
I am using Django for this, and I am asking any thoughts on how this database relation might work out.
Would I have something like this?
class Product(models.Model):
name = model.CharField()
class Size(models.Model):
size_of_product = model.CharField()
product = model.ForeignKey(Product)
class Color(models.Model):
color_of_product = model.CharField()
product = model.ForeignKey(Product)
size = model.ManyToManyField(Size,though="Price")
class price(model.Model):
size = model.ForeignKey(Size)
color = model.ForeignKey(Color)
date =model.Date()
Could anyone please suggest me of a better solution because obviously I don't have much practice with databases yet?
Thank You!

I propose the following to be close with your initial design:
class Product(models.Model):
name = models.CharField()
class Size(models.Model):
size_of_product = models.CharField()
class Color(models.Model):
color_of_product = models.CharField()
class ProductPrice(model.Model):
size = models.ForeignKey(Size)
color = models.ForeignKey(Color)
product = modelss.ForeignKey(Product)
price = models.DecimalField(...)
With that you'll have a list of products, a list of sizes and a list of colors. Whenever you want to add a variation for a product, you'll just a new ProductPrice instance with the price of the combination of all three (product, size, color) instances.
However, as a general comment, most e-shops do not work like this since products have more characteristics than color or size (for example manufacturer or material).
So, a more general solution would be to have a Category model that defines different categories of things (f.e shoes, jackets, trousers). Each Category has a number of Characteristics (for example color or material) and each Characteristic has a number of possible Values (for example blue, brown or leather, cotton etc). Finally, your Product which will be a specific item with a price, will belong to a specific Category and have specific Values for each of the Characteristics of that Category.
class Characteristic(models.Model):
name = modes.CharField()
class Category(models.Model):
name = modes.CharField()
# Each Category can have many characteristics and each
# characteristic may be related to many categories (e.g
# both shoes and jackets have color
characteristics = models.ManyToManyField(Characteristic)
class Value(models.Model):
value = models.CharField()
# each value belongs to a specific characteristic
characteristic = models.ForeignKey(Characteristic)
class Product(models.Model):
category = models.ForeignKey(Category)
# A product will have a number of values (e.g brown, leather)
values = models.ManyToManyField(Value)
prices = models.DecimalField()
So using the above design we can support as many characteristics as we want for each of our Products.

Ok, so you're modeling clothing. (Pun absolutely intended!) Fine, let's see what we can do about that.
Each product has different colors
Fine. The entity product has an attribute color. Let's continue.
Each product also has different sizes
Fine again. The entity product has an attribute size. So far so good.
Each size has also different colors
Um. Hold on. While a product may have a size and a color, a size cannot have a color nor a color have a size. As attributes, these relate to product, not to each other. Your modeling breaks down at this point.
I think what you mean is that all colors are not available in all sizes. This is different. In this case, a color is not directly related to a product, but a product/size combination.
You have correctly identified this as a many-to-many relationship. But it is between color and an intermediate product/size combination, not directly to product.

Related

Tableau How to color a chart based on two fields, one continuous and other discreet

I have a data set from Kaggle and here is what it looks like:
Now I want to plot a map using Tableau which illustrates the advantage/disadvantage of Republican/Democrat. Just picture this, because I have already had the total votes of each party in every single county, it is easy to compare which party won a county. My idea is depicting this fact: if a county is won by Republican, then it should be in red; if by Democrat, it would be in blue; otherwise it would be white if being won by minor parties (I am not sure whether there was such a case).
Note that if the more overwhelming a party is within a county, the darker should the color be. For example, if a Republican won a county tinily by 0.1%, it should be light red; if a county is won by Democrat with a landslide, say 30%, then it should be deep blue.
My problem now is that with the given data, I have no ideas about how to demonstrate the gap of votes between different parties. I guess I might need to create a calculated field that shows the vote difference with a county. But is it the right solution?
---- EDIT----
I found an example: https://public.tableau.com/profile/clillich.kltv#!/vizhome/ElectionResults_5/Dashboard1, it looks good to me. It is just uncertain what its data source looks like.
The example you have shown is perhaps not related to chart as you want. It shows only one measure. Please proceed like this.
Step-1 Create a calculated field win margin in percent with the following calculation
IF [Won] = TRUE then ([Total Votes] -
{FIXED [State],[County] : MAX(
IF [Won] = FALSE then [Total Votes] END )})/
{FIXED [State],[County] : SUM([Total Votes])}
END
Step-2 Convert it to dimension (by right clicking it).
Step-3 simultaneously create a group on party field as desired.
Step-4 select both fields in dimension pane and create a new hierarchy (party-group first and win margin second). Drag this heirarchy to marks card. Convert both to colors. The following gif may help
I think this serves your purpose. Good luck

Is it possible to get multiple sets of rows, each containing a limited number of rows, filtered by a column in a table in Django/SQL?

Sorry the question is so confusing, I couldn't find a way to word it better. This is better explained with an example:
I have an Image model linked to a Game model. Each Image has a category (the categories are fixed and number about 10). I want to get 3 images of each category (or less, if there aren't enough) for a game.
This is the current implementation:
from django.db import models
class Game(models.Model):
...
class Image(models.Model):
category = models.CharField()
image = models.ImageField()
game = models.ForeignKey(Game)
#classmethod
def categories(cls):
return ('category1', 'category2', ...)
#classmethod
def get_game_images(cls, game:Game):
return [cls.objects.filter(game=game, category=category)
for category in cls.categories()]
# Do stuff with the images
game = Game.objects.all().first()
for category in Image.get_game_images(game):
print(category)
for image in category:
print('\t', image.image.url)
I feel a bit dumb doing 10 very similar queries to retrieve 3 elements each... A simple Image.objects.filter(game=game).order_by('category') gets close, but then ensuring there are only 3 rows per category becomes a bit complex. Is there a better way to accomplish the same result?
Thank you
You can use a single query that makes a union of certain subqueries:
from django.db.models import QuerySet
# …
#classmethod
def get_game_images(cls, game:Game):
QuerySet.union(
*[cls.objects.filter(game=game, category=category)[:3]
for category in cls.categories()]
)
This thus will make one query, and furthermore the QuerySet is lazy so if you do not enumerate over it, call len(…) on it, etc. it will not make the query.
The [:3] at the end means we will fetch at most three objects for that game and category.

How to use Inversable features in prestashop

This is a very special problem I met in Prestashop.
I have a product, let's say a two color wooden stick, which is a normal 10" long stick. Half of it (5") can be blue and the other half red for example.
My product is this: Two color wooden stick. I have the following features: color 1 and and color 2 .
In the admin at the product's features I check red for the color 1 and blue for color 2.
Now the problem: when user filters using layered navigation, maybe they select blue for color 1 and red for color 2. This will result displaying 0 products as our wooden stick is inverse, but in the reality it's the same product.
How could I make that possible without duplicating the wooden stick product?
I see there is mismatching, your product 10" is not blue OR red, but blue-red in same time, so set two different colors is bad idea, instead I can propose you to do next, I hope when you said that you use color features it is named in Presta backoffice attributes, there is the difference between two this things in Presta, so:
in Catalog -> Product Attributes create new P.Attribute with name Color and for last option choose Color or textures in dropdown
add new Value for this new Color p.atrribute named e.g. "blue-red" and upload texture (img) that contains both colors. Repeat this procedure as much as needed.
in Layered navigation use this new p.attribute instead old
OR
another idea, create using same way 2 different color attributes Color1 and Color2, no textures, just use real separate colors there like "red", "blue". Then in product create combinations of this two colors and assign it to product.
In this case in layered navigation you will can set 2 filters - Color1, Color2 and customers will can to choose it. But, imho, first solution is better for UX.

Game Design: Data structures for Stackable Attributes (DFP, HP, MP, etc) in an RPG (VB.Net)

I'm wrangling with issues regarding how character equipment and attributes are stored within my game.
My characters and equippable items have 22 different total attributes (HP, MP, ATP, DFP). A character has their base-statistics and can equip up to four items at one time.
For example:
BASE ATP: 55
WEAPON ATP: 45
ARMOR1 ATP: -10
ARMOR2 ATP: -5
ARMOR3 ATP: 3
Final character ATP in this case would be 88.
I'm looking for a way to implement this in my code. Well, I already have this implemented but it isn't elegant. Right now, I have ClassA that stores these attributes in an array. Then, I have ClassB that takes five ClassA and will add up the values and return the final attribute.
However, I need to emphasize that this isn't an elegant solution.
There has to be some better way to access and manipulate these attributes, including data structures that I haven't thought of using. Any suggestions?
EDIT: I should note that there are some restrictions on these attributes that I need to be put in place. E.g., these are the baselines.
For instance, the character's own HP and MP cannot be more than the baseline and cannot be less than 0, whereas the ATP and MST can be. I also currently cannot enforce these constraints without hacking what I currently have :(
Make an enum called CharacterAttributes to hold each of STR, DEX, etc.
Make an Equipment class to represent any equippable item. This class will have a Dictionary which is a list of any stats modified by this equipment. For a sword that gives +10 damage, use Dictionary[CharacterAttributes.Damage] = 10. Magic items might influence more than one stat, so just add as many entries as you like.
The equipment class might also have an enum representing which inventory it slots to (Boots, Weapon, Helm).
Your Character class will have a List to represent current gear. It will also have a dictionary of CharacterAttributes just like the equipment class, which represents the character's base stats.
To calculate final stats, make a method in your Character class something like this:
int GetFinalAttribute(CharacterAttributes attribute)
{
int x = baseStats[attribute];
foreach (Equipment e in equipment)
{
if (e.StatModifiers[attribute] != null)
{
x += e.StatModifiers[attribute];
}
}
// do bounds checking here, e.g. ensure non-negative numbers, max and min
return x;
}
I know this is C# and your post was tagged VB.NET, but it should be easy to understand the method. I haven't tested this code so apologies if there's a syntax error or something.

How can I model complex role relationships where only certain groups of entities can take part in a role?

Let's say I have to model the meals of a diner.
A meal can consist of several "components":
(Fries OR rice OR wedges)
AND (One of six different beverages)
AND (One or two out of seven different sauces OR none at all)
Another meal can consist of:
(Salad OR rice)
AND (Garlic OR no garlic)
Further meals can consist of:
Just fries
Just a beverage
Just ...
How can I model this? (UML, entity-relationship, code, ... whatever you can explain best)
Perhaps it helps if you know some tasks I want to perform, so:
Allowing the customer to choose a meal first and display all remaining "add-ons".
Detecting a meal from a list of components. For example if the customer ordered fries, a sauce and a beverage, it should be possible to detect the meal from the first example.
I've thought about dividing all components into articles and then adding some kind of role mapping to mark "fries" as supplement to "cheeseburger", "schnitzel", "..." but then I wondered, how I could model multiple add-ons, optional add-ons, n-out-of-m add-ons...
I hope you can help me out...
If this is homework, it may not matter...
But - if this is going to be used in a real-world app, I would strongly recommend against using concrete classes for each food item ie. Coke class, Salad class, Rice class, etc. as recommended above.
This is a sure way to make your application inflexible.
It would be much better to have a food item class and a drink class with a name property or some such..
Imagine having to rebuild your whole application just because there is now a new special or food item... not cool ;).
I think what is missing from the other answers is the idea of a group.
Each food item could belong to a group along with other items, or by itself.
Say fries, rice, and wedges belong to group A. Drinks belong to group B.
Then you could model a combo as a list of groups - ie. 1 group A item and 1 group B item, or two group A items and1 group B item.
You could also make food items able to belong to multiple groups at the same time... to make the options more flexible.
The db model could get complicated defining all of the relationships, but I think it's necessary.
Perhaps something like this:
group(id, name, desc) - group of like items - entrees, appetizers, drinks... or anything
foodItem(id, name, desc) - represents a single item - fries, rice, etc.
foodItem_group(foodIgem_Id, group_Id) - maps food items to their group - many to many
combo(id, name, desc) - describes a combo
combo_group(combo_Id, group_Id) - maps groups to combos - many to many
I think this would do for representing the basic required model - you may want additional tables to store what the customer actually ordered.. and of course detecting if a customer order matches a combo is left up to your business logic.
It seems like an order can consist of either meals, components, or a mix of both, so I would say, have an Order class that has a list of Components and Meals. Meal should either subclass Component, or they should implement the same interface.
A Meal consists of several "slots," which can be filled by some set of Components. Meals should know how many slots they have and what Components can fill them.
The "detecting a Meal from a list of Components" question is tricky. Off the top of my head, the best way I can think of is giving each Meal a method that takes a list of Components and returns true if that Meal can be made from them (or maybe the subset of Components that would make up that Meal). Order would go through the list of Meals it knows about and see if any of them can be made from the Components in the current Order. There may be a better way to do this, though.
Hope this helps!
Create Component class, and sublcasses (or objects) for all possible types of Components.
Create an abstract Meal class, and subclasses for all possible types of Meals. A Meal can check, whether a certain list of Components matches it (for detecting a meal from a list of components). And a Meal can present to a customer all the choices of components for this meal.
I agree with Amanda that the Meal should be built of the "Slots". Each slot represents one of the Component choices of the Meal, e.g. Fries OR rice OR wedges. A Slot may also model the m-outof-n option.
The Meal class:
class Meal
{
class MealSlot
{
Add(Component);
bool DoesItMatch(vector<Component> ComponentsVector)
{
//Check if this Slot is filled by some element(s)
// of ComponentsVector
}
PrintSlotOptions();
vector<Component> Options;
// for m-of-n option, if multiple items can be chosen in this slot
int HowManyNeededToFillIt;
};
bool DoesItMatch(vector<Component> ComponentsVector)
{
//Check if all Slots are filled by ComponentsVector elements,
//using Slot::DoesItMatch function
}
void PresentChoices()
{
for(i=0; i < Slots.size(); i++)
Slots[i].PrintSlotOptions;
}
vector<Slot> Slots;
};
One of Concrete Meals: (Salad OR rice) AND (Garlic OR no garlic)
class MealType2 : public Meal
{
MealType2()
{
Slots[0].Add(Salad);
Slots[0].Add(Rice);
Slots[1].Add(Garlic);
Slots[1].Add(NOTHING);
}
};
Create an Order class which will contain a Meal name, and a list of Components. If a Meal is ordered, call Meal.PresentChoices() . And if a list of Components is given, go over all the Meals and call Meal.DoesItMatch .
I assume this will eventually get stored in a database. I suggest to create two tables:
Would store the components (fries, salad, garlic, etc)
Would have: id1, id2, relationship. Relationship being:
belongs to
goes with
Based on the "belongs to" relationship, you could find if all components belong to a certain meal. Maybe then go and select all components that belong to that meal and suggest the meal if the components selected make up 50% or more of the meal.
Based on the "goes with" relationship, you could suggest add-ons to the meal, or to the components selected.
seems like you meal can be almost any collection of food items, so start with one abstract base class (or interface) for a Food. make lots of concrete subclasses, one for each food: coke, tea, steak, chicken, potato, rice, pasta, soup, salad, etc.
make your components interfaces: appetizer, dinner, protein, starch, dessert, drink, etc.
refactor your concrete classes into whatever hierarchy they seem to want to go into as you write code and tests.
sprinkle in the component interfaces where they make sense.