User inventory database design? - mysql

I'm making a game in PHP with MySQL and I was wondering what is the best way for me to store the items the users have purchased so it is linked with their account.
I plan to have a database with the items information in and the only ways I could think of doing it was:
Having a table for the users items in a serialised array of sort
Having masses of columns with a set amount of inventory space
Table with user_id and item_id and add a row every time they purchase an item, selecting the user_id relevant to the user to display their items
Which is best?

I think that you know at the beginning which items a user can buy, so in my opinion you should have three tables
USERS table, in which you store user data (PRIMARY KEY is user_id)
ITEMS table, in which you store items with their cost and data (PRIMARY KEY is item_id)
USERITEMS table, in which you store every item bought by users. It should have two columns: user_id and item_id and you add a row every time a user buy an item.
This design lets you easily manage bought items and show every user its inventory.
More: you avoid wasting space in database duplicating unuseful informations

As per your question, the No.3 is suitable.I prefer #Marco suggestion.

Related

Database design for dynamic columns

I am trying to design a database in which users can set the cost of different products based on how much they sell them and their availability in their store. The users can only set their prices for the products and the availability but the products are created by the system admin for the users. I have tried by designing the database to have three tables one for the products and another for the users then the third is a modal for linking the users to the existing products using user_id and the product_id. What I am not able to do is to know how and where to set the price attribute of the products
As stated in the comment, using pivot tables then attaching all the additional data is the best option with mysql database in your case, you could have the users table with user_id as the primary key, products table with product_id as the primary key then create a modal table product_user with the fields of product_id and user_id as index, cost as decimal and availability or quantity.
During insertion or update, you will use attach as follows
$userProduct = Product::where(['id'=>$data['product_id']])->first();
$userProduct->userProducts()->attach(User::where('id', $data['user_id'])->first(), ['amount' =>$data['cost'],'availability' =>$data['quantity']]);
In your Product model, you will need to create the userProducts() function that will hande the one to many relationship

Database design issue in project?

I am designing a database for my app. In which I want to do mapping between multiple tables. Now situation is like There is one user table. User can have generate multiple orders. So I was thinking if I can put json obejct of order_id in a column in order table. Or I can create a user_id column in order table & repeat user_id for same user. So which is a better way of doing it?
PS: What is the standard way of doing it?
You should just have user_id in your order table, then make queries like
select * from orders where user_id = *some_user_id*
A user can place multiple orders which in turn can have multiple line items. Each line item can have n quantity of a specific product. So when product comes in picture, then it becomes many to many relationship between user and product because a user can place order for many products and a product can be ordered by many users. So my suggestion is -
Create a User table with UserID
Create a PurchaseOrder table with OrderID, UserID and LineItemID
Create a LineItem table with OrderID, ProductID and LineItemID
Create a SKU table with ProductID
A user can place multiple orders.
Based on this you should maintain three different tables as given below:
User (user_id,...)
Order (order_id,...)
UserOrder (user_id,order_id,...)
Only the primary keys in the above tables are focused
Storing comma separated list or json object will worsen the design. And this is strongly discouraged.
EDIT:
As #NevilleK suggested, the above design is typically used for many-to-many relationships. For one-to-many relationship you can create a foreign key constraint in orders table where user_id should refer to the user_id in the User table.
But still you can adopt the above design for one-to-many relationship since many-to-many qualifies for one-to-many too.
The best way is to have different table for your
User table - which hosts the user information
Transaction table - which will have order_id against each user_id.
Transaction table will carry all the transaction details with user_id. If you create a JSON object, how will you map the USER to the transaction. So at the time of retrieving the json information you will have to map it to the user table anyway. I suggest you the use the above said method, which will help you maintain and scale your application much easily.

Establishing relationships in a database between multiple tables

I have a web application which allows users to join multiple groups.
I have a 'users' table which stores details about the users (id, email, password, etc.) and a 'groups' table which stores details about the available groups (id, name, owner of group).
I have been researching the best way to store group memberships (i.e. which users are in which group, bearing in mind they can be members of multiple) - however I am still not sure what the most efficient solution would be.
Would you recommend I:-
Create a second table called 'group_memberships' and store the user's ID along with the corresponding group ID?
Store an array alongside the group particulars in the 'groups' table with the user IDs of its members?
Approach this task a different way?
The DBMS I am using is phpMyAdmin.
I would advise you to go with option 1; where you have a Mapping Table for linking Users & Groups.
The Users Table will have PK on User_ID.
The Groups table will have PK on Group_ID.
The Mapping table will have User_ID(FK) and Group_ID(FK).
Now you should have PK on these two columns together.
This will ensure you don't have duplicate entries.
What you're describing is called a many-to-many relationship in database terms. A user can belong to multiple groups, and groups have more than one user (or else they wouldn't be "groups"!).
Your first idea, the group_memberships table, is the accepted best way to model this relationship. Although you'll want to name it users_groups or something similar to reflect the fact it relates or associates those two tables. At its most basic, this association table needs three columns:
ID (primary key)
user_id (foreign key)
group_id (foreign key)
By JOINing to this table ON either user_id or group_id, you can find the related records from either side of the relationship. And you can do it right from a SQL query, without any additional code like you'd need if you stored an array.
I would definitely go with option 1 - creating the junction table 'group_memberships' - I have used this approach many times without problems. Don't forget to add an Index on the new table 'group_memberships' for columns: 'groupID' and 'userID'.
Option 2 is not scalable for a large amount of data, especially if groups have a lot of users.
UPDATE:
For info on Indexes, here is a good (and short) blog: https://blog.viaduct.io/mysql-indexes-primer/.
The first option is a right choice. Actually it is a materialized view for both user table and group table.
Just think materialized view as a extra table or a redundant data structure that denormalizes the user properties and group properties together for quick search.
Since if we do not have the view, when we query a group id to list all its users, we have to filter millions of users to check if he/she is in the certain group. It is a performance nightmare!
Mysql has tools to build this view very efficiently. You may build secondary index on this view columns for quick search, say, group id, group name, user id, user name or something else you hope to search with.
good luck :-)

2 seperate relational tables or just one relational table

I have a users table and at the moment a table for storing the users information. The users have a role of buyer or as seller. where the seller has some additional fields that the buyer doesn't have.
Now im wondering what will be a good approach to use. create a table for the users information where i refer to the users id, or two separated tables. One table for the buyers information referring to the user id and one for the sellers information with the exta fields referring to the user id. Where you fill the table according to the users role.
There will be millions of users inside this table so thats something to keep in mind here.
Any help will be appreciated.
Generally you put all the information both types of users share (and that fits on one records of course) in the User table. Then if you need more information by type create a table for that type. If you only need more information right now for sellers, then create a sellers table. If buyers also have specialized fields, then create a buyers table. If however, you do not at this time have any specialized fields to add for the buyers table, then you may not need one at this time. It can be added later if your data model changes.
If this table (these tables) is going to be in a one-to-one relationship with the User table, then make sure to create the Userid as both the FK (to users)and the PK of the child table to maintain data integrity.
You should use two tables, one for users and the other for associates
users
+id
user_name
...
associates
+id
user_id
assoc_type //buyer or seller
...

Database Modelling of users table having 2 tyes of users

I am modeling a database that will hold data relating sales from a shop. I have two different kind of users which have distinct properties.
In my normalization process I created a User1 Table and a User2 Table.
The problem I have is tracking sales. For example if I want to track sales say for a particular kind of user for a product and know the users buying trends for that product, I would have to create two tables, Bread1 and Bread2 for the two types of users.
I came up with a solution but I don't know the performance implications on the long run or if its the best solution at all. The solution is having a unified table User which have the ID's of both users.
If there is any other better solution, I would appreciate it.
Thanks.
Better to have just one table for Users and one for Products and so on. You can easily categorize your users or products by making an another table for grouping them.
UserTypes(UserTypeId PK, ...)
Users(UserId PK, UserTypeId FK, ...)
Also for properties you mentioned for users or even for products, You can have a list of properties in a table and assign them by a third table to users.
Properties(PropertyId PK, Name)
UsersProperties(UserPropertyId PK, UserId FK, PropertyId FK, Value)