ER-Diagram Company key - mysql

The following screenshot is ERD for one application or one business. If you have used QuickBooks youll know that it has starting form called company so in one application we can create many companies and maintain company accounts
if I add a column companyid to all table then I can add many companies in one application
what is the good practice:
Adding company key and exacting company info with company key
Creating database for each company if thrs 100 companies 100 mysql databases
please advice !

Creating a separate database per company is almost assuredly not what you want to do (unless you have a really good reason to need to do so). Adding a company_id to your tables and ensuring that columns you query against are indexed with company_id along with whatever other column you will typically be querying would be wise.
You'll also need to ensure that your application is designed to correctly inadvertent (or purposeful) access from one company to another company's data.
EDIT - Now that I see your ERD has been added: I would add a "company" table containing a company_id, name, and whatever other data you like, then ensure your other tables have an additional company_id field as well.

Since you want to maintain all companies' businesses and accounts within the same application, then there is no need to create a database for each company, just add a Companies table, then add a foreign key company_id to the other database tables

Related

What should the joiner table include when joining two tables?

I am working on a database which as a user table and a party table. A user can go to many parties and the party can host many users. So this is a many-to-many relationship. But since its not possible to have a many to many relationship between two tables, I created a joiner table called 'user_party' table. Now I am not sure what goes in the party table and what goes in the user_party table. For example, user table has basic columns like user_id, user_name, user_email, etc. and party table has information like party_description, party_time, party_location, etc. Should these party table values go to user_party table instead? What values should the joiner table include and what goes in the party table?
The joiner table should be here to maintain the relation between a particular user and a specific party, and in your case, not more.
Before all, the party should be uniquely defined with a party_id primary column. Then, a user_party table could be define with only two columns: a user_id and a party_id.
So, the join would involve 3 table rows uniquely identified:
One from the user table (identified by the user_id and storing all users details such as first_name, address...)
One from the party table (identified by the party_id and storing all the related info like location, start_datetime...)
One from the user_party(identified by the t-uple [ user_id, party_id])
The user_party table could only embed some data which are meaningful for single occurrences of the [ user_id, party_id] t-uple itself, such as the number of beer cans brought to a particular party :)
Eventually, these data could be externally stored into a specific table in order to keep only the relational aspect there and the t-uple extended with another key.
According to the underlying DB engine, the definition may go one step further, with the user_id and party_id columns of the user_party table declared as foreign keys, and additional drop and update triggers to handle automatic data binding across related tables.
I think I have a solution for you. As I understand from your description you need to change your schema a little bit, and your table should be look like below.
User(user_id, user_name, user_email);
party (party_id,party_description, party_time, party_location);
user_party (id,party_id,user_id);
hostuser_party (id,party_id,user_id);
Note: hostuser_party table is required if a party hosted by multiple users. If party always hosted by one user then you can add host_id(User_id) column in party table.

Should I use multiple databases in MySQL for my "hosting" platform? [duplicate]

Let us say I need to design a database which will host data for multiple companies. Now for security and admin purposes I need to make sure that the data for different companies is properly isolated but I also do not want to start 10 mysql processes for hosting the data for 10 companies on 10 different servers. What are the best ways to do this with the mysql database.
There are several approaches to multi-tenant databases. For discussion, they're usually broken into three categories.
One database per tenant.
Shared database, one schema per
tenant.
Shared database, shared schema. A tenant identifier (tenant key) associates every row with the right tenant.
MSDN has a good article on the pros and cons of each design, and examples of implementations.
Microsoft has apparently taken down the pages I referred to, but they are on on archive.org. Links have been changed to point there.
For reference, this is the original link for the second article
In MySQL I prefer to use a single database for all tenants. I restrict access to the data by using a separate database user for each tenant that only has access to views that only show rows that belong to that tenant.
This can be done by:
Add a tenant_id column to every table
Use a trigger to populate the tenant_id with the current database username on insert
Create a view for each table where tenant_id = current_database_username
Only use the views in your application
Connect to the database using the tenant specific username
I've fully documented this in a blog post:
https://opensource.io/it/mysql-multi-tenant/
The simple way is: for each shared table, add a column says SEGMENT_ID. Assigned proper SEGMENT_ID to each customer. Then create views for each customer base on the SEGMENT_ID, These views will keep data separated from each customers. With this method, information can be shared, make it simple for both operation & development (stored procedure can also be shared) simple.
Assuming you'd run one MySQL database on a single MySQL instance - there are several ways how to distinguish between what's belonging to whom.
Most obvious choice (for me at least) would be creating a composite primary key such as:
CREATE TABLE some_table (
id int unsigned not null auto_increment,
companyId int unsigned not null,
..
..
..,
primary key(id, company_id)
) engine = innodb;
and then distinguishing between companies by changing the companyId part of the primary key.
That way you can have all the data of all the companies in the same table / database and at application level you can control what company is tied to which companyId and determine which data to display for certain company.
If this wasn't what you were looking for - my apologies for misunderstanding your question.
Have you considered creating a different schema for each company?
You should try to define more precisely what you want to achieve, though.
If you want to make sure that an HW failure doesn't compromise data for more than one company, for example, you have to create different instances and run them on different nodes.
If you want to make sure that someone from company A cannot see data that belong to company B you can do that at the application level as per Matthew PK answer, for example
If you want to be sure that someone who manages to compromise the security and run arbitrary SQL against the DB you need something more robust than that, though.
If you want to be able to backup data independently so that you can safely backup Company C on mondays and Company A on sundays and be able to restore just company C then, again, a purely application-based solution won't help.
Given a specific DB User, you could give a user membership to group(s) indicating the companies whose data they are permitted to access.
I presume you're going to have a Companies table, so just create a one-to-many relationship between Companies and MySQLUsers or something similar.
Then, as a condition of all your queries, just match the CompanyID based on the UserID
in my file Generate_multiTanentMysql.php i do all steps with PHP script
https://github.com/ziedtuihri/SaaS_Application
A Solution Design Pattern :
Creating a database user for each tenant
Renaming every table to a different and unique name (e.g. using a prefix ‘someprefix_’)
Adding a text column called ‘id_tenant’ to every table to store the name of the tenant the row belongs to
Creating a trigger for each table to automatically store the current database username to the id_tenant column before inserting a new row
Creating a view for each table with the original table name with all the columns except id_tenant. The view will only return rows where (id_tenant = current_database_username)
Only grant permission to the views (not tables) to each tenant’s database user
Then, the only part of the application that needs to change is the database connection logic. When someone connects to the SaaS, the application would need to:
Connect to the database as that tenant-specific username

Multi-User Database

My experience with databases is limited so I am not sure of the best way to ask this question, so I am going to break it down as simply as possible. I've built an ASP.net application with a mySQL database using NHibernate that has multiple users that can log in and all work on the same table (let's say of forum posts). So we have our users table and our food table.
Now I am looking for the best way to split these users into groups, very much like different companies. So The users from the same "company" can log on and see all there other company users and edit/create posts view-able by said "company".
I am looking for the most scalable (fastest with 1000's of companies) way to do this. Should I
1: Have a universal table for users and posts with a foreign key? So everything is stored on the same SQL table but their view of this table is restricted by the company ID. I see this being the easiest one to build, but will 1000's of companies accessing the same table with this be slow/problematic?
2: Create a new posts table for every company? So every user from a company accesses their own table of posts. To scale up would this be more efficient/faster if there were thousands of companies?
A quick explanation of the best method would be really appreciated. But also pointing me to documentation/resources would be amazing! Cheers.
I strongly suggest option 1.
You should create company table with companyID as primary key. Use companyID as foreign key in users table and food table.
This is regular approach and works well in most of the cases.
It would be very complicated to maintain 1000's of tables in the application.
Users and food table will be already indexed by company ID so the filtering will be very fast.

Store the employee name in the report table or just the employee number that references an associative table?

I am creating a web application for internal use. One of the main features is the ability for the users to enter Sales Call Reports. My question is simply: Do I store the Employee Name and Company Name in the Call Reports table or do I only store the employee number and customer number in the table, as foreign keys and then retrieve the Employee Name and Customer Name, using the foreign keys, for display purposes? It seems like the foreign keys option would be procedural correct, however, it would be much easier to retrieve data from only 1 table when displaying the call reports.
Usually you'll save future-you a lot of pain by storing them separately as you've described.
On the face of it, and initially it seems like lots of extra work, but you'll end up with a much more flexible system, and 2 JOINS in a query isn't a lot.

Users table - one table or two?

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.