Should I split the mySQL tables? - php

Lets take the example from Yelp: http://www.yelp.com/boston
You can see that it's a website with several different categories, each category containing a listing of places. Should I include all the different places/listing in a single table, or let each category have its own tables?
EDIT: this means having tables 'places_restaurants' and 'places_nightlife', instead of just having the single table 'places' and every entry of every different category will be stored in one huge table... Will this affect performance?

One table per category will require that you CREATE a table every time there's a new category. I'd prefer CATEGORY and PLACE tables, with a one-to-many or many-to-many relationship between them.

You should keep all of the categories in the same table and then have a CategoryID which actually maps each category to the specific / desired category. Your application should be built in a way that is inherently extensible which creating tables each time is definitely not.

It depends. You could normalize the database so that all categories are in their own table, and only referred to from other tables by a foreign key. But there are some arguments that performance outweighs normalization, and so it may be beneficial to keep category names both in their own table of record, and also to include a category name column in other, frequently-joined tables.
If you took the second approach, you would need to ensure data integrity by implementing UPDATE and DELETE triggers such that whenever a category changes in the table of record (presumably, not often), that other tables containing copies of category names also get updated.

It still depends on the application ,also, all the categories is a many to many fields with a main table and of course beliving u have some unique columns in each table

Related

Foreign key vs. SET data type MySQL

I have a MySQL database set up with a list of all my movies, which I imported from a MS Access database. One field contains the possible values for the genre of the movie, movies can have more than one genre, so I need a data type which supports this feature. In access I could link one table 'genre' to the field 'genre' in my table 'movies', so I could choose none, one ore multiple genres per movie. When I switched to MySQL I used the SET data type to define all the possible values. So far everything is running perfectly.
I am now trying to set up a table in html/php to show the mysql table. I want the table to be able to sort on: title, genre, quality, rating, etc. But for the sorting on genre, I would need the possible values from the set data type. I don't know if it is possible to get the values with some php command/code, but after I lurked around on the web for a while, I didn't see many applications where they use the SET data type for obvious negative reasons.
So I started looking into the Foreign Key possibility. The problem I have here is that -for as far as I know- the key can only contain one possible value, which puts me right back at the start of my problem. I do like the idea of a foreign key, because it would make it way easier for me to add a new genre to the list.
Is there a possibility I am overlooking? Is it possible to either get the values from the SET type to php or to use a foreign key with multiple possibilities for one record?
I know I can also put every genre in my php script manually, but I'd like to have it all on one place. So that if I add a movie with a genre I haven't defined yet, I can just update it at one place and everything else adapts to it.
Dagon is absolutely right here - you have an issue with the structure of the tables in your back end. You are wanting to model a many to many relationship when at the moment with your current back end the best you can do is a one to many relationship.
To review:
You have individual films that can have many genres
And you have individual genres that are related to many films
Relational databases actually don't model many to many relationships with one relationship they use recursion of the one to many relationship and create two joins.
To model a many to many relationship you need three tables
A film table (which I think you already have)
A genre table (which I think you already have)
A junction table which as Dagon suggests will consist of two fields film id and genre id.
You then set up two separate one to many relationships. One from the film table to the junction table and one from the genre table to the junction table.
Now if you want to know all the genres a film is in you simply filter the junction table on the relevant film id and if you want to know all the films with a certain genre you filter the junction table on the genre id.
Set up lookups to relate your genre ids to textual descriptions and bang you are free to change the textual description as much as you want and the great thing if you've done it right it will upgrade every single value in your forms.
This is an absolute fundamental concept of the algebra of sets behind the design of SQL and relational database design.

General efficiency questions regarding MySQL tables setup

I have couple questions regarding the best way to set up tables in MySQL DB.
Say I have multiple categories on a website; and I have multiple tables for those categories in the DB. However, for all the posts that use those categories, is it better to create only one table that holds all post records or separate them by the relevant category?
Same as above but for the user comments. Stick with one table or use multiple tables?
1) I would keep all the posts in one table- if they are separate you'd have to do joins anytime you wanted to query posts across multiple categories.
2) Same idea, you want all your comments to be in one location, regardless of category.
Have a table for posts. another table for categories and a table that contains the relationship between them consisting post_id and category_id. This type of relationship is called many-many read more here

Backend app in OO PHP: Structuring classes/tables efficiently

I'm currently working on an app backend (business directory). Main "actor" is an "Entry", which will have:
- main category
- subcategory
- tags (instead of unlimited sub-levels of division)
I'm pretty new to OOP but I still want to use it here. The database is MySql and I'll be using PDO.
In an attempt to figure out what database table structure should I use in order to support the above classification of entries, I was thinking about a solution that Wordpress uses - establish relationship between an entry and cats/subcats/tags through several tables (terms, taxonomies, relationships). What keeps me from this solution at the moment is the fact that each relationship of any kind is represented by a row in the relationships table. Given 50,000 entries I would have, attaching to a particular entry: main cat, subcat and up to 15 tags might slow down the app (or I am wrong)?
I then learned a bit about Table Data Gateway which seemed an excellent solution because I liked the idea of having one table per a class but then I read there is virtually no way of successful combating the impedence missmatch between the OOP and relational-mapping.
Are there any other approaches that you may see fit for this situation? I think I will be going with:
tblentry
tblcategory
tblsubcategory
tbltag
structure. Relationships would be based on the parent IDs but I+'m wondering is that enough? Can I be using foreign key and cascade delete options here (that is something I am not too familiar with and it seems to me as a more intuitive way of having relationships between the elements in tables)?
having a table where you store the relationship between your table is a good idea, and through indexes and careful thinking you can achieve very fast results.
since each entry must represent a different kind of link between two entities (subcategory to main entry, tag to subcategory) you need at least (and at the very most) three fields:
id1 (or the unique id of the first entity)
linkid (linking to a fourth table where each link is described)
id2 (or the unique id of the second entity)
those three fields can and should be indexed.
now the fourth table to achieve this kind of many-to-many relationship will describe the nature of the link. since many different type of relationship will exist in the table, you can't keep what the type is (child of, tag of, parent of) in the same table.
that fourth table (reference) could look like this:
id nature table1 table2
1 parent of entry tags
2 tag of tags entry
the table 1 field tells you which table the first id refers to, likewise with table2
the id is the number between the two fields in your relationship table. only the id field should be indexed. the nature field is more for the human reader then for joining tables or organizing data

Single Category Table For Entire Site Or Different For Different Use Case

product table has category, media table has category, ticket table has category.
Each of these has a HasMany relation with category table. There are two ways of doing it:
Have a common Category table with probably a type column and have intermediatory table like MediaCategory, etc.
Have separate tables like MediaCategory with each having same structure as category
First one is better I think in point of integrity.
IF the categories are not shared then it is best (in most cases) to have separate tables for each category type.
Here's the rationale:
The database is the gatekeeper of your data's relational integrity. In a well written program there should not be any foreign key violation exceptions, i.e. the code does not rely on the database to keep the relational integrity of the data. However should a bug creep-in, the relations in the database make the bug less likely to cause data corruption.
When using separate tables for media, products, etc. and their valid categories, the relational integrity can be easily maintained with a foreign key relationship; essentially any record in the media table can belong to any category in the media categories table. Ensuring the relation:
"Records in media table can belong to any category of type 'media' in
the categories table"
is less straight forward at the database level.
That being said, a problem whose solution is duplication of data structures makes the whole underlying structure suspect. This may not be so in your case, but you should look at the underlying use-cases that require the categories to be introduced and see whether they are better served in a different manner (say Free Text Search indexed keywords.)

Should I create a new table into my database for this?

On my database I have among other tables, products. Products table contains the id, name, description and some other data about the product. I want to add also a category.
Should I create a new table named category with and id and the name of each category, and have into the products a *category_id* that will refers to the id of category, or should I have the name of the category on each row of products ?
On the first case I will have to use JOIN. Will this have a serious impact on the performance?
By defining the categories in their own table you can:
Rename categories
Dynamically generate lists of categories for picking from
Add descriptions of categories
Add new categories
… and so on, without having to update every bit of category related code each time you modify them.
So yes, add a table.
Will this have a serious impact on the performance?
Probably not.
Yes you should keep your data normalized. I think create a new table named category is a good idea.
Will categories tend to change over time? In most instances that will be the case, so you're usually better off with a separate Categories table and a foreign key (FK) between the two tables. You can then add or change categories simply with data changes. Otherwise, you'll want to put a check constraint on the category name column in your table to make sure that you don't get junk data in there and that becomes much harder to maintain.
With proper indexing, the join should only have a minimal cost. Also, keep in mind that you won't always necessarily need to join the tables. You'll only need to join them when you want the actual category name as part of your result set. For example, if you have a look-up box on your front end with the categories and their IDs then your select of the Products only needs to return the category ID values and you don't need to even bother with a join.
The stock answer is "it depends". It depends on how the data is used, will be used, might be used. But once you get through all the discussions and arguments, for something this simple and prominent in your data, nine times out of eight you will be better off properly normalizing the data (i.e. Category table, CategoryId columns, and foreign key).
Only add a table if you require the extra functionality this level or normalization provides.
If you need to rename categories, or list them then yes this is a good candidate. If not then why bother with it, it will make your database slightly harder to read.
Join will most probably not be a performance impact but if you do not need it now, try not to be a victim of over-design.

Categories