Foreign Key Issue ERD - mysql

Good day folks . I am building a relational database . I am at the ERD Stage and i am having a problem. The situation is a customer can either be representing themselves or a company and a company might have different customers because of different departments.
the problem is i need to link the customers and company table, as to run queries such as what organisation a customer works for, but not all customers rep a company therefore i am thinking i cannot put the com_ID attribute as a foreign key in the customer table or put the c_ID in the company table because there are instances where a customer doesnt represent a org therefore the foreign key would be null in some instances which i know cannot happen...Any suggestions would be great.
Thank you very much for your time

A foreign key can be null in MySQL and most DBMS. This is why you can create an ON UPDATE or ON DELETE SET NULL.
The best solution is primarily opinion, but using com_id allowing null values would seem to work fine. You can also set the default to null. This would also allow you to create customers before you create companies and then assign a customer to a company, depending on your software, creating a higher degree of flexibility.
For this I would also recommend the referential integrity of ON UPDATE CASCADE, ON DELETE SET NULL. This would allow you to keep a customer updated on the update of a company and the contact in your database should you delete a company*.

Related

MySQL How to create one to Zero or Many relation

i have entity customer and entity order, a customer can have 0 or more orders but an order can only have 1 customer.
I already tried a lot of things like making the foreign key unchecked at NN but I cant get a foreign key order at customer
EDIT: Using mySQL ERD workbench
Your customer table will have a unique customer_id column. In the MySQL world we often use autoincrementing primary keys for this kind of id column.
Your order table will have a customer_id column that's a foreign key to customer.customer_id.
This allows the order table to have any number of rows relating to a particular customer_id: none, one, or many. The foreign key relationship, when enforced--checked--simply prevents an order from having a customer_id value that references no valid customer.
Classic data design tools with their distinction between logical and physical design can drive ya nuts when you're trying to do easy stuff like this.
Pro tip if you name your id columns the same way everywhere they're used, data design tools tend to work better, especially when "reverse-engineering" your tables. That's why I suggested column names like customer.customer_id and order.customer_id rather than customer.id and order.customer_id.

Can A Foreign Key Be Used More than Once?

Apologies for the newbie question.
The primary key of a table, such as Holiday, would be something like Holiday_ID. Holiday reference a get-away ticket that you can buy to go on a type of holiday, based on the ticket you buy.
Suppose I used Holiday_ID in a composite entity with Customer_ID to identify an instance of Holiday associated with customer, for whatever purpose.
However, suppose I also want to keep track of other information related to this instace: how much has the customer paid for the ticket, how much has the customer yet to pay for the ticket
I have two options:
a) I can create another composite entity. However, I am not sure if I can do that because I am not sure if you can use a particualr foreign key more than once
b) I can create a composite/associate entity, however, I am not sure if you can create a composite entity with more than two foreign keys?
To answer the technical parts of your question, once you create a composite unique or primary key, ONLY ONE record in the table can have the same values in the set of fields defined in that key. SO, no, you cannot reuse the holidayId key WITH THE SAME customer. You can use it with another, different customer if you wish.
Second, there is no limit to the number of attributes that can be included in a Unique or primary key. If you need, and if it's appropriate and conforms to the rules of normalization, the key can include all the attributes of the table.
Third, to answer your question below, Any column, or set of columns in a table can be defined as a Foreign Key, as long as it is also the primary key or unique key of some table in the database. And there can be any number of FKs defined in a table, they can even overlap. (you can have HolidayId as a FK, and also have HolidayID and CustomerId as a composite FK) the only restriction is that the FK must reference a Primary or Unique Key of some table in the database.(It can also be the same table the FK is in as well, as when you add a supervisorId to an employee Table that is a FK to the EMployeeId of the same employee table)
This example illustrates one of the problems of using surrogate keys without also using a natural key. to wit, what, exactly is a "Holiday"? Is Christmas 2016 the same "Holiday" as Christmas 2015? Is Christmas in Aruba the same holiday as Christmas in Hawaii?
and then, about the composite table to identify associations of customer with Holiday, is it the same association if the customer goes to Aruba on Christmas the next year, or a different instance? What does the row in the table represent if the customer wants 5 tickets?
The first thing that should be done in database design is a logical design which defines, as clearly and unambiguously as possible, in business terms, the meanings of the entities for each table in the database.

Database 1...n relation with several owner tables

I want to create a database scheme and don't really know a solution for the following scenario:
I have users, teams and projects. I want to enable to create projects as a user, but also as a team. What I thought of, was to include two foreign keys in the projects table. One for 'userId' and one for 'teamId'. But in this case for each entitiy either userId or teamId would be null.
Is this a good solution or is there a better possibility to solve that?
You can create a constraint that would force userId != null OR teamId != null.
Alternatively, you can require each project to have a non null foreign key userId (some user in the team had to actively create the project, right?), and then create an associatedTeam foreign key (which can be optional).

MySQL cascading tables

(My website is built using PHP and MySQL.)
My DB structure for users is mainly composed of 2 tables: "doctors" and "clients".
However, in order to integrate a chat system, I need to create a third table, namely 'chat_users', which combines both doctors and clients: fields of 'chat_users' table are
userid (unique integer),
username,
type (0:client, 1:doctor),
refid (id of the user in the associated clients or doctors table)
But I do not want to insert/delete/update this table manually each time a client or doctor is inserted/updated/deleted. I heard about cascading table some time ago...
What would be the best way performance-wise to do so? How can I achieve it?
I'm not sure you'll consider this an "answer", but may I comment on your database architecture?
You will be much happier in the long run having the following tables:
user_account: (ua_id, ua_email, ua_username, ua_password, etc.)
doctor: (d_id, ua_id, etc.)
customer: (c_id, ua_id, etc.)
In other words, have your relation going the other way. Then if you would like to be able to delete a doctor or customer by simply deleting the user_account, you can add the following relational constraint:
ALTER TABLE `doctor`
ADD CONSTRAINT `doctor_fk_user_account` FOREIGN KEY (`ua_id`) REFERENCES `user_account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `customer`
ADD CONSTRAINT `customer_fk_user_account` FOREIGN KEY (`ua_id`) REFERENCES `user_account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
What you need is an AFTER INSERT Trigger. This would allow you to create new users. In case if you want it to be updated on update and deleted on delete of the original record then you need those triggers as well.
CREATE TRIGGER `chat_users_insert` AFTER INSERT ON `doctors`
FOR EACH ROW BEGIN
INSERT INTO `chat_users` SET user_id= NEW.id;
END;
The above would insert a record and set the value of id. http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html can give you exact syntax. Let me know if you need any specific clarifications.
I know, this is not exactly an answer to your question but what about using an old fashioned view instead? This would save you from storing redundant data altogether.
CREATE VIEW chat_users AS
SELECT drid uid, drid userid, drname username, 0 FROM doctors
UNION ALL
SELECT clid+100000, clid, clname, 1 FROM clients
This view will have unique uids only if you don't have more than 100000 doctors in your table (otherwise choose a higher offset). The advantage of this approach would be that there is no dependent table data to maintain.
"I do not want to insert/delete/update this table manually each time a client or doctor is inserted/updated/deleted."
Why are you fretting about this? Just do it. You have application requirements that mandate it, so unless you can figure out how to unify your client and doctor tables, you will need a third that relates to your chat function.
The difficulty of adding this in an application framework is almost zero, it's just the case of creating an additional record when a client or doctor is created, and removing it when their respective record is deleted.
The other answers here propose using views or triggers to obscure what's really happening. This is generally a bad idea, it means your application isn't in charge of its own data, basically handing over control of certain application logic functions to the database itself.
The best solution is often the most obvious, as that leads to fewer surprises in the future.

mysql: proper way to handle relation between users and teams?

Newish to mysql DBs here. I have a table of USERS and a table of TEAMS. A user can be on more then one team. What's the best way to store the relationship between a user and what teams he's on?
Lets say there are hundreds of teams, each team consists of about 20 users, and on average a user could be on about 10 teams, also note that users can change teams from time to time.
I can think of possibly adding a column to my TEAMS table which holds a list of user ids, but then i'd have to add a column to my USERS table which holds a list of team ids. Although this might be a solution it seems messy for updating membership. It seems like there might be a smarter way to handle this information... Like another table perhaps? Thoughts?
Thanks!
ps, whats the best field type for storing a list, and whats the best way to delimit?
whats the best field type for storing a list, and whats the best way to delimit?
It's usually a really bad idea to try to store multiple values in a single column. It's hell to process and you'll never get proper referential integrity.
What you're really looking for is a join table. For example:
CREATE TABLE user_teams (
user_id INT NOT NULL FOREIGN KEY REFERENCES users(id),
team_id INT NOT NULL FOREIGN KEY REFERENCES teams(id),
PRIMARY KEY (user_id, team_id)
);
so there can be any number of team_ids for one user and any number of user_ids for one team. (But the primary key ensures there aren't duplicate mappings of the same user-and-team.)
Then to select team details for a user you could say something like:
SELECT teams.*
FROM user_teams
JOIN teams ON teams.id= user_teams.team_id
WHERE user_teams.user_id= (...some id...);