Naming conventions for MySQL tables - mysql

I would like to get some opinions since I am thinking about creating structure for my new application and I am struggling with names for tables so I thought maybe you can give me some ideas. App has users and users can create projects while projects can have multiple keywords. So users are in one-to-many relationship with projects and projects are in many-to-many relationships with tags.
So having table users I suppose projects table should be users_projects. But what about keywords? Should it be users_projects_keywords ? And what about pivot table since I think it is kinda bad to name it like users_projects_to_users_projects_keywords or something like that. I would be grateful for a tips.
Edit:
I always thought that one-to-many relationships should be called like x_y where y belongs to x. Is it not a good practice ?

I would have users, projects, keywords, project_keywords. I would use foreign keys to define the relationships between the tables. For example, projects would have a column such as createdby_userid, referring to the users.user_id column.

One idea:
There could be three dictionaries:
Table users should have id and other data.
Table projects as well.
And so table keywords.
Then you create "linking" (relations) tables:
users_projects with column id, id_user, id_project
projects_keywords with id, id_project, id_keyword
EDIT:
Maybe it indeed would be rational to include id_user into table projects as mentioned by #Laurence.

Related

follower/following relationship

I understand how basic database relationships work but I am confused about the following/follower social media relationship in RDBMs.
Users table:
userId (PK)
email
name
Follow table:
followerId (FK referencing userId),
followeeId (FK referencing userId)
This seems to be the correct database design but what I really want to know if this is a one to many or a many to many relationship.
I think it is a many to many because a user can follow many users and be followed by many users. But it may be a one to many because each follow a user makes consists of one userId to follow. This isn't the perfect many to many example such as Students and Classes so it is confusing me. Thanks.
It looks to me like your database design is consistent with your use case.
You have many-to-many relation between users, where a user may :
follow many users
AND be followed by many users
To represent this relationship, you have created a bridge table, the follow table. This is the relevant way to proceed.
The difference with a the typical Student/Class relation is that both objects being in relation are stored in the same table (users) : this is why you end up with two foreign keys in the follow table referencing user.userId. But regardless of this specifity, this is conceptually the same type of relationship.

how can I create a table 'post' where author can be of various types

I have two tables.. lets say 'staff' and 'customer'. Now anyone who can post on the social networking site has to be either staff or a customer..
I have created another table by the name 'post' but how can I keep track of the author using foreign key constraint if author can be of any two types and they are also stored in two different tables. Any help would be appreciated!
You are asking more about normalization practices rather than a true/false type question.
It is difficult to imagine what you're attempting without a schema, but it is likely better that you use a single table for users (staff and customer) and have a column that foreign-keys over to a user-type table. Then you only have a single user_id PK to use as your FK in your posts table.

ID Refer to Table Rather than Column within Table

Multiple Voting Table Schema:
Single Voting Table Schema:
Businesses, Products, and Comments can all be voted on. For the first obvious solution, I chose to create an association entity for each of the relationships. We thought maybe there would be a better solution, though.
After extensive research and looking around for a solution, I found the concept of the second schema, which is to have a single voting table with a column (Entity) to define the type of the table or the table in which the ID (EntityID being the ID of the Table it Came From) belongs to. The only problem is that there is no relationship between the voting table and the three entities. Is there a way for the Entity Column to refer to the table rather than the table's ID?
Any suggestions of other constructive ways of developing the schema are welcome.
I think you will find this answer very sufficient.
Why can you not have a foreign key in a polymorphic association?
What you're looking at here is a Polymorphic Association. It has many solutions, of which three are described thoroughly through the given post.
I would suggest you combine the Business, Product and Comment tables into a single table, with an additional colume to denote 'Type'. Then you can enforce your relationship to the Vote table.

Model a table that can have a relationship with several tables

I have a table called 'notes', on this table I need to track who made that note, but the problem is that the creator of the note can be a user stored in one of three possible tables:
users
leads
managers
I have though of simply create three fields on 'notes' to represent the three possible relations: note.user, note.lead, note.manager
With this approach I would be forced to create three table joins when requesting the notes to gather the creators information, and I don't think that is the way to go, so I would like to hear your ideas or comments and what would be the best approach on this.
For me personally this smells like a design problem on a totally different part of the schema: Are manageers not users? Do leads carry person information?
With any approach that creates a relation between one column and one of three others, you will need three joins for the select. If you can't rectify the underlying problem, I recommend you use
note_type ENUM('users','leads','managers')
as an additional field and
SELECT
...
IFNULL(users.name(IFNULL(managers.name,leads.name))) AS name
..
FROM notes
LEFT JOIN users ON notes.note_type='users' AND users.id=notes.note_source
LEFT JOIN managers ON notes.note_type='managers' AND managers.id=notes.note_source
LEFT JOIN leads ON notes.note_type='leads' AND leads.id=notes.note_source
...
for the query
I think you need to abstract out the concept of a user id, so that it does not depend on their role. The author of a note could then be specified by the user id.
Users could be assigned roles, and maybe more than one.
The correct way to structure this would be to pull all common data out of users, leads, and managers. Unify this data into a "contact" table. Then if you want to get all notes for a given manager:
managers->contacts->notes
for a lead:
leads->contacts->notes
Notice your original post: "the problem is that the creator of the note can be a user stored in one of three possible tables"
From the structure of your sentence you even admit that all these entities have something in common; they are all users. Why not make the DB reflect this?
you have to model a parent table for the three tables you already have. Define a table that depicts generally user, leads and manager tables. Something like "Person". So you have all of the ids of the three tables and any common attributes on the Person table. And when you must define the relationship you put the foreign id "Person_ID" on the note table. And when you model user, leads and manager tables you also put the primary key as a foreign key to the Person table.
So you would have something like this:
Table users:
Users(
person_id primary key
...(attributes of Users)
foreign key person_id references Person.person_id
)
This model i depict is common to any relational model you have to model using parents and childs

Table design for tag-like categories in a directory

I noticed that most directory-like sites have categories created and managed by the site administrators while users choose / select which category they would like to post to. For such implementation, there would always be 2 table; a categories table and a listings table whereby listings table will consist of a column that contains the category ID.
This design is straightforward if there are only a few categories and if you know the categories on hand.
But what if you have a lot of categories (i.e. 2000+ categories) or you allow user to specify their own categories (i.e. tags)?
If we create a category column in the listings table, it'll contain duplicate categories. Likewise, if we create a separate categories table, it too will contain duplicate as the categories are specified by the users.
What is the best practice when it comes to designing database for such scenario?
Thank you in advance.
The number of categories doesn't really change anything, but the UI for selecting 1 out of 10 categories will look very different from the one with 2,000 categories.
Duplicates are prevented by adding appropriate constraints to the database tables. This doesn't change when users can add tags themselves either. A listing have a one-to-one or a one-to-many relation with categories. The former is best implemented as a foreign key in the listing table to the category table. The latter is best implemented as an additional table with two foreign keys; one for category and one for listing. Make the primary key a composite key consisting of the listing key and the category key.
However, what the database cannot enforce, is a unique "meaning".
Users may independently create the following categories:
Java Programming
Java Porgramming
Programming, java
All about Java
... and they might all mean the same thing. That last category may also be a category related to coffe making, but I wouldn't bet on it :)
Stackoverflow has to deal with this, and I suspect you could find information about how if you searched Meta stackoverflow
Why not to look at wordpress approach to this? WordPress.com is really huge and it has far more than 2000 tags or categories. You can download latest WordPress at www.wordpress.org. Database schema is at wp-admin\includes\schema.php file in plain SQL.