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
Related
I'm creating a database for personnel records and trying to ease record creation for the user and avoid a kludgy solution. The tables are:
people:
people_id,
person_name,
person_category_id
person_category:
person_category_id,
person type
document_requirement:
document_requirement_id,
document_requirement_name,
person_category_id,
document_section_id
document_section:
document_section_id,
document_section
I've created an append query (inner join) that populates a table caLLed document_repository which contains all of the required documents for all of the people. (I use a primary key composed of people_ID & document_id to avoid duplicates when the append query runs.) Here is the document_repository table.
document_respository:
document_repository_id,
people_id,
person category_id,
document_id,
document_section_id,
document_attachment
I'd like to be able to allow the user to create a document requirement that is applicable to multiple person categories. I understand I should avoid multi field values, which doesn't work anyway with inner joins. For example, if people categories include doctors and nurses, I'd like to be able to create a new document requirement that applies to both people categories (e.g., doctors and nurses), without having to create two separate document requirements.
More information needed?
Suggestions on design changes and/or queries?
Thanks!
snapshot of tables and relationships
What you describe is a many to many relationship. Each document requirement can be applicable to multiple person categories and different document requirements can be applicable to the same person category.
To have a many to many relationship between two entities (tables) in your database, you need another table to relate them. This additional table contains the primary key of both tables and each record in this table represents a link between the two entities.
Your naming is different between your text and your diagram, but I'll assume you want to have document_requirement records that can link to zero or more person_category records.
You need a table which for example could be called document_requirement_person_category and contains the following fields:
document_requirement_id - foreign key referencing PK of document_requirement
person_category_id - foreign key referencing PK of person_category
You then add a record to this link table for each person category that relates to each document requirement.
Edit: BTW, (if I'm reading your schema correctly), you already have a many to many relationship in your schema: document_repository allows a relationship between multiple people and a document requirement as well as multiple document requirements and a person. That's a many to many relationship.
I'm managing to create my first complicated J2E Solution and in every tutorial I find some sort of intermediary tables usage, like here :
Tables : User, User_Roles, Roles
While logic would simply add a key to user Table referring to it's role on Roles table, why the usage of that intermediary table ?
I thought it's one or two developpers choice, but everywhere I look for a tutorial, I find this sort of sql schema.
Is it better ? Does it help in something particular ? Speed, security ? Cause from a logic point of view, using one table User and a foreign key to Roles is better.
Thank you
This is a common database relationship modeling called M-N (Many To Many). A User can have many Roles, and a Role can be assigned to many Users, so you need the intermediary table. Here's another example: a Teacher can teach many Classes, and each Class can be taught by many teachers (during different semesters, for example). In this case you need a Teacher-Class intermediary table.
A different kind of relationship is 1-N (one to N). A User can have many Telephones, but each Telephone is owned by a single User. In this case, a User's primary key (PK) is exported as a foreign key (FK) into the Telephones table. No need for an intermediary table.
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.
I have the following tables created:
Animes(id,title,date), Comics(id,title,date), TVSeries(id,title,season,episode,date)
Some of them have already foreign keys (for one-to-many or many-to-many relations) of directors, genres, articles and so on.
Now i would like to create two more tables Reviews(id,rating,date) and Posts(id,thumbid,articleid,reviewid).
A review is about one Anime and/or Comic TVSerie and vise-versa but properties of a review may be in more than one table. Its the same about a posts.
Is this a typical example of one-to-one relation in separate table or is it more efficient to add more properties to the existing tables?
So more tables and relations or less tables more columns?
Thank you and i hope my question isnt that stupid but im a bit confused.
In my view, It is better to avoid foreign key relationship for one-to-one relationship. It is best suitable for one - many relationships.
I'm not exactly sure what your requirements are, but the choices are as follows:
Have Reviews have 2 columns, either being a foreign key to the applicable table, can be NULL. This is really for when a single review can be about both.
Have a ReviewsComics and ReviewsAnime table. You'd then have all the fields from Reviews in each table (and no Reviews table).
An alternative (2) is to use them in conjunction with a Reviews table, then those 2 tables only has 2 fields which are foreign keys to Reviews and Comics/Anime respectively (thus no direct link between Reviews and Comics/Anime).
Have a base table to which Anime and Comics are linked to 1-to-1 and have reviews link to that table instead.
(Edit) If all the fields are all going to be the same (or similar) for Anime/Comics, you can merge them into a single table and add a type field, indicating Anime/Comics, then the problem goes away. This is similar to the base table option.
EDIT: The 2 reviews tables will probably give the best performance (unless you want to select all reviews for either, often), but with proper indices the performance shouldn't be an issue with any of the above.
i wanna have a Users details stored in the database.. with columns like firstname, last name, username, password, email, cellphone number, activation codes, gender, birthday, occupation, and a few other more. is it good to store all of these on the same table or should i split it between two users and profile ?
If those are attributes of a User (and they are 1-1) then they belong in the user table.
You would only normally split if there were many columns; then you might create another table in a 1-1 mapping.
Another table is obviously required if there are many profile rows per user.
One table should be good enough.
Two tables or more generally vertical portioning comes in when you want to scale out. So you split your tables in multiple tables where usually the partiotioning criteria is the usage i.e., the most common attributes which are used together are housed in one table and others in another table.
One table should be okay. I'd be storing a hash in the password column.
I suggest you read this article on Wikipedia. about database normalization.
It describes the different possibilities and the pros and cons of each. It really depends on what else you want to store and the relationship between the user and its properties.
Ideally one table should be used. If the number of columns becomes harder to manage only then you should move them to another table. In that case, ideally, the two tables should have a one-one relationship which you can easily establish by setting the foreign key in the related table as the primary key:
User
-------------------------------
UserID INT NOT NULL PRIMARY KEY
UserProfile
-------------------------------------------------------
UserID INT NOT NULL PRIMARY KEY REFERENCES User(UserID)
Depend on what kind of application it is, it might be different.
for an enterprise application that my users are the employees as well, I would suggest two tables.
tbl_UserPersonallInformation
(contains the personal information
like name, address, email,...)
tbl_UserSystemInformation (contains
other information like ( Title,
JoinedTheCompanyOn,
LeftTheCompanyOn)
In systems such as "Document Managements" , "Project Information Managements",... this might be necessary.
for example in a company the employees might leave and rejoin after few years and even they will have different job title. The employee had have some activities and records with his old title and he will have some more with the new one. So it should be recorded in the system that with which title (authority) he had done some stuff.