How can we represent a relation where there is no need to add a foreign key in the table in DBDesigner? For Example, If i have 2 Tables As:
1) Admin
2) Machine
Suppose the relation "Admin can Add machines",
there is no need of Admin table's primary key to go in Machine's table as foreign key. Or you can say that i don't want to add it. But still i want to show this relation in my ERD. How can i do it using DBDesigner?
The best way is to create separate table Permissions.
Then there will be a row with specific permission Add machines
This way you can assign different permissions to different users.
Obviously you will need 2 more tables for this to work: Users where the user data is kept and say user_permissions with 2 fields only user_id & permission_id where you keep the info which user has which permission.
This is the right way to design scalable permissions that can expand and accommodate any set of permissions.
Related
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
I am doing a database on phpmyadmin. One of my tasks is to do a table called Users. One of the features the users will have is the ability to add another user as a friend. However, I am not sure how to go about this..
I thought of creating another table with the same data and use that ID as FK, however thought it was a bad idea since it is a many-to-many relationship.Instead, do I use the same table and do a foreign Key (Friend_id) inside it and give it an index and do a constraint using the same table?
I have a project which requires me to setup custom privileges, divided in three categories "Admin, Manager, User"
My regular approach is to distribute Privileges in one table as headers, then add a raw for each category with 0 or 1 to activate or deactivate the privilege for a group like follows:
id|name|can_do_this|can_do_that
1|admin|1|1
2|manager|1|0
3|user|0|0
however my professor requested that each privilege to be added separately per user no per group like follows:
id|user_id|privilege|active
1,1,can_do_this,1
2,1,can_do_that,1
3,2,can_do_this,1
4,2,can_do_that,0
my question, for the sake of my sanity.. which is more efficient? his point is that IF we needed to add a new privilege we won't need to ALTER the table to add a new column.
hope this question makes sense.
To me, this is a very simple data modeling issue. You have two "entities" in your data model:
users
privileges
This suggests that each one should have its own table.
Because this is a many-to-many relationship (many users can have a given privilege, one user can have many privileges), a third table is normally used for expressing the relationship; this is often called a "junction table" or "association table".
Your professor gives one very good reason for expressing the values in rows rather than columns: The ability to add new privileges.
I can add a few more:
The userPrivileges table can have a createdOn column so you know when the privilege took effect.
The userPrivileges can have a createdBy column, so you know who granted the privilege.
The userPrivileges table can have a suspended column, so you can temporarily suspend privileges.
I would suggest you the second one, because like that as your teacher says you don't need to Alter the table. Altering the table would mean adding a new 1 or 0 for each member in your table (you could use a default value but you will still need to change the values for those users that need the privilege).
The way your teachers says you could have another table with all the privileges, and use a foreign key.
That way you could add a new privilege and asign it to the users they need it with a default value of "1", and if you need to revoke the privilege change it for a "0". No innecesari rows will be added for default, that in small tables is not a problem but for bigger ones it is.
id |user_id |privilege |active
1 1 can_do_this 1
2 1 can_do_that 1
3 2 can_do_this 1
4 2 can_do_that 0
As per my experience, If you don't want to add the extra column every time whenever a new privilege required to be updated in apps. Then go with second option.
Benefit:
Option-1: There will be no redundant data for group and that can be managed easily as you can apply the unique constraint on the group name and hence it will not requires the insert every time.
Option-2: You don't need to add the alter the table you can simply verify does new permission is already there or not, if not then simply add a new insert or update the existing permission.
Dis-advantage:
Option-1: You need to alter the table every time whenever new permission comes in.
Option-2: Whenever you want to add the new permission for a group first you have to identify that the records already exists or not, then you have to insert into table. And while validating the is also a bit of complex compare to the first option.
So, both has its advantage and disadvantages. If you think from data redundant perspective then go with option-1, else go with option-2.
I would prefer to go with option-1 as per my knowledge, and what I will do I just maintain a extra table which identify the permission and physical column between them, and I will make it generic.
ThatsAll!!!
I'm designing a MySQL database with some tables for a clinic and I need three different user types: admin, medic and patient.
What I did was to create a table called users where its columns are precisely the common fields shared by admins, medics and patients (there is of course a primary key called id_user which auto increments every time a user is added).
Then I created three tables regarding the specific data for each user type: admin, medic and patient in which I have a field called id_user which is a foreign key to id_user in the table users.
When I tried to establish the foreign key constraint for the three user type tables, phpMyAdmin doesn't allow me to set ON DELETE as "SET NULL" (I think that would make sense because if I delete a user from the users table then it should automatically set the fields as NULL in the medic, admin or patient tables, right?) and gives me the error "relation has not been added".
Doubt 1: What's happening here that I'm not aware of?
Doubt 2: Should I forget this way of relating tables and simply add the specific fields for each user type in the users table although some users will have some fields set as NULL?
Here is an image illustrating my database:
You should use Cascading Deletes instead of setting fields null, if you delete a user you want them gone if you null out the data you'll just have tables filled with nulls.
Also from what i understand you created 3 tables for each of the permission levels if this is the case you should maybe handle that in code with conditions checking the permissions level
My questions are very simple, but I do not know an answer.
There is a table User. The User has a few photos in his profile on the site. There are at least two way to store links to photo. I can serialize an array of references to a string and store it, or create another table and store pair userId-link. Which way is better?
The user has a unique username column, email, phone. Is the following code right?
ALTER TABLE [User] ADD CONSTRAINT [LoginUk] UNIQUE CLUSTERED ([Login])
ALTER TABLE [User] ADD CONSTRAINT [EmailUk] UNIQUE CLUSTERED ([Email])
The user has the description of one car and one of the services, which he provides. Number of services and machines will not change. I can store the vehicle details (make, photos) in the profile of the user, or I can create a new table Car and create a 1-1 relationship. Similarly, I can do with the service. Which way is better?
Actually it's better to have one photos table and have a users_photos link table, then when you add photos to other entities, there's less to change.
People tend to have more than one phone number. If it's a business rule that they only have one number then leave that in the application layer, not the data layer.
One type of thing, one table for that thing. A car is a different thing than a user.