Technique to validate foreign keys, MVC web application, MySQL - mysql

Having two database tables:
orders (id, client_id, ...) - stores orders of customers
addresses (id, client_id, ...) - stores delivery addresses of customers
Relationship between that tables is many-to-many so I have table
addresses_orders (id, order_id, address_id) which maps where order goes
But I'd like to enforce one thing - in table
addresses_orders can only be paired together orders and addresses of the same customer.
What is the best way to do this?
I have web application based on MVC, which stores data in MySQL database.
Every customer gets only his orders and addresses to choose from, but form can be tampered and malicious user can change address_id to random guess, so it will produce described insonsitency.
For safety I have to validate against this scenario - probably in Model or directly in database.
I prefer second solution, but how to do this? Maybe some triggers?

If there are no overlap in addresses ( only one client per address ), Then your DB structure makes no sense.
Clients Addresses Orders
--- ------- -------
client_id PK address_id PK order_id PK
name client_id FK address_id FK
phone_number full_address data
Then to get all details from an order
SELECT
Clients.name
Addresses.full_address
Orders.data
FROM Orders
LEFT JOIN Addresses USING(address_id)
LEFT JOIN Clients USING(client_id)
WHERE
client_id = 42
This would give you all orders from client with ID 42.
each order has one address
each address has one client
each client has multiple addresses
each address has multiple orders

Is the address_id hidden or visible form field and you are worried that users are capable or willing to mess with it?
I'm guessing your customers are logged in. You could take advantage of session information and user_id (or something). Retrieve the customers address_id in the process file and use that address_id, not the id sent by form (you could of course check if they match). If something goes wrong the problem is probably somewhere in session/application security, but not in the spoofed form.

We tend to use the following approach:
a) Store the customerid in the session
b) When selecting the orders or addresses use one of the following showing the user names while saving the ids:
- A pregenerated list using a select control where only one can be selected
- A pre-generated list from which specific items can be selected using checkboxes

Related

How to enforce integrity for orders?

If a user can have multiple addresses and phone numbers, is it possible to design the database in such a way that I can enforce integrity between data?
For example:
users(id,name)
addresses(id, description, user_id -FK to users)
phones(id, description, user_id -FK to users)
orders(id,address_id -FK addresses,phone_id - FK to phones)
How can I be sure that in the orders table I won't accidentally insert a record with user1 address and user2 phone number?
I'm sorry if this was asked before but I don't know how to search for this situation.
Where is the Orders table? It will have columns user_id, address_id, and phone_id.
For data entry, if a known user calls in an order, then the UI brings up the existing addresses and phones for that user. The order-taker can quickly click on them. Or the user can say to use a different address. Then the UI assists in adding a new address for that user.

Database design accounts vs customer accounts

Hello Stack Overflowers,
I'm redesigning a system for an ordering group.
We have a hundred or so companies (ordering accounts) that order from us.
And maybe 40 of those companies also have online stores (admin accounts) with us.
An online store has a customer list of users that belong to their store, and the admin account lets them create and manage customers and customer orders.
So the customer shops, and when finished the order goes to the company.
The company verifies the order (combines orders to save shipping if they want) and then send it(/part of it) to us or fill it(/part of it) from their inventory.
We pack their order at our warehouse and ship it to the address on the order.
And we invoice the company.
The company then settles payment with their customer. (we never bill a customer directly)
Hopefully that wasn't too convoluted...
So again, we never bill a 'customer' directly. But in our current system, we store all accounts (ordering, admin, AND customers) in the same way.
While considering the redesign, I've questioned if this is the most logical approach. And I was thinking of storing our billable accounts (ordering and admin) in an accounts table and customers in a separate customers table.
The way I was thinking of setting this up was, our accounts have an accountID XXXXX, while users have a similar userID YYYYY, but are identified by a composite key of the two (XXXXX-YYYYY)
So company A's first customer is AAAAA-000001 and company B's BBBBB-00001. This seems fine when I think about things like customer orders being billed to their parent company, and displaying all of a companies customers, etc.
But is it a bad idea to have a customer table where customers non-unique customerIDs, even if that isn't the Primary Key?
I know I could make it work, but is it suboptimal when doing something like a customer_address table that relates a customerID and an addressID? Wouldn't it then need to use an accountID + customerID right?
Originally I was thinking they would all be accounts, and the account number would just be structured that way AAAAA-00000 being the admin account, AAAAA-00001 being customer 1, and so one.
But that brings me back to, should our accounts table treat our clients/billable accounts and their customers the same?
Sorry if this question is kind of all over the place. I think that demonstrates how unsure I am of how it should all be structured...
Any input would be greatly appreciated.

Database design: Associating tables of variable types

I am looking for a solution to (something I imagine to be) a common and trivial problem, but I couldn't find the correct words to find solutions on Google.
Starting situation
I have a table orders that is associated to a product and a customer:
orders (id, product_id, customer_id)
The problem
Each order must have a payment associated. These payments come from different payment processors (e.g. Paypal, stripe, Google Wallet, Amazon Payments) and thus have different types of data and data fields associated to them.
I'm looking to find a clean and normalized database design for this.
My own attempt/idea
I could create separate tables for the different types of payments and associate the order from there:
paypal_payment (id, order_id, currency, amount, [custom paypal fields])
stripe_payment (id, order_id, currency, amount, [custom stripe info])
direct_debit_payment (id, order_id, currency, amount, [custom direct debit info])
The problem: With this approach I would need to SELECT from each table for every payment type to find an associated payment to an order, so that doesn't seem very efficient to me.
What is a clean solution to this problem? I'm using MySQL if that is relevant at all.
Thanks for your help! :)
Your Payment table should have all fields that are common to all payments (amount, type of payment, etc) as well as a unique ID.
Variable fields would then be stored in a second table with three columns:
Payment UID (foreign key to the Payment table)
Type (what kind of data this current row is storing, i.e. the name of a custom field for the payment type)
Value
This allows you to associate any arbitrary number of custom fields with each payment record.
Obviously, each payment could have any number of entries in this secondary table (or none if none are needed).
This works quite well as most of the time you wont need the payment type specific info and can do queries that ignore this table. But the data will still be there when you need it.
If you're never going to be using those fields' contents in a where or join clause (which it usually is):
Add a payment method field (an enum or varchar)
Serialize the paypal, stripe, or whatever the client used as json
Store the thing using the most appropriate database type -- text in MySQL, json in Postgres.
A normalized way you could do this is by having a base payment table and extension tables for the other payment types.
All common payment information would go in your payment_base table.
payment_base(payment_id, order_id, currency, amount)
paypal_payment (paypal_payment_id, payment_id, [custom paypal fields])
stripe_payment (stripe_payment_id, payment_id, [custom stripe info])
direct_debit_payment (direct_debit_payment_id, payment_id, [custom direct debit info])

How to store customer data in mysql (2 tables vs 1 table)

I was thinking that I would have two tables for mysql. One for storing login information and the other for shipping address. Is that the conventional way or is everything store in one table?
For two tables... is there a way where it automatically copies a column from table A to table B, so that I can reference the same id to grab their shipping address...
If its a single address and if it is going to be updated everytime , then you can have it in a single table something like
**Customer**
customer_id [pkey]
customer_name
login_id
password
shipping_address
whereas if you want to store all the shipping addresses for a single customer(across multiple visits) then it would be a good design to have another table customer_shipping_address
**Customer**
customer_id [pkey]
customer_name
login_id
password
**Customer_Shipping_Address**
customer_id [fkey to customer]
shipping_address
This is my answer to your question regarding using 1 table or 2 tables. This decision depends on may factors. But i would suggest that you should use 2 separate tables. Because the log-in information is something that you will be retrieving very often compare to shipping information. Now if you have all the info in one table then table size will be huge and you will have to query this huge table everytime you need login information of user.
I think using two tables is better way to go. then just join them when you want to do the shipping.
The SQL for that would be like this.
SELECT
table1.id, table2.id, table2.somethingelse, table1.somethingels
FROM
table1 INNER JOIN table2
ON table1.foreignkey = table2.primarykey
WHERE
(some conditions is true)
The code above would need to be run on the shiping page itself.

How to structure a mysql database where each user has multiple contacts

I am creating a site where each registered user can store a list of contacts. It occurred to me that rather than storing the contacts in a table with user_id, contact_name, contact_email, it would be better to normalize it to prevent the same names/emails being stored multiple times. As a result, I now have 4 tables: users, names, emails and contacts where contacts contains user_id, name_id and email_id. Am I heading in the right direction, or am I complicating things needlessly?
Thanks for all the helpful responses to what I can see now is a pretty nebulous question. It may be a good idea to explain my reasoning.
In an example scenario, where there are 100 users, most of whom have joined though the recommendation of another user, there will be a large number of common email addresses shared by each users contact lists. However, johnsmith#email.com, may be known as John, J Smith, Johnny boy etc. by different users. If I understand the principles of normalization correctly (unlikely) the separation of user, contact name, and email address in to separate tables, should reduce duplicate entries significantly and make the database more efficient. In the example below, the Contacts table could contain the same email addresses multiple times.
So, to cut a long story short, is it better to have more entries than necessary in one table or several smaller tables without duplicate entries?
You're probably needlessly complicating things: I'd recommend one table for users, one for contacts and a join table to allow a many to many relationship between the two. If contacts are not shared between users it'd be acceptable to have the user id as a foreign key in the contacts table.
Hope this helps
You can do like this
1] User_info Table
User_Id | name
2] Contacts Table
Contact_Id | Contact_Name | Contact_Email
3] User_Contact Table
User_Id | Contact_Id
Can contacts have same email but distinct names, or vice-versa ? If not, i suggest two tables (users and contacts) linked by an associative table :
USERS
- userId
- userName
CONTACTS_USERS
- userId
- contactId
CONTACTS
- contactId
- contactName
- contactEmail
With foreign key constraints on userId and contactId you can achieve a robust linkage between the two tables, where each contact may be used by distinct users and where each user may have distinct contacts.