I am designing database architecture. I have user. User make request for order. Order is associated with payment. Once payment is completed, I want to generate sticker for that user.
Sticker has initial prize(i.e. $10). Now, admin can edit sticker prize. so, if admin change sticker prize then order will generate with new prize after change by admin.
By database architecture is as follow :
User(id, name, email, password)
Order(id, user_id, no_of_sticker,sticker_prize, address, status)
Payment(id, order_id, amount, date)
sticker(id, order_id, name, content)
sticker_info(sticker_prize)
Now, my question is--- is it good to create new table for just one single attribute.
That sticker_prize is only available for admin to edit
Please give your valuable suggestion.
Thanks in adv.
Creating the sticker_info table, for the purpose of storing a single value is ok from a database design perspective. You should ensure you have a primary key on the table so you can not get duplicate rows.
In larger systems, there are often lots of values like this, and often the solution is a table like: configuration( configId, configValue ).
Related
I am very new into backend stuffs like databases. That being said, I lack the database design knowledge.
I am wondering how and what is the best design for my scenario.
I am creating a social network app where the users can create groups and join other groups. Those groups have places in it. Those places are created by the User in the group
User
Group
Place
Rules:
One User can create and join many Groups
One Group can contain many Users
One Group can have many Places
Each Group have an admin User
I currently have 3 separate tables
1. USER TABLE
ID, EMAIL, USERNAME, PASSWORD, PROFILE PICTURE
2. GROUP TABLE
ID, NAME
3. PLACE TABLE
ID, NAME, COORDINATE, RADIUS
I am extremely confused in designing the proper database for it it.
Question:
How should I design the relation of the table.
I would like to have one User (maybe more) in a Group that has the permission to do certain stuff that normal User cant do. Such as Creating New Place, Deleting A Place
How should I define my table structure?
Any thoughts please? Any help is greatly appreciated!!
Thank you
You will need to have one more table in order to create what is known as a many to many relationship between the users and the groups.
Since you didn't specify the rdbms you are working with, I'll use SQL Server for my code:
CREATE TABLE TblUserToGroup
(
UserToGroup_UserId int FOREIGN KEY REFERENCES TblUser(UserId),
UserToGroup_GroupId int FOREIGN KEY REFERENCES TblGroup(GroupId),
UserToGroup_IsAdmin bit DEFAULT 0
CONSTRAINT UC_UserToGroup UNIQUE(UserToGroup_UserId, UserToGroup_GroupId)
)
As you can see, there is also an IsAdmin column that can take values of 0 or 1. If you only want one admin user for each team, you can add a check constraint to prevent having more then one admin for each group.
Like Facebook, I have posts, comments and user profiles.
I THINK THAT
Posts and comments do not need the details of user
ONLY user profiles need the details
So I separate the user information into main and detail
Here is the schema.
Question
Is it necessary to separate user data into main and details?
WHY not or WHY yes?
Thanks for applying!
I would recommend using separate tables because you may not need all that information at one time. You could do it either way but I think of it as do you need all of the data at once.
Table 1 (User Auth)
This table would hold only information for log-in and have three columns (user_name, hashed_password, UID)
So your query would select UID where user_name and hashed_password matched. I would also recommend never storing a readable password in a database table because that can become a security issue.
Table 2 (Basic Information)
This table would hold the least amount of information that you would get at signup to make a basic profile. The fields would consist of UID, name, DOB, zip, link_to_profile_photo, email and whatever basic information you would like. email is kind of special because if you require the user_name to be an email address there is no reason to have it twice.
Table 3 (Extended Information)
This table would hold any optional information that the user could enter like phone_number, bio or address assigned by UID.
Then after that you can add as many other tables that you would like. One for Post, one for comments, ect.
An Example of a Post table would be like:
post_id, UID, the_post, date_of_post, likes, ect.
Then for Comments
comment_id, for_post_id, UID, the_comment, date_of_comment, likes, ect.
Breaking it down in to small sections would be more efficient in the long run.
Database performance is associated with disk seek time. Disk seek time is a bottleneck of database performance. For large table, you may need large seek time to locate and read an entry. As for post and comments you do not need user details, just user main info, you may get reduced read time when you read only user Id for post and comments. Also joins with user_main_info will be faster. You may keep the smallest portion of data you need to read most frequently on one table and other detailed information on another table. But, in a scenario like when you will always need to read all the user information together, this won't give you any benefit.
1)the userinformation table will be added
ex:create table fb_users
(intuserid primary key,
username varchar(50),
phoneno int,
emailid varchar(max))
2)the sending of the friend request would be
2.a)create the table name called friends, friend requestor, friend requested by, status b/w both of them, Active flag
ex:create table fb_friends
(intfriendid primary key,
intfriendrequestor int (foreign key with fb_users's(intuserid)),
intfriendrequestedby int (foreign key with fb_users's(intuserid)),
statusid varchar(max)(use the status id from the below table which is a look up table),
active bit)
3)creating the table for the status the status
3.a)create the table name called status, statusname, statusdesc, Active flag
ex:create table fb_staus
(intstatusid primary key,
statusname varchar,
statusdesc varchar,
active bit)
the status could be
pending
approval
deleted
..etc
4)similarly for creating the groups,likes,comments also
a table will be created respectively for each one of them and the foreign key of the intuserid from user table
are linked for each of them
When create a user registration system, I'll be using user's email as the username.
When creating the database schema, should I then treat them as 2 separate fields or should I just treat them as 1?
eg.
USER_TABLE {USER_ID, USERNAME, FNAME, LNAME, EMAIL}
or
USER_TABLE {USER_ID, USERNAME, FNAME, LNAME}
I would think the only argument to store 2 fields separately (even when they are the same) is for some kind of future-proofing if we ever decide to let user create a username that is not an email?
Thoughts?
I would avoid premature optimization and use only one field. If you ever need to have 2 fields, it's easy to create and populate one.
If you believe that there is a reasonable possibility that you might want to allow users to start creating user names that aren't email addresses, then keeping separate email and user_id columns is a good idea. This is especially true if you are building a new system.
I have a maxim in system design: "If someone has thought of the idea, it will eventually happen."
By this I mean that it is often a mistake to think "our business rules will never change in area X". Business rules change - a lot.
You can always add a new field to your table later on to distinguish email from user_id. Adding a column is easy. What will be much harder will be changing all of the code you've written that uses the original user_id column for email purposes. This is why I say it's a good idea to build the distinction between user_id and email into your code from the outset.
You could include both attributes but add a constraint ("check" constraint) to guarantee that username and email are the same. Business logic that requires user name or email can then be written against the appropriate attribute and if and when you need to make them independent you can just drop the constraint.
Don't forget the uniqueness constraint for user name and/or email.
I have a user table which has about 50-ish pieces of data. Some of it is Religion, political party, Ethnicity, City, Favorite movies, etc. Each of these items are lookup values from either: Their own lookup table OR I have a common lookup table for the small items like gender, sex preference, etc. Even favorite movie is from a movie lookup table.
The question is i assume in the member table all these will be stored as IDs and not text? So first Q:
1) Should they or should they not have FKs to the lookup tables?
2) If we store IDs then to get the actual answer text like Id 6 in city table = new york, Id 10 in nationality table = American etc. for the actual output on the page ,how will it be done? Do we need to Select from each lookup table in the read mode to output the text value? This scares me because out of the 50 pieces of data about 40 of them are lookup based, so that means 40 different select on 40 tables on page read mode and again on edit mode for the user to edit the values.
How is this implemented in real world sites with detailed user profiles? (I have search and analytics on each value so I need to ID them)
Depends on the scope, but this sounds like a sync process - setup a weekly/daily/hourly process to resync extended user information into a master table with a foreign key to the "user"-related table (username, password, email, update stamps, etc...).
What you've described is the big tradeoff between normalized DB design and more of a flat-table design: the queries are a lot more complicated with the normalized design, which is sounds like you have.
I'd think that you'd be reading from the table a lot more than you'd be writing to it? (How often does a person's religion, gender, city, etc. change?) In this case, (only) if you're running into performance issues on the read end, you might maintain two representations of the table: one extensible, normalized one like you have, and a plain-text, flat version that's fast and piece of cake to query and read. When you update the record in the normalized one, you update the record in the flat one.
I have several entities which respresent different types of users who need to be able to log in to a particular system. Additionally, they have different types of information associated with them.
For example: a "general user", which has an e-mail address and "admin user", which has a workstation number (note that this a hypothetical case). Both entities also share common properties like first name, surname, address and telephone number. Finally, they naturally need to have a (unique) user name and a password to log in.
In the application, the user just has to fill in his user name and password, and the functionality of the application changes slightly according to the type of the user. You can imagine that the username needs to be unique for this work.
How should I model this effectively?
I can't just create two tables, because then I can't force a unique constaint on the user name.
I also can't put them all in just one table, because they have different types of specific information associated to them.
I think I might need 3 seperate tables, one for "users" (with user name and password), one for the "general users" and another one for the "admin users", but how would the relations between these work? Or is there another solution?
(By the way, the target DBMS is MySQL, so I don't think generalization is supported in the database system itself).
Your 3 tables approach seems Ok.
In users table have only ID, username, password,usertype.
In general users table have ID, UserID (from users table), other fields.
Same thing for admin users.
Usertype field will tell you from what table to search for additional info
if(usertype==admin)
select * from admins where userid=:id;
else
select * from general where userid=:id;
Two tables. USERS with user names, first, last, etc. ROLES with roles, and a link back to the user name (or user id or whatever). Put a unique constraint on the user name. Put workstation nbr, email, phone, whatever else you need, in the user table. Put 2 columns in the ROLES table -- USERID and ROLE.
You should decide how much specific information is being stored (or likely to be stored in the future) and make the decision based on that. If there are only a handful of fields for each user type then using a single table is alright.
USERS table (name, type, email, password, genfield1, genfield2, adminfield1, adminfield2)
Make sure to include the type (don't assume because some of the fields particular to that user are filled in that the user is of that type) field. Any queries will just need to include the "AND usertype = " clause.
If there are many fields or rules associated with each type then your idea of three tables is the best.
USERS table (ID, type, name, password)
GENUSERS (ID, genfield1, genfield2)
ADMINUSERS(ID, adminfield1, adminfield2)
The constraints between IDs on the table are all you need (and the main USERS table keeps the IDs unique). Works very well in most situations but reports that include both types of users with their specific fields have to be done in two parts (unioned SQL or subqueries or multiple left joins).
You can solve it with one 'general' users table containing the information thats available for all users and 1 table for every specific user type. In your example you will then need 3 tables.
Users: This table holds only information shared between all usertypes, ie. UserId, Name, Address, etc.
GeneralUsers: This table 'extends' the Users table by providing a foreing key UserId that references the Users table. In addition, information specific to general users are held here, fx. EmailAddress, etc.
AdminUsers: As with GeneralUsers, this table also 'extends' the Users table by providing a foreign key UserId referencing the Users table. In addition information specific to admin users are held here, fx. WorkstationId, etc.
With this approach you can add additional 'specializations' if the need arises by simply adding new tables that 'extends' the Users table using a foreign key reference. You can also create several levels of specialization. If for example admin users are general users as well as admin users then AdminUsers could 'extend' GeneralUsers instead of Users simply by using a foreing key to GeneralUsers instead of Users.
When you need to retreive data from this model you need to which type of user to query. If for example you need to query a GeneralUser you will need something similar to:
SELECT * FROM GeneralUsers
LEFT JOIN Users ON GeneralUsers.UserId = Users.UserId
Or if querying an admin user
SELECT * FROM AdminUsers
LEFT JOIN Users ON AdminUsers.UserId = Users.UserId
If you have additional levels of specialization, for example by having admin users also being general users you just join your way back.
SELECT * FROM AdminUsers
LEFT JOIN GeneralUsers ON AdminUsers.UserId = GeneralUsers.UserId
LEFT JOIN Users ON GeneralUsers.UsersId = Users.UserId
I most definitely would not do a model where you have separate tables as in GeneralUser, AdminUser and ReadOnlyUser.
In database design, a good rule of thumb is "Down beats across". Instead of multiple tables (one for each type), I would create a SystemUsers table, and a Roles table and define a join table to put SystemUsers in Roles. Also, I would define individual roles.
This way, a user can be added to and removed from multiple roles.
A role can have multiple permissions, which can be modified at any time.
Joins to other places do not need a GeneralUserId, AdminUserId and ReadOnlyUserId column - just a SystemUserId column.
This is very similar to the ASP.Net role based security model.
alt text http://img52.imageshack.us/img52/2861/rolebasedsecurity.jpg