mysql table relationship with primary and foreign keys - mysql

I have created 3 tables: accounts, products, claims. These are the relationships:
Accounts: PK - username
Products: PK - serial number, FK - username
Claims: FK - username, FK - serial number
My issue is that a user can add a claim even for products the user has not purchased, as long as the user knows that serial number, while I should allow the user to add a claim only for products the user purchased. For inserting claims I am using this query:
INSERT INTO claims (username, serial_no, date, issue) VALUES (%s, %s, %s, %s)
Do I need to change the table relationship with keys to fix the above, or use a more specific query? Better, what is the logic behind how this is supposed to work?

You should filter the products by username of the current user to avoid claiming products that are not related to the user. If you filter the product to be claimed then you won't need to change your table structure, it's only up to you on how you'll implement the filter in the programming language you are using.
First select all the products related to the user.
SELECT * FROM products WHERE username=#currentusername;
Then in your program, just allow the user to claim only from the fetched products.

Related

SQL Best practices: Using a column to store two different kinds of data?

Suppose I have a login table containing id, username, password, type, and linked_id
The type column specifies whether that login belongs to an employee or a client.
If they are an employee, linked_id is their ID in the employee's table.
If they are a client, linked_id is their ID in the client's table.
Intuitively, this seems like a bad idea, but other than dealing with foreign key constraints, I can't think or a reason not to.
This also brings up another question: Is it ALWAYS important to have FK constraints in situations like this?
Thoughts?
I think you are thinking about your table design incorrectly. I would have the login information in one table and then point to the login record from the appropriate table. In other words, point to your login record from the employee and clients tables rather than pointing to a client or employee record from the login record. That allows you to have your foreign key constraints and removes the need for an extra field of "type"
As an example:
Login: Id(PK), Username, Password
Employees: Id(PK), Name, EmployeeNumber, Login_Id(FK_LoginId)
Clients: Id(PK), Name, Address, Login_Id(FK_LoginId)
Then, you inherently know what "type" each login is by what table the data is stored in.
The easiest solution would be to simply add an additional column in your database and have EmployeeId and ClientId to make the table structure easier to understand.
You could also argue that you're missing an Entity in your database design. As an example, what if an Employee was also a client? How would the current system deal in that circumstance?
You could have an intermediate table to manage this and determine the status of that Person.
I.e. have the table Login.
Fields: ID, username, password, type, PersonId
And then another table Person with the EmployeeId and ClientId, although I do think this would cause a lot of NULL values it would support the above circumstance I have described.
As an additional note, I would not want to look at the existing Login table, identify the linked_id field and then have to decide which table this column relates to, Employee or Client?
You could also split this out like #randyh22 has suggested and remove the linked_id field altogether and have the Login identifiers in the child tables (Employees and Clients).
Restructure:
Login table: LoginId, Username, Password (Ensure it is hashed)
Employee table: EmployeeId, Forename, Surname, LoginId
Client table: ClientId, Forename, Surname, LoginId

database schema for two similar users

I have a doubt about this DB schema I'm making.
I have two similar users, but one has extra information than the other:
Type 1 : Administrator
- Name
- Lastname
- Email
- Password
Type 2: Student
- Name
- Lastname
- Email
- Password
- Status
- Sex
- Among other type of personal information fields
So, I'm hesitating about either make these two separate tables, and when they're going to log in, query them both (Because I have only one logging screen), or unify them as only one table User, and make another called like "extra" with a foreign key from User pointed to the latter.
What would be the most efficent way to accomplish this? Thanks for your time
I would make two tables and do the join after log in. Cache the extra facts about the user after they're logged in.
You should have a User table with these columns:
Id, Name, Lastname, Email, Password, IsAdmin
With a Student table:
UserId, Status, Sex, ...
A Student must also be a User - this will reduce duplication of data.
If you need more permissions than IsAdmin then remove that column and make UserPermissions and Permission tables.
If you're really that concerned about a join, then just make everything nullable and in one User table. I doubt it will matter in your use case (this is a much bigger topic).
An administrator is a role played by a person.
A student is a role played by a person.
A person could play one role at a time, or maybe multiple down the road. This is a business rule and should not factor into your database schema.
Use single table inheritance to allow for different types of roles in the same table.
create table people (
person_id int primary key,
given_name varchar(...),
surname varchar(...),
password varchar(...)--consider a `users` table instead
);
create table roles (
role_id int primary key,
person_id int not null references people(person_id), --use the long-hand foreign key syntax for mysql
type varchar(...), --admin or student
status varchar(...), --consider PostgreSQL over mysql, as it supports check constraints
sex varchar(...)
);

Should i stock "quotation_request" as a table on my DB?

I'm working on a very simple DB.
Imagine I've table customer and table seller.
The customer is able to request a quotation for some products
There will be a simple form that allow to customers to select products and submit the quotation.
Now, should I create table : "Quotation" and store all quotations (with id_quotation..etc)?
Thank you all
Without knowing all of the business rules that govern the requirements of this database, perhaps the following design will help to answer your question and explain a few concepts in the process.
In database terms, an entity is a person, place, or thing about which we want to collect and store data. From your description we can already see two entities: seller and customer. This is important since the entities we identify conceptually become database tables in their own right.
The seller table should contain data applicable only to sellers. Thus, the qualities (attributes) about sellers that we want to store become columns in our seller table. Each row (record) in the seller table represents an individual seller. Each individual seller is uniquely identified in the seller table with a unique value stored in it's primary key column, which we can name seller_id.
A simplified version of such a table could look like this:
In a similar manner, the customer table should contain data only applicable to customers. The qualities (attributes) about customers that we wish to store become the columns in the customer table. Each row (record) in the customer table represents an individual customer. Each individual customer is uniquely identified in that table with a unique value in it's primary key column, which we can declare as customer_id.
A simplified version of this table:
I'm guessing the business rules state that any customer is able to request any number of products, from any seller, any number of times...since surely any seller would want as many sales and customers as possible!
How can we express and record the interactions (relationship) between seller and customer?
This is done with a new kind of entity: a composite entity. It becomes a new table, having it's own primary key, and contains seller_id and customer_id as foreign keys. The foreign keys in this table connect (relate) the seller table to the customer table.
We can name this new table quotation (if that is your preferred name). Each row of this table is intended to capture and record each and every individual transaction between a customer and a seller. The columns (attributes) of this table are the data that apply to a transaction between a customer and seller, such as amount or date of sale.
A very simplified version of this composite entity:
Note that the foreign key values that exist in this table must already exist in their respective tables as a primary key value. That is, a foreign key value cannot be entered into this table unless it exists already as a primary key value in it's own table. This is important, and it is called referential integrity - it ensures that there is no record of a customer purchasing from a non-existent seller, etc.
In the example above we can see that Builder B requested a quotation from Acme Construction in the amount of $3500.00. They then requested another quotation at another time for the amount of $1800.00. What else does it reveal? All existing customers have ordered something. Acme Lumber has not made a sale at all (yet), etc.
A design such as this enables the database to store any number of transactions between sellers and customers. Likewise, it supports the addition of any number of new customers and sellers, even if they have not sold or purchased anything yet. Queries can be run that reveal which sellers have sold the most or least, and so on.
Good luck with your studies!

Storing Payment Details and Subscription Details

I am trying to create a subscription based payment module for a project.
There are three plans
Will cost 49$ but right now it will be free till we acquire users.
499$ which will have 15 days trial
799$ which will also have 15 days trial.
We are using Stripe for Payment Integration.
I have a users table with as follows
users(name, email, password, ....)
Now i want to store the following
Define and Maintain Plans
Which plan a user is subscribed to
When a user is subscribed to a plan - details regarding the payments - upgrade - downgrade etc.
Can some one share how i can do it via Mysql tables and if i am missing any key information that i need to store ?
Here it is a little sketch of what i would do in this scenario :
Tables
Users
id, nameemail, password, ...
MaintainPlans
id, user_id, name, ...
Payments
id, name, user_id, ...
Operations
id, type, user_id, name, ...
Notes
The user_id field reference of course the id primary key of the user table
Each tables can,of course, contains more columns containing more information or relations(i have inserted only the essentials.
The Operations type field should contain an enumeration with the possible value (upgrade, downgrade), could be defined into and enumerator or into another table referenced (even better) ...

How to design this simple database?

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.