A better database design on SQL Server? - sql-server

In SQL Server, I need to design a User table. It should have a UserID (int), a RoleID (int) and a UserName (nvarchar(255)).
A user can be assigned with a name but possibly multiple roles so a UserId may correspond to multiple RoleIDs. This makes it difficult to assign primary key to UserID as UserID may duplicate.
Is there any better design other than breaking it up into multiple tables?

You should have:
1. a user table with UsertId(int), UserName (Varchar)
2. a role table with RoleId(int), RoleName(Varchar)
3. a user_role table with user_id(int), role_id(int)
And don't forget to add the proper indexing and foreign keys.

Ye, have a table Roles, then RolesUsers with UserID and RoleID, and lastly a Users table
edit: where the UserID + RoleID in the RolesUsers are a composite key

Related

SQL Server Database Design - 1 Table vs 2 Tables

I have a table named Report and another named ReportRights. The purpose of these tables are to restrict access to a report based on a user or user group.
The Report Rights table is
ReportRightsId (int - Surrogate Key)
ReportId (int - Foreign Key to Report)
UserId (int - null FK to Users)
GroupId (int - null FK to Groups)
HasAccess (bit default 0)
The issue with this is that I want to add a Unique Constraint to ReportId+UserId as well as to ReportId+GroupId but in this table structure I cannot because ReportId 1, UserId 1, Group Id NULL, and trying to add a permission for report id 2 trips the reportid 1 groupid null unique constraint.
Is this bad design? Should I have 2 tables: ReportGroupRights and ReportUserRights instead? If i were to make a front-end UI they would both be managed by the same 'grid' so 1 table makes sense to me...but the inability to enforce only 1 user record or only 1 group record is problematic.
What is the best practice for this problem?
It isn't bad design.
Make GroupId nullable, so you can as well enter permissions for user only.
Also, unique constraint should be on three columns together: ReportId, UserId, GroupId.
So you can allow more then one report per user/group.

UserRoles table with no PK

I have the following tables (among others):
Users
Departments
Roles
UserRoles
The UserRoles table has the following fields:
UserId
RoleId
DepartmentId (NULL)
The idea here is I can give a user a specific role, for specific department(s), if the DepartmentId is NULL, then this role applies to all departments.
The problem here I cannot make a composite primary key out of the three fields in the UserRoles table since the DepartmentId is nullable.
Should I just go with a unique index without a primary key since I cannot have a primary key for the first two columns only (that will prevent the user from having the same role to multiple departments), or should I change the whole structure to something else (any ideas will be appreciated).
I would make DepartmentID not null and assign a value of 0 to symbolize all departments. This will help you both in creating a PK and in queries where now you can simply say where DepartmentID = 0 instead of where DepartmentID is null.

SQL Regenerate Guid PK

Hello I have a scenario where I have multiple SQL databases, and a tool on a central database which connects to each user table on each database and builds a dataset.
The issue happens when say a user from one database is migrated to another. When the tool runs it encounters an issue because the user_id is a guid pk, and since users have been migrated across databases the dataset will end up having duplicate private keys in the final dataset.
My question, if I want to regenerate the user id guid for some user,
I of course have to also update all of the connecting foreign keys. Is
there a command in MS SQL to regenerate the GUID and also do so for
all connecting relationships?
ON UPDATE CASCADE is what you want, but you need to define it in the foreign key relationship ahead of time.
CREATE TABLE User (UserID UNIQUEIDENTIFIER, UserName varchar(30), ... )
CREATE TABLE UserData (DataID UNIQUEIDENTIFIER, UserID UNIQUEIDENTIIFER, ...)
ALTER TABLE UserData
ADD CONSTRAINT FK_UserData_UserID (UserID) REFERENCES User(UserID)
ON UPDATE CASCADE;

EF5 How to Add missing Relationships

Hi i have a database first EF5 model defined.
My user table has a primary key guid UserGUID
and another key field UserID with an auto-incrementing integer.
I have created a table called UserCustomField which has
UserID and I have created a foreign key constraint to UserID in my User Table.
When I update the model from the database all foreign key relationships to primary keys are generated but none to Key fields. Ignoring the potential point about using the guid through all my tables.....
A/ shouldn't EF add this relationship?
B/ how can i manually add it?
Cheers
Tim
A: No.
B: You cannot.
EF is able to use relations only when they point to primary key so either change User table to use UserID as primary key and remove UserGuid or change UserCustomField table to point UserID to UserGuid in the User table.
The reason why it doesn't work is that your database requires UserID in User table to be marked as unique (that means unique constraint) and EF doesn't support unique constraints yet.

SQL Server how to maintain GUID across tables in same DB

I want to create a DB , where each table's PK will be GUID and which will be unique across the DB,
Example: my DB name is 'LOCATION'. And I have 3 table as 'CITY' , 'STATE' and 'COUNTRY'.
I want that all the 3 tables have same PK field as GUID ,and that value will be unique across DB.
How to do this in SQL Server, any idea? I have never used SQL Server before, so it will be helpful if briefly explained.
create table CITY (
ID uniqueidentifier not null primary key default newid(),
.
.
.
)
Repeat for the other tables.
What do you mean exactly ?
Just create the table, add an Id field to each table, set the data type of the Id field to 'uniqueidentifier', and you're good to go.
Next, add a primary constraint on those columns, and make sure that, when inserting a new record you assign a new guid to that column (for instance, by using the newid() function).
I can't think of any good reason to have a unique number shared by 3 tables, why not just give each table a unique index with a foreign key reference? Indexed fields are queried quicker than random numbers would be.
I would create a 'Location' table with foreign keys CityId, StateId & CountryId to link them logically.
edit:
If you are adding a unique id across the City, State and Country tables then why not just have them as fields in the same table? I would have thought that your reason for splitting them into 3 tables was to reduce duplication in the database.

Resources