use of views for validation of an incorrect login-id or an unidentified user - sql

I read this on msdn:
Views let different users to see data in different ways, even when they are using the same
data at the same time. This is especially useful when users who have many different interests and skill levels share the same database.
For example, a view can be created that retrieves only the data for the customers with whom an account manager deals. The view can determine which data to retrieve based on the login ID of the account manager who uses the view.
My question:
For the above example , i would have to have a column named Userid/LoginId on my table on which the view is created so that i can apply a check option in the view for this column. and then if a user with a name not in that column tries to enter data , then he/she is blocked.

Yes, you are right. You should
add a column with the user's login or database user name (say you call it username),
each row should have username populated with the login or database name of the person who is allowed to see that row
you can then build a view where you use the builtin functions SUSER_SNAME() (for logins) or USER_NAME (for database names) in your WHERE clause to filter only the rows the user is allowed to see
See Granting Row-Level Permissions in SQL Server (ADO.NET).

You don't have to add a column to the table: it could be more appropriate to instead add a new table to model the relationship.
There's a deisgn rule of thumb that states a table should model an entity or a relationship but not both. Let's say the table in question models the companies a customer owns (i.e. an entity table) and the business rule states the the account manager can only see companies relating to customers he looks after.
Is account manager an attribute of a company? No, so account_manager should not be a column (attribute) in the Companies table.
Is there a direct relationship between account_manager and a company? No, so a relationship table between is not due here (because the relationship is indirect).
Rather, the direct relationships are between account manager and customer, and between customer and company respectively. There should be two tables whose sole purpose is to model these relationships.

Related

Delegate data-access permissions from web-app to DB

I have a web application that reads data from a DB.
I have different users in my web-app and I'm thinking of delegating the functionality to determine "who can see what" to the DB instead than to the web-app.
Example:
On my DB I'm storing data for different customers. On the same table, I'm storing data for different customers, each row has a "customer" field that identifies the customer to which the row belongs. When the web-app queries the previous table, as the users in the DB are equal to the users in the web-app, the DB will return to the web-app only the rows to which the user has permissions to SELECT.
To implement this I have thought on the following process:
Use ROW-LEVEL SECURITY ACCESS to create a role per each customer. That role will only allow querying rows with Customer='CUSTOMER_NAME'
As the same CUSTOMER could have different types of users (EX: Marketing/Sales users). I want to create a common role for all customers that will filter the data that each type of user could SELECT.
I don't know if I could create a ROLE that will limit the rows that a certain user can select (EX: All the rows with CUSTOMER='CUSTOMER_NAME') and then grant another ROLE to the same user that will limit more the rows that the user can select (EX: All the rows related to a certain department: Marketing/Sales).
Are the roles applied from more restrictive to less? If so, my desired outcome is to have a single "Marketing" role with access to all Marketing-related rows and then to have a single "Customer" role with access to all Customer-related rows. Then the user with those roles will only be able to see Marketing related rows but only for a certain customer.
Is there any other way to do this?

Associate one column in table with two existing tables

My DB has following tables:
Resource: Some resources can be uploaded on site
Groups: Groups on site
Users: Users on site (not necessarily be part of any group but could be if they like)
Now, when some one uploads a resource then currently, ownership of that resource is given to it's uploader by default. So resource table has column OwnerID with foreign key association to User table.
But now, this has to be changed such that ownership of a resource could be given to either a user or entire group.
I'm trying to decide the migration scheme, to move this owner being user to an entity that could be either user or group. Intuition is that when someone uploads a material, he can choose its owner to be a user or entire group.
Currently my migration plans involves:
Add OwnerType (User, Group, Global) and UserOwner and GroupOwner within the Material table (probably worse normalized table).
OwnerType could be Global if owner is everyone --or-- Group if owner is group entity else user.
Then when I'm querying the Resource table, I can check the OwnerType to condionally select its Owner from either user table or group table.
I do not know if this is good way. I'm using entity framework, and things are already started to look ugly as User and Group hardly have any relationaship that would require me to make generalized entity.
Can some expert guide me on this? What is generally considered good migration plan in this case? Thanks for any help or suggestions.

1 to 1 database design

I have a database and normally users are the central object.
In database I have a tables roles and users in roles so I can give users different permissions on site.
But now I have one doubt.
I saw before one database with structure like this (User is in 1:1 relation to other tables):
User{UserId, Username, Email etc.}
Admin{UserId, some specific columns}
Child{UserId, some specific columns}
Admin{Parent, some specific columns}
and other tables are connected to user not through User table but through Admin, Child and admin.
Because now I design my database I have Users and user can be Admin, CompanyManager and Professor.
I wonder should I design table like I show above or just relied on roles?
What is advantage of the first approach?
And also in my business model User doesn't have to be CompanyManager or Professor so this is actually 1 to 0 or 1 design.
What is a good way to design database with scenario like this?
The advantage of having specific tables for certain types of users is to store information that is only relevant to that class of user.
In your example,
perhaps all users would have a manager - so the manager ID would go in the users column.
managers would have permissions to view certain information, so this would be handled via a role.
only professors would have a Subject, or the "HasTenure" property. So this information would go in a professors table. Using this approach, you avoid the need to have a "Subject" column in the users table, when it is only applicable to a certain subset of users. As such you avoid a functional dependency in the users table, and a violation of 3rd Normal Form.
I prefer this approach:
In this way, you can easily group Roles into categories and assign them to users.

Database design relations in User and Profile

I'm designing a web application for a school. So far, I'm stuck with the database which has these tables:
users
id
username
password
profile
user_id (FK)
name
last_name
sex
group_id (FK)
(other basic information)
... And other tables irrelevant now, like events, comitees, groups and so on.
So, the users table stores basic information about the login, and the profiles table stores all the personal data about the user.
Now, the *group_id* column in the profile table has a foreign key that references the ID column of the group in which the user is currently enrolled, in the groups table. A user can only be enrolled in one group at once, so there's no need for any additional tables.
The thing is that it doesn't make much sense to me declaring a relation like group HAS MANY profiles. Instead, the relation should be group HAS MANY users, but then, I would have to put a *group_id* column on the users table, which doesn't really fit in, since the users table only stores auth information.
On the other side, I would like to list all the users enrolled in a group using an ORM and getting the a users collection and not profiles. The way I see it, is that the users table is like the 'parent' and the profiles table extends the users table.
The same problem would occur when setting attendances for events. Should I reference the profile as a foreign key in the events_attendance table? Or should I reference the user ID?
Of course both solutions could be implemented and work, but which of them is the best choice?
I have dug a little and found that both solutions would comply with 3NF, so in theory, would be correct, but I'm having a hard time designing the right way my database.
This is a question of your own conventions. You need to decide what is the main entity, right after that you can easiy find a proper solution. Both ways are good, but if you think of User as of the main entity while Profile is a property then you should put GroupId into User, otherwise, if you mean User and Profile as a single entity, you can leave GroupId in Profile, and by this you're not saying group HAS MANY profiles but group HAS MANY users.
By setting a proper one-to-one relation (User-Profile) you can force your data integrity good enough.

Database design for CRM User table for a specific scenario

I'm designing a database for our CRM system and need some help with the CRM User table.
Types of users:
Admin
Sales Reps from Branch 2
Sales Reps from Branch 3
Client login
Now for this scenario would it make sense to have all users in a single table and have a table attribute called "type" to identify the type of user? OR should I have a seperate table for each type of user? Also, there will be some information sharing between the Sales reps.
Typically, I usually go with one User table with a Type associated with it. If you have additional Sales Rep attributes you want to store, create a SalesRep table with a foreign key back to the User table. Then, create a view that joins User and SalesRep, so it looks, logically, like there's just a usvSalesRep table that has all of the attributes you need for Sales Reps.
But, this depends a lot on data volume and transaction load, so additional information you can supply there is useful.
It depends on the number of users that you expect.
But usually a single table is enought.
If you'll have billions of users maybe you can do horizontal partitioning and make multiple tables.
Single table should be fine. And I disagree that the number users really have much impact on its design in this case.
Whenever possible, you should design your tables to mimick real life. Admin, Sales Rep, etc are just descriptions/attributes of who they are. Ultimately, they are all "People"... or User. So having one "User" table with "Admin", "SalesRep" as attibutes makes sense to me. Use the "Type" approach only if the user can only be one "Type". Use separate columns if they can be multiple user types. Ie. one can be a SalesRepBranch2 and SalesRepBranch3 at the same time. Might consider normalizing this even further.