Database implementation in order to save user activity information - mysql

I am using Ruby on Rails 3 and MySQL.
In my project I would like to create an activity-stream "module" in order to save each user action information in a dedicated user table. That is, to create a database table for each user.
Is it a good approach to create a database table for each (new registered) user in my application?

No, it is not a good approach. Why would you create a separate tables with all the same fields? Just add user_id to your table and store all info for every user in there.

I do something similar, and it's not necessary to create a whole table for each user. For example, I have a table called "user_actions", and in it there is a column, "user_id".
The relationships are:
User has_many :user_actions
UserAction belongs_to :user
And you're done. Let the foreign-key relationship that comes naturally take care tying the specific action to a specific user.
Once you do that, you only need to decide:
Which actions cause an entry to be added?
How long should you retain the data (1 week, 6 months)?
For example, on my site, I keep a log of the last 5 things a user viewed, and present that list to them on a section of the page called "Recently viewed items" for convenience.
I also have a separate table called "admin_actions" that I use for security logging that keeps track of everything done under an admin account, and what admin account made what sort of change.

I guess the answer is that it depends on how many users there are. If it's not a small, defined number then I'd suggest that it's not a good idea to create one table per user.
I'd suggest a single table with one column being a unique identifier for the user. Make sure that whenever you're querying the table that you're using an index that has this column as the first column in the key. E.g. PRIMARY KEY(user_id, activity_time)
This should allow for fast and efficient reading of the rows.

Related

What is the best way to organize daily user data in a database?

I am setting up a database using MySQL with the goal of storing data for a potentially large number of unique users. Each user will have some basic data associated with them - a unique username, when they joined the service, how many times they have used the service, in addition to a set of their personal preferences. I am planning on keeping one table called 'Users' dedicated to these fields.
However, there is a bunch of data with a specific schema that will be collected about that user during each session that they use the service. This data includes which user performed this session, the date of the session, what the user did, etc.
My thought process is the following: if I use a single table for users that includes data on each of their sessions, this seems inefficient because there would have to be either a column for each unique session, or a column containing more or less an array or list of sessions. If I wanted to keep this data for an indeterminate number of sessions, then the one-per-column idea would break down, because I believe there is a column limit. Updating an array within a single column also seems to be frowned upon, I think for reasons having to do with preserving the integrity of the data and maintaining the best possible organization.
So it seems like I want two tables, one for users, and another for sessions. Every time anybody completes a session, data about that session will be created as a new row in the 'Sessions' table, and each row would also have a foreign key linking that session to the particular user who completed it.
Is this a correct line of thought? If not, how should I think about this?
Thanks
I would say you're pretty close. You should separate users and sessions, and you're looking at modeling a relationship. Each session only has one user, so it's a one-to-many relationship.
1 User (1 Row in the "Users" table) can have many Sessions (1 Row in the "Sessions" table)
The Foreign Key is the User ID in the Sessions table. This links each unique session (Which will have it's own Session ID I'm assuming) back to a unique User in the Users table.
If you're looking at a massive volume of users, which means a ton of sessions, you may want to consider options on how to help the sessions table not grow to be extremely huge and slow to query. If you're collecting this data on a daily basis, consider that you could "Partition" the table on dates:
Partitioning on DateTime in MySQL
edit: typos

Need suggestion on DB architecture

I am working on a Project where I have below use case.
User can have many taglines for them , we have lot of predefined data in the DB which we using to show autosuggestion when they started typing tag lines, I am using Rails.
User has_and_belongs_to_many taglines
Tagline has_and_belongs_to_many users
I have separate joint table and everything was fine , but now I need to store custom taglines of user to DB , which will be belongs to only particular user.
Should I clone the taglines table and add user ID to it Or what is the best architecture to handle these kind of scenario , if we have more than one model which have same use case as like taglines.
your existing user and tagline table has many-to-many relationship, keep it that way. Whereas the user table and the new customTagline has a one-to-many relationship so why don't you create a new table to represent it? Since you mentioned the customTagline belongs to only a particular user.
#BroiSatse Comment make sense, I followed same.
If you create a second table, you will need to remember to update two
tables/models every time you will want to change your model. You won;t
be able to pull all the user tags in one go neither. many-to-many is
able to hold one-to-many association. Just add a validation to check
that given tag can belong to only one user if it is custom.

MySQL Two User Database Consolidation

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.

Many-to-One and One-to-One Relationships on Same Two Tables?

I'm designing a database where two fields have a many-to-one relationship, but I also need a one-to-one relationship between them, and I would like some advice on whether there is a better way to do it than what I've got right now.
My tables are accounts and users. An account can have multiple users, but each account can only and must have one owner. A user can be related to only one account.
I have an account field in the users table, which stores the ID of the account the user is related to. In the accounts table, I have an owner field, which stores the ID of the user who owns the account (i.e. the head admin).
I'm using InnoDB so I can make use of foreign keys. The problem is that I can't create an account or a user without the other being created first (due to the restraints of the foreign keys), so I made owner nullable. Now I can create an account with a null owner, then create the user, and finally set the owner on the account to the user.
Is this acceptable, and is there a better way?
Here are some possible other ways I've come up with, and my thoughts on each:
Have a boolean owner field in the users table. Since every account can only have one owner, this way seems less than ideal because I'd have to ensure only one user per account has the attribute set to true.
Have a third table called owners. This seems like more overhead and more work for no good reason since it's effectively the same as having an owner field in the users table.
How I have it now makes the most sense to me, but it's a little awkward having to set a null owner until I create the user, and then coming back to set it after the fact.
I'd appreciate any input you can give me. Thanks!
This question is similar, but there's no mention of foreign keys: Designing Tables: One to many and one to one at same time?
In general is a bad idea if your schema cannot be sorted topologically, i.e. if you cannot establish an ordering where a table only refers to tables preceding it in the ordering. This sort of "layered" dependency is also a very nice property to have for example for software modules (you have a problem if two modules depends on each other).
In your case you have user that refers to account and account that refers to user so clearly there's no way to find a topological ordering.
One standard solution in this case is to introduce a separate table e.g. "role" where you have three columns: user, account and role. The column role can be either "owner" or "guest".
The fact that you know that (given the current requests) an account must have one and only one owner, or that a user must be listed in one and only one account are not IMO rules that are really pertinent to the domain of "users" and "accounts".
You can implement those rules easily, but structuring your data so that you have no other possibility is IMO a mistake. You should aim to model the domain, not the specific rules... because people will change their mind about what those rules are.
Can you conceive a user with two accounts? Can you conceive an account with multiple owners/admins? I can... and this means that most probably quite soon this will be a request. Structuring the data so that you cannot represent this is looking for troubles.
Also when you have cyclical dependencies in the model your queries will be harder to write.
A very common case is for example to try to represent a hierarchical part list database using just one table with a "parent" field that points to the table itself... much better is having two tables instead, part and component, where component has two references to part and and a quantity.
Your solution is fine.
If you're uncomfortable with the owner column being nullable, you could rely on some magic user record (perhaps with an id of zero) which would be the "system user". So newly created accounts would be owned by user-zero, until their ownership was suitably redefined. That seems smellier than allowing accounts to have a null owner, to me, anyway.
For the current requirement to have only one account per user
alter table UserAccount add constraint un_user_account unique(UserID);
and when the requirement changes to many-to-many, drop the constraint
alter table UserAccount drop constraint un_user_account;
For the one owner only, simply enforce that on the application level.

Can i create each table for each user in my social networking site?

I'm creating a social networking site with features similar to Facebook.
I want to start with schema design for my database.
What i thought was to create each table for each user who registers to our site.. am i doing right?
If a million users register to my site, a million tables will be created. how to go on about optimizing this? Please do suggest me techniques to overcome this and some references or books to learn about such concepts will be vry useful..
Thanks in Advance.
This is not the way you want to do it.
What you want to do is have a table (perhaps called 'users') that contains one row for each user that registers. Creating a new table for each user is completely pointless and would cause terrible performance.
Maybe something like this:
TABLE users
- username AS VARCHAR(255)
- password AS VARCHAR(255) (use a hashed password, of course)
- ...
Then when a user registers, simply insert the information they provide into the users table as a new row.
That would be massive overkill. You should probably read up on database design (start with normalisation, but don't overdo it). Then write down what you want to save for each user, and think about how to save it without saving data double.
But I'm pretty sure a table-per-user is not an option for this.
You must be confusing the meaning of the words database, table, field (or column), record (or row).
A database contains all your data for a specific project. There is always one database per project (or almost always)
A table contains all data of a specific entity and by saying entity, I mean an object type that is imaginable as real or seperatelly existing by itself. A person is an entity, a book is an entity, a phone is an entity, a movie is an entity, etc. Each of these would be seperate tables in a database.
A field (or column) is a data type that represents a specific characteristic (feature) of a table's entity. For example a table of users can have the fields: NAME, SURNAME, AGE, etc. These are all features that a user has.
A record (or row) is an actual item of one table. It is a single 'piece' of the table's entity. For example in a table of users, one record is one single user, namely {NAME:"John", SURNAME:"Smith", AGE:"32"}.
In your example, I can tell you for sure that you only need one database. You want to store information for many users, so you need one table called USER. You will need to store features to your users, like: name, surname, age, address, etc., then you will need to create the respective fields in this table: NAME, SURNAME, AGE, ADDRESS, etc. Then you will need to insert your data in the database as records. It will be one record per user you want to store.