I'm trying to design a system for giving users permissions on objects. Currently I have a database schema where there are roles and each role can have a permission on multiple 'securable objects'. Such an object can be a sensor, an other user or whatever new thing we might add later. So I have a table role_permissions that links a role to a user, sensor etc. A user can also have a permission directly, so there would also be a user_permissions table that link a user directly to a user, sensor etc.
Now the field that refers to a securable object can't be a foreign key, because the target objects can be of different types and thus come from different tables.
The problem I'm facing right now is how I can make Hibernate work with this. One-to-many relations won't work here I think because Hibernate can't possibly know in which table to look.
An alternative would be to create a role_user_permissions table, a role_sensor_permissions table, a user_user_permissions talbe, a user_sensor_permissions table, and a new role_other_type_permissions table + user_other_permissions table for every securable type that's in the system. So for every single type that needs to have permissions on it I would need 2 new tables to manage the permissions.
But now the database is cluttered with permissions tables that actually serve the exact same purpose but for different types. However, Hibernate IS happy to take this because through foreign keys it always knows what table to look in and what type the object is.
Does anyone know a best practice to solve this issue?
Thanks in advance,
Stan
Related
I've been looking through different questions on here and I can't find something that exactly matches my situation.
I am designing a database for multiple types of users. I have one main User table which includes ID, Username, Password, PasswordSalt, AccountType (enum), and LastLoginDate. I need to have multiple types of accounts: Student, Parent, SchoolAdmin, SystemAdmin, Coordinator, and Teacher. I was originally thinking of having a separate table for each of these types of accounts, but I realized that SchoolAdmin, Coordinator, SystemAdmin, and Teacher all share the exact same data. These account types all have different permissions though. The Student and Parent accounts have extra information that they have to store.
I then thought about adding the information that the 4 identical tables share to the User table and then deleting those tables, but I came across another problem. I need to reference different types of accounts in other tables. For example, I had a foreign key for TeacherID in the Club table to show who the club sponsor is. If I add the information to the User table and get rid of those other tables, then how do I reference a specific account type in another table?
I have never designed a database like this so any help is appreciated.
There are three main ways of implementing inheritance on database models. Please check the links below, and study which is the best one to solve your problem. Nothing better to start analyzing this types of situations to become a good architect.
Single Table Inheritance
Class Table Inheritance
Concrete Table Inheritance
Each of the different approaches have their pros and cons so choose wisely.
Here is a question from a newbie. I need to store music data(URL, artist ...) for each user. Should I put all data in one single table with distinct keys for each user. Or maybe it is good idea to have separate tables for each user.
I am making an online player.
Thanks in advance
You will create huge database if you are going to create seprate table for each user, make a table structure that will contain entries of all user in single table....
Create a single table with different user privileges for ex create an
group column table and provide different grouids to different users
e.g. groupid =1 for admin ,2 for normal user etc.
A separate table for each user is not appropriate.
You need one table for the music data (URL, artist, ...).
If the only item you store about users is the name, you can put that into the music data table as well without violating database design principles too much.
As soon as you store additional information about users (e.g. password, e-mail address) you need a second table for the user data and connect the music data to the user data via a foreign key in the music data table (or, in case of a n:m relation, a third table).
If you are looking for further information about database design, keywords are functional dependency and normalization.
Enhanced relationship diagrams may help you in designing your database. It might be worth mapping out your proposed database using these diagrams before you implement them.
This is a good tool to make sure you have a correct database design for you and as previously said below deal with functional dependency and normalization.
This is a good website to help you if you haven't done this before: http://users.csc.calpoly.edu/~jdalbey/205/Lectures/HOWTO-ERD.html
I am designing a database for MySQL to create a relationship between two users of an application. I am unsure of the best way to store the particulars of this relationship, though I currently intend to use one record per relationship in a link table called RELATIONS. Each user has basic data like their name and occupation stored in the USERS table, and more specific personal data stored linked by FKs in other tables, which we'll say are called OTHER1, OTHER2, and OTHER3, which will all contain some other data to be shared, we'll say each in a field called [Data] and identified with ID and USER_ID.
The difficulty is that the application allows users to specify what basic and advanced data that they show to each user, and vice versa. The RELATIONS link table needs to have FKs to USERS for the two users to set up the relationship, but I don't know how best to specify what data each user is able to share, because virtually all of the data that the database stores is stored optionally but all needs to possibly be hidden from a user that doesn't have permission to view it. The second user should be able to see if there is data there, however, so that he might request permission to view it.
My model for RELATIONS at this point looks like this:
RELATIONS
ID
USER_ID1
USER_ID2
USER1OTHER1_ID [(Value), Unshared, Null]
...
USER1OTHER100_ID [(Value), Unshared, Null]
USER2OTHER1_ID [(Value), Unshared, Null]
...
USER2OTHER100_ID [(Value), Unshared, Null]
So USER1OTHER1_ID will contain the FK to OTHER1 if User1 has shared it with User2, will be "Unshared" if it's present but unshared, and Null if User1 has no data in OTHER1. Same for USER2OTHER1 for sharing with User1. I don't like having a massive field array, though, and I don't like how I'd have to update all the relations if User1 later decides to add data to OTHER1. Is there a simpler and more normalised way of representing this?
I believe the normalized approach would be to only store whether userA has permissions to view the userB's data and not add FK references to it in the Relations table because you already have references to userB's data somewhere else. By storing additional references in the Relations table you are duplicating data and will have to ensure that it stays synchronized as you described in your question which will probably be an ongoing maintenance hassle and one more thing you have to keep in mind whenever you refactor your code.
If you only store permissions (no fks) in the Relations table you would join on a table (User?) to get the User's shared data or to see if it exists depending on the permission.
As far as having an excessive number of columns on the relations table, I don't think you will have enough to see a real degradation when querying the table (you could correct me on this). For clarity sake in the db code as well as your application code, I think you are better off to have a column for each permission than to try to find a short cut such as combining them in a clob or something.
The most succinct way I can readily imagine is to store one INT with the relationship, which is a bit-wise representation of the permissions; with the interpretation of that INT in the code. The INT will need as many bits as you have unique permissions, and then define constants for each of them. I'm not sure what language you are implementing in, but there about a few ways to skin this cat...
So, some pseudo-code might look like this:
define RELATION_PERMISSION_SEE_MY_PHOTOS = 1;
define RELATION_PERMISSION_SEE_MY_FRIENDS = 1<<1;
define RELATION_PERMISSION_SEE_MY_EMAIL = 1<<2;
and then build some arrays of supporting info (like localized strings, etc) to build your interface with, and then do something like this to modify it:
int new_permission = 0
foreach(user-selected-permissions as selected_permission) {
new_permission |= selected_permission
}
my_relation_model.permissions_flags = new_permission
one way would be to use essentially key value pairs..
similar to this:
user_1_id
user_2_id
field
privilege
.. because virtually all of the data that the database stores is stored optionally ...
Considering this, I would suggest 6NF for all user attributes.
The User table serves as an anchor and ideally holds only UserID.
Each user attribute has its own table with only UserID and the attribute value (6NF); a row exists only if the attribute is specified (all attribute values are NOT NULL).
Each attribute has also a sharing table with only OwnerID, VisitorID. A row exists only if the owner shares the attribute with the visitor.
In this model, a user can share only attributes that do exists. If you want to allow sharing of not specified attributes, point the OwnerID to the User table too.
To make thing simpler you can (should) create a view(s) for user data.
I am redesigning a database and I need some help.
I have two "User" tables, USER and APPLETCUST, with one being an internal user and the other being a customer.
Since I want them both to login to the same area, I think I need to create a new table that holds login information and whether or not the person is a USER or an APPLETCUST and then have a relationship to the respective USER or APPLETCUST to get that information.
What do you think? Is there a better way?
I'd recommend merging the table, but you already suggested it yourself :-) Creating a third table that references the two tables is also possible but might get messy unless you write the constraints properly.
I am trying to figure out how to structure this database. I have used Apple's core data before just fine, I'm just working on a different project now that requires MySQL. I am very new to MySQL so please go easy on me. :)
For this example, let's say I have three tables, User, Device, and Location. Drawing it out, a Location can have many Devices, but the Device can only have one Location; Each User has its primary key, UserID, of which I need to use to fetch the correct information.
So how do I create a relationship like this here? I've heard of creating an index and a foreign key and I'm not sure how they work exactly.
In the end, what I need to do is be able to access the User's specific table and view all of the Locations associated with that User. I will also need to be able to add a Device at a certain Location for a certain User.
Again, please forgive me as I'm trying to wrap my head around MySQL. I am using HeidiSQL to do my database editing.
User - Device is a many-to-many relationship, so you'll want to introduce an intermediary table to resolve that relationship. That table simply consists of two foreign keys, one referencing the User table and one referencing Device. Device - Location can be handled with a simple foreign key in the Device table pointing to a Location table.