MySQL relationship within the same table? - mysql

I have a web application where you can create a group. A group can be one of 3 options,
Organization
Client
Team
A client group and a team group are relatively simple, however the organisation is a little more complicated.
An organisation can have multiple clients, now my confusion is coming from how do I create this relationship, as the organizations, clients and teams are all saved in the same table. What is the best way to set this up? Should I create a client table that just contains a unique ID and the ID of each client in the groups table, and create a relationship between that and the groups table?

The way I understand it, your application requires hierarchical groups. In other words, Organization is a group but it also contains another group, such as Client. From your comments, it appears that you want to treat all three as groups.
I can suggest the following table:
entity
+ id INT UNSIGNED AUTO_INCREMENT
+ parentId INT UNSIGNED
+ type ENUM ('Client','Team','Organization')
+ name VARCHAR(255)
+ address VARCHAR(255)
For top-level entity such as an Organization, parentId will be zero. For a client/team group, parentId will refer to the id of an organization group. Actually, any kind of hierarchy is possible with the above definition.
If your columns for different groups need to be different, then you need multiple tables but one table can contain the group hierarchy as noted above.

Related

Mysql table relation for a user with multiple business

How to properly implement mysql table relation such that a user can create multiple business and each of those business can have multiple users. thanks
Basically going to be two (possibly 3 tables):
Business Table:
business_id int (this will be the primary key)
business_name
whatever extra fields that relate to the business
User Table:
user_id whatever type (this will be the primary key)
user_name
whatever extra fields that relate to the business
The relational part you can implement in one of two ways:
add the business id to the user table. So user table will have an additional field business_id and will relate back to one of the rows in the business table. This implies a user can only relate to 1 business.
If you want a user to be able to relate to one or more businesses then you need a separate table:
Business_User Table:
business_id int
user_id (whatever type you picked)

Database design issue in project?

I am designing a database for my app. In which I want to do mapping between multiple tables. Now situation is like There is one user table. User can have generate multiple orders. So I was thinking if I can put json obejct of order_id in a column in order table. Or I can create a user_id column in order table & repeat user_id for same user. So which is a better way of doing it?
PS: What is the standard way of doing it?
You should just have user_id in your order table, then make queries like
select * from orders where user_id = *some_user_id*
A user can place multiple orders which in turn can have multiple line items. Each line item can have n quantity of a specific product. So when product comes in picture, then it becomes many to many relationship between user and product because a user can place order for many products and a product can be ordered by many users. So my suggestion is -
Create a User table with UserID
Create a PurchaseOrder table with OrderID, UserID and LineItemID
Create a LineItem table with OrderID, ProductID and LineItemID
Create a SKU table with ProductID
A user can place multiple orders.
Based on this you should maintain three different tables as given below:
User (user_id,...)
Order (order_id,...)
UserOrder (user_id,order_id,...)
Only the primary keys in the above tables are focused
Storing comma separated list or json object will worsen the design. And this is strongly discouraged.
EDIT:
As #NevilleK suggested, the above design is typically used for many-to-many relationships. For one-to-many relationship you can create a foreign key constraint in orders table where user_id should refer to the user_id in the User table.
But still you can adopt the above design for one-to-many relationship since many-to-many qualifies for one-to-many too.
The best way is to have different table for your
User table - which hosts the user information
Transaction table - which will have order_id against each user_id.
Transaction table will carry all the transaction details with user_id. If you create a JSON object, how will you map the USER to the transaction. So at the time of retrieving the json information you will have to map it to the user table anyway. I suggest you the use the above said method, which will help you maintain and scale your application much easily.

Abstract databases design.

So I'm creating a web app with different user types that can come from different countries. Examples of the user types would be company, staff etc. Where a company would have a company_name field and staff would not.
In the users database I'm wondering if it's a good idea to implement a one table per column approach i.e for each user attribute there would be a table with a foreign key which would be the user_id and a value for the attribute value.
eg.
users.company_name =
id(PK), | user_id(FK) | 'company_name'
1 | 1 | company 1
users.email =
id(PK), | user_id(FK) | 'email'
1 | 1 | user#email.com
The same could be applied to an address database where different countries' addresses have different values.
Opinions?
The term you're looking for is "The Party Model"
You want to use Table Inheritance†, also known as subtype/supertype relationships to model stuff like this.
An Individual is a concretion of an abstract Legal Party. An Organization (e.g. a Company) is also a concretion of an abstract Legal Party.
"Staff" is not a subtype of Legal Party. It's a relationship between a Company and an Individual. A company hasMany staffRelationships with individuals.
I recommend Single Table Inheritance, as it's fast and simple. If you really don't like nulls, then go for Class Table Inheritance.
create table parties (
party_id int primary key,
type smallint not null references party_types(party_type_id), --elided,
individual_name text null,
company_name text null,
/* use check constraints for type vs individual/company values */
);
I'd go with PostgreSQL over MySQL (or MariaDB) if you're going to use Single Table Inheritance, as the latter do not support check constraints.
You can make user belongTo a party, or make party haveOne user.
† Which is different than PostgreSQL's Inheritance feature.
I'd create a single users table with company_name and email columns.
For addresses table, I'd start with something simple like this: id, address_line_1, address_line_2, city, state, country, zip.
With this strategy you'll have to do a lot of joining tables to get a meaningful query result. As a result your performance will suffer and you have very ineffective use of storage.
You should at least combine columns that will typically be combined for a logical entity in your application. So if a 'company' differs from 'staff' in that it has extra columns, you would create a table 'users.company_properties'.

MySQL database with user created tables with custom column numbers

I have a person table and I want users to be able to create custom many to many relations of information with them. Educations, residences, employments, languages, and so on. These might require different number of columns. E.g.
Person_languages(person_fk,language_fk)
Person_Educations(person,institution,degree,field,start,end)
I thought of something like this. (Not correct sql)
create Tables(
table_id PRIMARY_KEY,
table_name_fk FOREIGN_KEY(Table_name),
person_fk FOREIGN_KEY(Person),
table_description TEXT
)
Table holding all custom table name and descriptions
create Table_columns(
column_id PRIMARY_KEY,
table_fk FOREIGN_KEY(Tables),
column_name_fk FOREIGN_KEY(Columns),
rank_column INT,
)
Table holding the columns in each custom table and the order they are to be displayed in.
create Table_rows(
row_id PRIMARY_KEY,
table_fk FOREIGN_KEY(Tables),
row_nr INT,
)
Table holding the rows of each custom table.
create Table_cells(
cell_id PRIMARY_KEY,
table_fk FOREIGN_KEY(Tables),
row_fk FOREIGN_KEY(Table_rows),
column_fk FOREIGN_KEY(Table_columns),
cell_content_type_fk FOREIGN_KEY(Content_types),
cell_object_id INT,
)
Table holding cell info.
If any custom table starts to be used with most persons and becomes large, the idea was to maybe then extract it into a separate hard-coded many-to-many table just for that table.
Is this a stupid idea? Is there a better way to do this?
I strongly advise against such a design - you are on the road to an extremely fragmented and hard to read design.
IIUC your base problem is, that you have a common set of (universal) properties for a person, that may be extended by other (non-universal) properties.
I'd tackle this by having the universal properties in the person table and create two more tables: property_types, which translates a property name into an INT primary key and person_properties which combines person PK, propety PK and value.
If you set the PK of this table to be (person,property) you get the best possible index locality for the person, which makes requesting all properties for a person a very fast query.

How to structure my Users Database?

I have a website that allows users to be different types. Each of these types can do specific things. I am asking if I should set up 1 table for ALL my users and store the types in an enum, or should I make different tables for each type. Now, if the only thing different was the type it would be easy for me to choose only using one table. However, here's a scenario.
The 4 users are A, B, C, D.
User A has data for:
name
email
User B has data for:
name
email
phone
User C has data for:
name
email
phone
about
User D has data for:
name
email
phone
about
address
If I were to create a single table, should I just leave different fields null for the different users? Or should I create a whole separate table for each user?
Much better if you could create a single table for all of them. Though some fileds are nullable. And add an extra column (enum) for each type of users. If you keep your current design, you will have to use some joins and unions for the records. (which adds extra overhead on the server)
CREATE TABLE users
(
ID INT,
name VARCHAR(50),
email VARCHAR(50),
phone VARCHAR(50),
about VARCHAR(50),
address VARCHAR(50),
userType ENUM() -- put types of user here
)
Another suggested design is to create two tables, one for user and the other one is for the types. The main advantage here is whenever you have another type of user, you don't have to alter the table but by adding only extra record on the user type table which will then be referenced by the users table.
CREATE TABLE UserType
(
ID INT PRIMARY KEY,
name VARCHAR(50)
)
CREATE TABLE users
(
ID INT,
name VARCHAR(50),
email VARCHAR(50),
phone VARCHAR(50),
about VARCHAR(50),
address VARCHAR(50),
TypeID INT,
CONSTRAINT rf_fk FOREIGN KEY (TypeID) REFERENCES UserType(ID)
)
Basic database design principals suggest one table for the common elements and additional tables, JOINed back to the base table, for the attributes that are unique to each type of user.
Your example suggests one and only one additional field per user-type in a straightforward inheritance hierarchy. Is that really what the data looks like, or did you simply for the example? If that's a true representation of your requirements, I might be tempted (for expedience) to use a single table. But if the real requirements are more complex, I'd bite the bullet and do it "correctly".
Try creating four tables:
Table 1: Name, email
Table 2: Name, phone
Table 3: Name, about
Table 4: Name, address
Name is your primary key on all four tables. There are no nulls in the database. You're not storing an enumerated type but derive the type from table joins:
To find all User A select all records in table 1 not in table 2
To find all User B select all records in table 2 not in table 3
To find all User C select all records in table 3 not in table 4
To find all User D select all records in table 4
You should not create tables for different people because this will lead to a bloated database. It's best to create a single table with all the fields you need. If you don't use the field, pass in null values.
I would suggest that you use 1 single table with nullable fields. And a table of something like roles.