A User with many Addresses, but User has a primary billing, shipping, and profile Address - mysql

I'm building a Rails app where a User can have many Addresses. A User also needs a primary billing Address, primary shipping Address, and primary profile Address. These primary fields can point to the same Address. A User cannot have more than one of any primary Address.
I've created a join table called AddressInfo, and I'm bouncing between a few options:
Make 3 columns on the User model corresponding to each of the primary Address ids (this would remove the need for the join model I think).
Add a primary boolean column to AddressInfo, and make sure only one is true when scoped by user_id, address_id and purpose (purpose being billing, shipping or profile).
Add a primary date time column to AddressInfo, and use the most recently updated as the primary address (scoped like option 2).
Maybe these options aren't the best, but it's what I've come up with so far.
Any help on how to resolve this issue would be appreciated.
UPDATE:
To be clear, once an Address is created it should always belong to that User and be undeletable. Ex. a User changes their primary billing address to a new Address: they should still be able to retrieve that old Address (maybe even make it a primary address again). If I go with option 1 and remove the join table, that means I'll need a user_id on Address.

Go with option 1, 3 columns. This will make less of a headache (as a programmer), will run faster, and is more flexible for doing things like combining similar addresses into one. Maybe you have 2 people with the same address, they could share the same record (not recomeneded though).

If you're using rails I would look to a rails solution to 'stay on the rails'.
I would consider STI (Single Table Inheritance)
More info at Rails: Need help defining association for address table
or a Polymorphic relationship - http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
As you want 1 user to have multiple address (rather than ther being multiple user types) than STI may be best for you.
Note: they can also be combined, e.g. http://www.archonsystems.com/devblog/2011/12/20/rails-single-table-inheritance-with-polymorphic-association/
There's a great example of STI addressing this issue at: http://blog.arkency.com/2013/07/sti/

Another possibility is to create another model to hold user.id, addressinfo.id, and an primary_for_address_type (containing "Shipping", "Profile", "Billing").
Constrain this to be unique on user and primary_for_address_type, and you can tag addresses in AddressInfo as being the primary for particular address types in a completely extensible way that still guarantees uniqueness of the primary address.
You might join directly from this model to address, but there's scope for getting it out of sync with your addressinfo model.

Related

At what point should I create a separate table (mysql)?

A friend and I are working on a database that stores information about cPanel hosting accounts, such as what settings, apps, and features each account is using.
Most of the fields are boolean, such as whether or not the account has any wordpress sites, any php 5.4 driven sites, any ruby on rails sites, etc...
A small number of fields are non-boolean data like disk usage in MB, hostname of the server the account resides on, and the username of the account, etc...
In my mind, it makes sense to store ALL this information in one single table.
So the table might have the following columns:
php54 boolean,
wordpress boolean,
ror boolean,
username varchar(8),
hostname varchar(20),
usage_mb int(9),
I figure that the primary key could be (username,hostname).
However, my friend has already set up the database with multiple tables that look like this:
Fact Table:
id int(11),
php54 boolean,
wordpress boolean,
ror boolean,
usage_mb int(9),
User Table:
id int(11),
factid int(11),
hostid int(11),
username varchar(8)
Hostname Table:
id int(11),
hostname varchar(20),
ip varchar(15),
Where each table's primary key is "id" and the user table references the hostname table and fact table using 'hostid' and 'factid' foreign keys (respectively).
I believe my friend's rationale behind multiple tables is to organize the data based on the type of data, despite all the data being related to one single, unique account.
My rationale is that since all the data belongs to one unique account, and therefore every single row is 1:1, does it make sense to have multiple tables?
I would think multiple tables would be sensible if a row in one table can reference multiple rows in another table... But in this case each row from each table can only be associated with one single row from any other table... so i think one table is fine.
Should this data be in multiple tables, or in one single table?
We're both sort of noobs figuring things out as we go.
At which point does it make sense to use multiple tables?
Currently its really difficult to write an API to add the data associated with one single account to three separate tables, as all the primary keys auto increment, and other than that there isn't any key that is unique to the account which would make it easy to update existing data.
Sorry if none of this makes sense
In your case, I dont't think having multiple tables with one to one relationships is the right way.
It is not forbidden and in some cases it can be helpfull (
Is there ever a time where using a database 1:1 relationship makes sense?), but you'll have to deal with unecessary joins in your requests.
Ignoring ids, the way you find out what your CKs (candidate keys) are and whether you should decompose is the topic of normalization to higher NFs (normal forms). This formalizes your notion of "a row in one table can reference multiple rows in another" (among others). Guessing using common sense here, there's no particular need to decompose. Introducing ids not visible at the business level is always technically unnecessary but happens per its own practical/ergonomic reasons. Further explanation/justification is information modeling & database design textbook chapters on design, CKs, NFs & surrogates--read some. Vague notions like "same type of data" are not helpful.
(TL;DR "At what point should I create a separate table?" is a basic question with a complex answer that requires learning some stuff.)

Mysql database design for customer multiple addresses and default address

I am creating the database structure of an ecommerce with Mysql and INNODB engine.
Point 1: To create multiple addresses for the customers i have this tables
Am I doing it in the correct way? And how should I store the default address (in which table)?
Point 2: I have another table called "Suppliers", should i just connect it to addresses with a "supplier_address" table or is there a better way?
Point 3: What about the tables cities and countries? Should i add something or is that ok? Maybe a field "district" in another table beetween the two?
In my view you're making this far too complex. There's no need to make your address schema so over-normalized. Most systems I've seen that handle multiple customer addresses have a customer table like yours, and then have an address table, as follows:
customer_id
address_ordinal (small number for each customer: 0,1,2,3 etc).
primary (boolean)
address_1
address_2
locality (city, village, etc)
province (state, etc)
postcode (zip, postcode etc)
country
customer_id is a foreign key to the customer table. The primary key is a composite of (customer_id, address_ordinal). The primary column is true if the address is the primary one.
Regarding your question about suppliers, you might want to create a common table called "contacts", and give both your customers and suppliers contact_ids.
If your system contains a reference table (perhaps something you purchase from a data supplier) containing (postcode, locality, province) rows, you can use that to help populate your address table. But you should avoid forcing your addresses to only contain hard-coded postcodes: those reference tables get out of date very fast.
I'll start out my answer with the ole cliche: "There's more than one way to skin a cat." That said, I have a few suggestions:
Point 1 - Assuming a customer can have multiple addresses (i.e. billing and mailing), then yes, you have the right idea in terms of the separate mapping table. As for adding a field to customer_addresses called default or preferred, or something like that, it's not a bad idea, but another option is to add a new field called address_type that would reference a separate table with two records, "Billing" and "Mailing" and/or whatever else you would want. Then, in whatever application you are coding that is going to use the address data, depending on what context i.e. if you're on the billing info page, then code the address type that you use on the page itself something like SELECT * FROM customer_addresses WHERE address_type = 2 /* Billing */.
Point 2 - Same as for customers.
Point 3 - Do you want to be able to display shortened country names? For example, abbreviate "United States" to "US," "Canada" to "CAN," or "United Kingdom" to "UK?" I'd consider adding a field for abbreviated country names for that purpose.

many to many relationships in ms access

I have a database (for a pet sitting company) containing tables for the following:
Customers
emergency contacts
phone numbers
phone types
The phone numbers are stored in a separate table to allow for efficient storage of a virtually unlimited number of phone numbers per customer. The phone numbers table stores both the customer ID and the phone type ID in addition to the primary key. My question is - is the best way to allow for emergency contacts to have the same functionality with phone number records to add another field to the phone numbers table "emergency contact ID"? Or should I be storing emergency contacts in the same table as customer (and rename it Individuals)? If so, please tell me how to create a relationship between records in the same table.
Thanks so much,
Jessica
You have to ask yourself the question: how far should you really go to respect data normalisation rules?
I'm not sure what the PhoneTypes table would contain, but if it is a list of things like Mobile, Work, Home, iPhone you are probably going a bit too far already: you're not building a contacts application, you're building a Pet Sitting application, there are probably more important areas of the software that would demand your development time.
Increasing the complexity of software is costly: time to mimplement features tends to creep up, as well as complexity and along with it the risks of errors, cost of maintenance, and more often than not, performance suffers as well.
These contacts details are really just properties of the Customer.
A Customer can have multiple telephone numbers and multiple emergency contacts.
Usually these should be listed in order of importance, so if the needs arises, you call the most relevant person first.
Without more information, the way I would handle this would simply to leave 2 memo fields in my Customer table where the user of the app can enter that data in any way she pleases, so she can list it in the right order, make annotations as necessary (Call on Mondays only, Customer's mum, call after 11:00am only, etc).
You can further constrain data input if you wish, like have a textbox where the user enters the details before clicking an 'Add' button that will append the data to the field, for instance by using a semi-conlon or simply CrLf to separate records. The data can then be split on the semi-colon or CrLf and shown in a listbox on the form for better presentation.
You can handle both Customer Phone numbers and Emergency contact numbers in the same way.
This makes things simple: all the Customer data is in one table instead of being split across multiple tables, with no unnecessary joins, it won't take more space than using multiple tables (actually, it will save space). It makes reporting easy (you can simply show the customer list and that will show all available phone numbers for all customer without you having to do anything fancy), it makes searching easy as well.
Having multiple values in a single field is quite common for peripheral data.
Unless you absolutely need to separate contacts, and make complex reports based on them or make sure you can re-use them, you do not have to create tables for every bit of information. Let the application user enter what is relevant for the Customer.
Constrain data entry to format it and check its consistency if you want, but ultimately, unless the purpose of the software is to maintain a complex contact list, don't make it harder than it probably should. A bit of VBA and some string manipulation is sufficient to constrain the data, allow it to be rearanged in the order that's most relevant by the user, and it will make your app snappier by avoiding some complexity.
Anyway, I would start with something simple anyway and see later if splitting the data accross multiple tables makes sense.
Avoid premature optimisation.
However, if you feel you really need to handle this by the book, I would probably handle it as follow:
Store everything in a Contact table that could have properties like these:
ID: unique contact ID
PhoneNumber: TEXT
PhoneTypeID: (whatever that is if it links to your PhoneType table)
IsEmergencyContact: BOOLEAN
ContactName: TEXT, freeform, how to address the contact person
CustomerID: foreign key linking to the Customer table
Notes: MEMO, any useful info about the contact
Rank: INTEGER, a sortable rank of importance for this contact
If you want to decouple the Customer from the Contact, so you can re-use the contact for multiple customers, you would need an intermediary table:
The Contact table would become:
ID: unique contact ID
PhoneNumber: TEXT
PhoneTypeID: (whatever that is if it links to your PhoneType table)
ContactName: TEXT, freeform, how to address the contact person
Notes: MEMO, any useful info about the contact
And the CustomerContact table (that makes the many-to-many relationship possible):
CustomerID: foreign key linking to the Customer table
ContactID: foreign key linking to The Contact table
IsEmergencyContact: BOOLEAN
Rank: INTEGER, a sortable rank of importance for this contact
To display and manage the list of Contacts and list of Emergency contacts, you simply need to filter each listbox or subform where you show the information based on whether IsEmergency is true or false.
Now, if you want the same contact to have multiple phone numbers, you will have to split everything even further:
The Contact table would become:
ID: unique contact ID
ContactName: TEXT, freeform, how to address the contact person
Notes: MEMO, any useful info about the contact
A PhoneNumber table would contain:
ID: Phone record ID
ContactID: foreign key linking to The Contact table
PhoneNumber: TEXT
PhoneTypeID: (whatever that is if it links to your PhoneType table)
Notes: MEMO, any useful info about this particular phone number
Now you have 4 tables to store all the info you need and share it any way you want, so a Customer can have multiple contacts (emergency or not), Contacts can have multiple phone numbers, Contacts can be shared accross customers (so one customer's contact is another customer's emergency contact):
Customer
Contact
PhoneNumber
CustomerContact
As I said, doing it the right way will entail a lot more complexity than maybe you really need.
Be careful about not building complexity prematurely. It's nice to anticipate the worse case scenario, but often, it means that you are prematurely optimising and therefore spending time on an area of the software that is not as important as the core of your app.
You always have to ask yourself: should I spend 2 days implementing this or spend 2 days refining the UI, testing or adding code to ensure data integrity, etc?
More often than not, YAGNI
I'd store it the same way as you store phone numbers; in its own table. This allows you the ability to store multiple numbers, and some people may have multiple emergency contact numbers. You always want to think about scalability when designing a database, and plan for the most complex situations. For example, I would imagine with pet sitting that a lot of your customers would come through word-of-mouth, and it's very possible you'll use the same contact for multiple clients.
Your first instinct (storing customers and contacts in a single table) was correct. If you think about it, customers and contacts are both people. It's just that both customers and emergency contacts are a specialised case of people. We can model this using a relational DB.
Let's create a table to hold info about people:
create table tblPeople (
ID autoincrement primary key
, FirstName varchar(100)
, LastName varchar(100)
, Notes memo
)
Now let's have a table to hold info about customers, but enforcing the fact that customers must also be people:
create table tblCustomers (
ID long primary key
constraint Customers_ID
references tblPeople (ID)
, EmergencyContactID long
constraint Customers_EmergencyContactID
references tblPeople (ID)
)
This is called a one-to-one relationship and is used to implement specialisation--like inheritance in object-oriented programming.
You have a choice here. Do you want to let each person have an arbitrary number of phone numbers of arbitrary types? This is obviously more general and more powerful. But also more complicated. Or do you want to go back and just store a fixed number of phone numbers for each person?
Let's say you want to do the former just to take it all the way. In that case, you need a table to hold phone numbers:
create table tblPhoneNumbers (
ID autoincrement primary key
, PhoneNumber varchar(15)
)
Notice how we don't specify here anything about what type of phone number it is. That part is next:
create table tblPhoneNumberTypes (
ID autoincrement primary key
, PhoneNumberType varchar(20) not null
)
Now we associate each person with a phone number and type:
create table tblPeople_to_PhoneNumberTypes_to_PhoneNumbers (
PersonID long not null
references tblPeople (ID)
, PhoneNumberTypeID long not null
references tblPhoneNumberTypes (ID)
, PhoneNumberID long not null
references tblPhoneNumbers (ID)
, constraint People_to_PhoneNumberTypes_to_PhoneNumbers_PK
primary key (
PersonID
, PhoneNumberTypeID
, PhoneNumberID
)
)
Here each person (and therefore each customer and each emergency contact) can have an arbitrary number of phone numbers of arbitrary types. Hence this is actually a many-to-many-to-many link table. I believe that is the key (or let's say 'secret sauce') to your contact-phone type-phone number model.
In link tables like the above I prefer to use multiple-column primary keys as I feel there is no useful purpose to an integer primary key column. Here the primary key enforces the fact that each person-and-phone-number combination should be listed only once, with one phone number type.
Note that the above is all valid Access ANSI-92 SQL.

MySQL database basic design

I have 3 entities:
buildings
activities
addresses
And I don't know how to foreign key the relationships between tables.
Buildings are located at addresses.
Activities are performed at addresses (one address at a time).
But I just want one address table.
Suppose the next attributes:
Buildings(id,phone,email,image,comments) <- should I put address_id ?
Activities(id,description) <- should I put address_id?
Addresses(id,street,city,state,postcode) <- or should I put center_id and activity_id here?
Thank you in advance!
You should use address_id both in buildings and activities tables.
Address is unique, while many buildings and many activities can be located to the same address!!
Your question implies that multiple buildings can be located at the same address - is this what you want? If so, just normalize it accordingly:
The Address is your 'root entity':
ADDRESS(address_id,street,city,state,postcode)
A Building can be located at exactly one Address, so include a reference to Address, a foreign key:
BUILDING(building_id,phone,email,image,comments,address_id)
An activity is performed at exactly one address, references to Address by foreign key:
ACTIVITY_ID(activity_id,description,address_id)
Maybe you should think about whether:
a street number is missing in the address?
should having more than one building at a given address be possible?
more than one address for a given building is possible (yes, I've seen this)?
a separate ADDRESS table is really necessary (see above questions)?
Alex, you should have the IDs in both tables, as you're saying in your question. There is no need to have them in separate tables as actually the address of a building will be where an activity will be performed, right?
If you are worried about two buildings having the same location then add a uniq index in the address_id column of the buildings table.
Moving a bit forward. Can you have an address without a building? If that is the case, then you could even add the address data (columns) to the buildings table. Because it would be a one-to-one relationship and no other entity would need to use the address table but the buildings one. That way you would get rid of the addresses table

Users table - one table or two?

i wanna have a Users details stored in the database.. with columns like firstname, last name, username, password, email, cellphone number, activation codes, gender, birthday, occupation, and a few other more. is it good to store all of these on the same table or should i split it between two users and profile ?
If those are attributes of a User (and they are 1-1) then they belong in the user table.
You would only normally split if there were many columns; then you might create another table in a 1-1 mapping.
Another table is obviously required if there are many profile rows per user.
One table should be good enough.
Two tables or more generally vertical portioning comes in when you want to scale out. So you split your tables in multiple tables where usually the partiotioning criteria is the usage i.e., the most common attributes which are used together are housed in one table and others in another table.
One table should be okay. I'd be storing a hash in the password column.
I suggest you read this article on Wikipedia. about database normalization.
It describes the different possibilities and the pros and cons of each. It really depends on what else you want to store and the relationship between the user and its properties.
Ideally one table should be used. If the number of columns becomes harder to manage only then you should move them to another table. In that case, ideally, the two tables should have a one-one relationship which you can easily establish by setting the foreign key in the related table as the primary key:
User
-------------------------------
UserID INT NOT NULL PRIMARY KEY
UserProfile
-------------------------------------------------------
UserID INT NOT NULL PRIMARY KEY REFERENCES User(UserID)
Depend on what kind of application it is, it might be different.
for an enterprise application that my users are the employees as well, I would suggest two tables.
tbl_UserPersonallInformation
(contains the personal information
like name, address, email,...)
tbl_UserSystemInformation (contains
other information like ( Title,
JoinedTheCompanyOn,
LeftTheCompanyOn)
In systems such as "Document Managements" , "Project Information Managements",... this might be necessary.
for example in a company the employees might leave and rejoin after few years and even they will have different job title. The employee had have some activities and records with his old title and he will have some more with the new one. So it should be recorded in the system that with which title (authority) he had done some stuff.