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.
Related
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.
I am developing a hospital system where patients can allow user access to their information as per their choice. There are different group of users for e.g doctors, nurses, registration clerks, insurers and managers. A user can access either patient personal details, patient medical details, patient prescription details or all. Each user is identified by a unique "user_id" and each group by a unique "group_id".
A patient can block:
a single user (e.g a nurse)
a group (e.g all nurses)
a group with some exceptions (e.g block all nurses except nurse1 and nurse3)
specific users but allow their respective groups (e.g allow all nurses except nurse1 and nurse3)
Once access is granted to a user or group they will be assigned permissions like read, write and delete.
I'm having a lot of trouble figuring out how to design my table(s) along with their fields so that I can store these access rights information.
At first I would deny to all users and groups as standard. And then the following table structures:
tblPatients
Name, patient_id (I would prefer uuid's), etc.
tblUsers
Name, user_id (I would prefer uuid's), etc.
tblGroups
Name, group_id (I would prefer uuid's), etc.
tblUsersGroups
users_groups_id, user_id, group_id
The user_id references to tblUsers and the group_id to tblGroups.
The idea behind the structure of tblUsers, tblGroups and tblUsersGroups is, that a user can be member of several groups.
Now to the important part, the whitelist:
tblWhitelist
id, patient_id, write_group_id, write_user_id, read_group_id, read_user_id, delete_group_id, delete_user_id
In this table you put the access id's, I would do it each per row and you can have as many rules in there as you like.
For your query you need a username or user_id, get the membership(s) of this user in tblUserGroups and then look at tblWhitelist whether the user or his group is allowed to do the action. The user rights should be have a higher priority.
I think, this way could work,
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
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.
I am building a database for a web application that includes users following each other. What would be a good design? I was thinking this:
TABLE: users ROWS: user_id, name, pass, email, activated, user_level, registration_date
TABLE: relationships ROWS: relation_id, user_id, followed_id
What do you think of that?
For the user table, I guess what you have is correct. If you need to add more columns, you could simply alter that table, or add an additional table with a one to one relationship.
As for the relationships table, I think that is correct. Although i wouldn't call it followed_id. I would suggest that you could use that table for many different types of interactions, so I would call it user_id and interacter_id and the relationship_id would be a number of different types of interactions (follow, poke, etc).