I have 3 tables -
User (Id, Name)
Roles (Id, Name)
UserRoles (UserId, RoleId)
I think they are self explanatory. How do I update an entry (UserId and RoleId) in UserRoles?
context.User.Roles gives me the list of roles but how do I update them?
Thank you.
From your comment:
context.User.Roles gives me the list
of roles. I can do a for-each and
update the Id, but how do I update the
corresponding UserId foreach RoleId in
that table?
First of all, you should NOT update the Id's.
Secondly, since you are using EF, you should try to think in terms of objects (or entities), rather than "DB-many-to-many-mapping-tables". Every User entity has a collection of Roles. If you remove a Role from the User.Roles collection and call context.SaveChanges(), the corresponding entry will be deleted from the UserRoles tabele. Similarly, when you add a Role object to the User.Roles collection, and save changes, a new entry will be created in the UserRoles table.
The following sample might be useful for clarity:
var user = context.Users.Include("Roles").Where(u => u.Name == "User1").FirstOrDefault();
user.Roles.Remove(user.Roles.Where(r => r.Name == "Admin").FirstOrDefault());
context.SaveChanges();
(null-reference checks omitted for simplicity).
Related
Consider this case,
a user can have many groups,
groups can have many users
only people belonging to a particular group can have access to a car belonging to that group
So i am not sure how the tables will look like
below are the tables
-- Creating a new User
INSERT INTO Users (UserLogin, UserPassword, UserName)
VALUES ('SomeUser', 'SecretPassword', 'UserName');
-- Creating a new Groups
INSERT INTO Groups (GroupName, GroupDescription)
VALUES ('GroupName', 'GroupDescription');
-- Finally, updating the junction
INSERT INTO UserGroup (UserId, GroupId)
VALUES ('UserId', 'GroupId');
consider another table cars
INSERT INTO Cars (Name, Model)
VALUES ('SomeCar', 'Model');
only those people who belong to a group can have access to the carsS
So should cars have many to many relationships with UserGroups?
INSERT INTO CarUserGroup (UserGroupId, CarId)
VALUES ('UserGroupId', 'CarId');
OR Should group have a one-to-many relationship with cars?
INSERT INTO Cars (Name, Model, GroupId)
VALUES ('GroupId','SomeCar', 'Model');
can u tell which approach is the best?
thanks
If a given car can have only a single group relationship, then your second version in theory would work:
Cars (Name, Model, GroupId)
However, this approach becomes undesirable as soon as a car can be associated with more than one group. The reason is that then we would be duplicating the car's metadata:
SomeCar, SomeModel, Group1
SomeCar, SomeModel, Group2
In general, you would do better to go with the standard junction table approach, and have a table which keeps tracks only of the relationships between cars and groups:
SomeCar, Group1
SomeCar, Group2
Then, let the Cars table exist to store the metadata for each car, with one car occupying only a single record:
SomeCar, SomeModel, SomeOtherMetadata
Since,
only people belonging to a particular group can have access to a car belonging to that group
So you should create a One-to-Many relationship between groups and cars. Now, why this should be done? The intuition behind this is that a user can have a car only if it belongs to a particular group, so the dependency of cars is on group. But since the car is a composite attribute of the group table, you make its owm table with a one-to-many relationship.
Another point is, when you delete a group, all cars associated with this group should also be deleted ( this is optional, you can also have null foreign key, in which case it will be an orphan child if you dont want to delete these entries from cars table ).
I have made 2 separate tables namely userlogin and userprofile with the following columns.
userlogin:
id
uname
pass
userprofile:
user_id(Foreign key)
name
gender
aboutme
Since i Will be taking some of the userprofile data at signup i was wondering what would be the best way to give the newly generated id from the userlogin table to the userprofile table.
I thought of making both insert queries right after one another but what if multiple users are signing up at the same time and one users login is saved with another users profile.
Should i instead go with saving the profiles foreign keyed with username?
If you worry about "simultaneous" sign up, you can use mysql transactions.
start transaction; then commit;
Example:
http://www.mysqltutorial.org/mysql-transaction.aspx
For the insertion with foreign key see this question: https://dba.stackexchange.com/questions/46410/how-do-i-insert-a-row-which-contains-a-foreign-key
Using a transaction is good, but there is probably another thing to point out here.
If id is AUTO_INCREMENT, then
INSERT INTO userlogin (uname, pass) VALUES (..., ...) -- without specifying id.
Get LAST_INSERT_ID() -- this gives you the value, and it is specific to your connection. That is no other connection can sneak in and grab your id.
Use that value for doing INSERT INTO userprofile (user_id, ...) VALUES ($id, ...)
Is there some reason for not combining the two tables? 1:1 relationships are rarely useful. as discussed here .
Ok i was told my last question was too wide so i try it more precise this time.
I need a Database Structure for a MessageBoard App.
I have 2 ideas but dont know which scales better.
Is there another possibility that is even better than my ideas?
There are Users, Messages and Groups.
All messages belong into at least one group but can be in more.
Users subsscribe to at least one Group and than can see all Messages of all Groups they belong to.
Users can create Groups at will.
Scale(theoretically):
Users: Millions
Messages: Billions
Groups: More than Users
I have two ideas right now:
Idea 1:
Table Users:
ID
All personal information...
GroupsSubscribed (string with all group IDs?)
LastUpdate (Date)
Table Messages:
ID
ImageURI
Text
Creator
Date
Groups
Answer_Messages_IDs (String with all IDs of messages that are an answer to this message)
Table Groups:
ID
GroupName
LastUpdate (Date)
Idea:
Message Get:
App gets every X seconds the Group-LastUpdate (DB call: Group)
If Group-LastUpdate > User-LastUpdate ->
Select all Messages where Groups contain Group and Date > LastUpdate (DB call: Messages)
Message Write:
App writes Message belonging to more Groups
Save Message in Message Table (DB call)
Update Group Table LastUpdate (DB call)
-----------------
Idea 2:
Table Users:
ID
All personal information...
GroupsSubscribed (string with all group IDs?)
NewMessages (string with MessageIDs?)
Table Messages:
ID
ImageURI
Text
Creator
Date
Groups
Answer_Messages_IDs (String with all IDs of messages that are an answer to this message)
Table Groups:
ID
GroupName
UserIDs (string with all user IDs)
Idea:
Message Get:
App gets every X seconds the User-NewMessages(DB call: Users)
If User-NewMessages != "" ->
Select all Messages where ID in List of NewMessages (DB call: Messages)
Message Write:
App writes Message belonging to more Groups
Save Message in Message Table (DB call: Messages)
Get Groups-UserIDs for every Group (DB call: Groups)
Update every User with new Message ID (DB call: Users)
This is an exercise in database normalization as #Paul Spiegel indicates above.
You would create something like the following:
Users
UserID PK
ImageURI
... personal user informational columns ...
Messages
MessageID PK
Text
UserID FK -> Users(UserID) // Message Author (Creator)
Date
Replies
MessageID FK -> Messages(MessageID)
ReplyID FK -> Messages(MessageID)
PK (MessageID, ReplyID)
Groups
GroupID PK
Name
Description
UserID FK -> Users(UserID) // Group Moderator -- I'm just adding this one in for fun.
User_Groups
UserID FK -> Users(UserID)
GroupID FK -> Groups(GroupID)
PK (UserID, GroupID)
Message_Groups
MessageID FK -> Messages(MessageID)
GroupID FK -> Groups(GroupID)
PK (MessageID, GroupID)
I moved ImageID from Messages to Users on the assumption that it is a user Avatar. If it is really something else associated with a message, then move it back.
There are three application integrity rules in addition to the PKs and FKs already included.
AIR #1 - The existence of a row in Messages implies at least one matching row in Message_Groups.
AIR #2 - The existence of a row in Users implies at least one matching row in User_Groups.
AIR #3 - A given ReplyID can only appear once in Replies. This keeps adjacency list semantics preventing a generalized many-to-many association and enforcing a hierarchical association.
The database join logic and application code is left as an exercise to the reader.
I am newly responsible for a database.
It contains the tables "users", "role" and "users_roles".
In "users_roles", "uid" (user id) from "users" and "rid" (role id) from "role" are mapped, as the former administrator told me.
WHAT I NEED TO DO:
I need to create a form by which users can register. Every newly registered user needs to appear in the table "users" of course and at the same time he must be attributed the role "7" and his "uid" must appear together with "rid" = 7 in the table "users_roles".
QUESTION:
I already know how to add the user to the "users" table. But how do I achieve, that his user id is mapped to the role id = 7 and that this entry appears in the table "users_roles"? Which SQL query do I need to write? $db->query(' ????????? ')
Regarding, "But how do I achieve, that his user id is mapped to the role id = 7 and that this entry appears in the table "users_roles"? "
There is always more than one way to do something. In this case, I would make 7 the default value of the role_id column in the users_roles table. That would make providing a role_id optional as you add new records.
I have 2 tables - one storing user information (id, username, password) and the second one storing information about events (id, name, description, date, username(represents the user who created the event)). I would like to implement 'favourite events' functionality. This would allow the user to store his favourite events and later display them in a list. I am not sure how to implement this in terms of design. I need a simple solution. Something like storing the IDs of favourite events in a field in the user table. I am using mysql and PHP. Can anyone point me to the right direction?
You want to have a table linking the foreign keys from the user and event tables.
Users Table:
id, username, password
Events Table:
id, name, description, date, username
Favorites Table:
id, user_id, event_id
This way you can easily access the list of favorite events.
SELECT events.name, events.description, events.date
FROM events, users, favorites
WHERE favorites.user_id = users.id
AND favorites.event_id = events.id
What you need is the most classic and basic many-to-many relationship.
You'll need extra table (let's say: user_event_ref) that will store user and event ids.
User:
id
name
Event:
id
name
UserEventRef:
user_id
event_id
In usereventref each column is a Foreign Key, and both columns are parts of Primary Key.
There's always the option to add a tiny-int field to the Events table flagging an event as a favorite. This doesn't violate normalization in that whether or not an even is a favorite has no effect on the other events. It has the added benefit of automatically deleting the event from favorites if the event is deleted.
If a sorting scheme is needed for the favorites you can still modify the events table in the same manner. If details about the "favorite" such as when it was added to the list etc is needed then you should use an additional table as suggested.