My project is a website written in php & js that use a mysql database.
I need to store an item with its "category" or "type" (couldn't find a better name for that). Each item can only have one category.
Each category has a "name" (a sort of id) used by the php and javascript code, like "hat".
These "names" are hard-coded in the php/javascript code. They are not user-defined. There's a known list of them. There can be new "names" with new versions of the application, and eventually some can be removed.
Here are the solutions I considered:
This is the solution I'm currently using.
The database would look something like this:
items
categories
Downsides (for me):
The database would look something like this:
items
It has the advantage to remove the two-tables query of the first solution, but the data is still duplicated, and more heavily bould to the database than ever.
The database would look something like this:
items
The category name is stored directly in the "items" table, with a index. From the query view I have the impression that the index will act the same way that the second table I used previously (with the advantage of querying only one table and one index instead of two tables and two indexes)
What is the best way to do it, in term of performances and/or maintainability ? Is there another better way to do it ?
Having integrity constraint would be good but not necessary. (I can manage this problem in another way)
I have found the following thread: php mysql - should i add the field "category-name" to a table or not? , but it was about a many-to-many relationship and looks like it was a variable list of categories. So it doesn't really apply to my case.
It depends,
How many categories will you have, how often will you need to update them?
I've taken the approach before where I added Enum, but also wrote a static method in a class and stored the valid names there
class Item{
public static function get_categories()
{
// only works in php >=5.4 otherwise use return array('Category1'...);
return [
'Category1' => 'Category1',
'Category2' => 'Category2',
'Category3' => 'Category3'
];
}
}
Doing the above you can easily get access to the array by Item::get_categories(), which should correspond to the values in the ENUM field in the database. If you need to add more categories, add them to the database and then to this function. You can use this to validate the users choice and generate the javascript options.
However!!!!
You mention a seeding that populates your table, this wouldn't be able to easily update your ENUM for you.
I'd use an ENUM, because
1). It's easy to setup 2). It's slightly easier than joining the two tables (but JOINS are ace when you learn them) 3). If you used a secondary table you'd (as you pointed out) have to lookup the value from that table first, and then insert, or if the category was used in a dropdown, use the category id and it's name to populate the dropdown (i'd do it this way)
Final thought
The performance of both the ways (lookup table, and ENUM) you would barley even notice the difference unless your site is very very busy. You'd still have to update the categories table with each version both ways, but it would be slightly easier to USE an INSERT statement instead of a ALTER TABLE
Whichever way you chose, if you don't like it, it would be quite easy to update your code.
Hope this helps, and good luck
Remember Keep It Simple Stupid KISS
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.