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.
Related
I am working on a database which as a user table and a party table. A user can go to many parties and the party can host many users. So this is a many-to-many relationship. But since its not possible to have a many to many relationship between two tables, I created a joiner table called 'user_party' table. Now I am not sure what goes in the party table and what goes in the user_party table. For example, user table has basic columns like user_id, user_name, user_email, etc. and party table has information like party_description, party_time, party_location, etc. Should these party table values go to user_party table instead? What values should the joiner table include and what goes in the party table?
The joiner table should be here to maintain the relation between a particular user and a specific party, and in your case, not more.
Before all, the party should be uniquely defined with a party_id primary column. Then, a user_party table could be define with only two columns: a user_id and a party_id.
So, the join would involve 3 table rows uniquely identified:
One from the user table (identified by the user_id and storing all users details such as first_name, address...)
One from the party table (identified by the party_id and storing all the related info like location, start_datetime...)
One from the user_party(identified by the t-uple [ user_id, party_id])
The user_party table could only embed some data which are meaningful for single occurrences of the [ user_id, party_id] t-uple itself, such as the number of beer cans brought to a particular party :)
Eventually, these data could be externally stored into a specific table in order to keep only the relational aspect there and the t-uple extended with another key.
According to the underlying DB engine, the definition may go one step further, with the user_id and party_id columns of the user_party table declared as foreign keys, and additional drop and update triggers to handle automatic data binding across related tables.
I think I have a solution for you. As I understand from your description you need to change your schema a little bit, and your table should be look like below.
User(user_id, user_name, user_email);
party (party_id,party_description, party_time, party_location);
user_party (id,party_id,user_id);
hostuser_party (id,party_id,user_id);
Note: hostuser_party table is required if a party hosted by multiple users. If party always hosted by one user then you can add host_id(User_id) column in party table.
I have a database with contacts in it. There are two different types of contacts, Vendors and Clients.
The Vendor table has a vendor_contacts table attached via foreign key value to allow for a one to many relationship. The client has a similar table.
These contacts can have a one or many relationship with a phone numbers table. Should i have a separate phone numbers table for each of these or one shared phone number table with two foreign keys allowing one to be null?
OPTION 1
Here I would have to enforce that one of vendor_id or client_id was NULL and the other not NULL in the shared phone table.
OPTION 2
Here each table would have its own phone number table.
TBH I would merge the vendor and client tables and have a 'contact' table. This could have a contact type and would allow for newer contacts to be added.
Consider you want to add something to your contacts - address, you may have to change each table in the same way, then you want birthday (OK maybe not but just as an example) and again, changes to multiple tables. Whereas if you have a single table, it can reduce the overhead of managing this.
This will also mean you have one contact phone number table!
"wasting space" is not really a meaningful concern in modern database systems - and "null" values are usually optimized by the storage engine to take no space anyway.
Instead, I think you need to look at likely query scenarios, at maintainability, and at intelligibility of your schema.
So, in general, a schema that repeats itself - many tables with similar columns - suggest poor maintainability, and often lead to complicated queries.
In your example, imagine a query to find out who called from a given number, and whom they might have been trying to reach.
In option 1, you query the phone number, and outer join it to the two contact tables - relatively easy. In option 2, you have a union of two similar queries (only the table names would change) - duplication and lots of chance for bugs.
Imagine you want to break the phone number into country, region and phone number - in option 2, you have to do this twice (and modify all the queries twice); in option 1, you have to do this only once.
In general terms, repetition is a sign of a bad software design; this also counts for database schemas.
That's also a reason (as #siggisv and #NigelRen suggested) to flatten the vendor_contact and client_contact tables into a single table with a "contact_type" column.
I would use two different tables, a vendor_contacts table and a client_contacts table.
If you only have one table, you always waste space as you will have in each row a null column
option 2
but change vendor_contact and client_contact to 'contact'
and add a 'type' column to 'contact' that identified 'Client' or 'vendor' if you need to separate the records.
I would do as others have suggested and merge vendor_contact and client_contact into one contact table.
But on top of that, I doubt that contact<->phone is a one-to-many relationship. If you consider this example you will see that it's a many-to-many relationship:
"Joe and Mary are both vendors, working in the same office. Therefore they both have the same landline number. They also have each their own mobile number."
So in my opinion you would need to add a contact_number table with two columns of foreign keys, contact_id and phone_id.
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.
I have a table called 'notes', on this table I need to track who made that note, but the problem is that the creator of the note can be a user stored in one of three possible tables:
users
leads
managers
I have though of simply create three fields on 'notes' to represent the three possible relations: note.user, note.lead, note.manager
With this approach I would be forced to create three table joins when requesting the notes to gather the creators information, and I don't think that is the way to go, so I would like to hear your ideas or comments and what would be the best approach on this.
For me personally this smells like a design problem on a totally different part of the schema: Are manageers not users? Do leads carry person information?
With any approach that creates a relation between one column and one of three others, you will need three joins for the select. If you can't rectify the underlying problem, I recommend you use
note_type ENUM('users','leads','managers')
as an additional field and
SELECT
...
IFNULL(users.name(IFNULL(managers.name,leads.name))) AS name
..
FROM notes
LEFT JOIN users ON notes.note_type='users' AND users.id=notes.note_source
LEFT JOIN managers ON notes.note_type='managers' AND managers.id=notes.note_source
LEFT JOIN leads ON notes.note_type='leads' AND leads.id=notes.note_source
...
for the query
I think you need to abstract out the concept of a user id, so that it does not depend on their role. The author of a note could then be specified by the user id.
Users could be assigned roles, and maybe more than one.
The correct way to structure this would be to pull all common data out of users, leads, and managers. Unify this data into a "contact" table. Then if you want to get all notes for a given manager:
managers->contacts->notes
for a lead:
leads->contacts->notes
Notice your original post: "the problem is that the creator of the note can be a user stored in one of three possible tables"
From the structure of your sentence you even admit that all these entities have something in common; they are all users. Why not make the DB reflect this?
you have to model a parent table for the three tables you already have. Define a table that depicts generally user, leads and manager tables. Something like "Person". So you have all of the ids of the three tables and any common attributes on the Person table. And when you must define the relationship you put the foreign id "Person_ID" on the note table. And when you model user, leads and manager tables you also put the primary key as a foreign key to the Person table.
So you would have something like this:
Table users:
Users(
person_id primary key
...(attributes of Users)
foreign key person_id references Person.person_id
)
This model i depict is common to any relational model you have to model using parents and childs
I'm creating a social networking site with features similar to Facebook.
I want to start with schema design for my database.
What i thought was to create each table for each user who registers to our site.. am i doing right?
If a million users register to my site, a million tables will be created. how to go on about optimizing this? Please do suggest me techniques to overcome this and some references or books to learn about such concepts will be vry useful..
Thanks in Advance.
This is not the way you want to do it.
What you want to do is have a table (perhaps called 'users') that contains one row for each user that registers. Creating a new table for each user is completely pointless and would cause terrible performance.
Maybe something like this:
TABLE users
- username AS VARCHAR(255)
- password AS VARCHAR(255) (use a hashed password, of course)
- ...
Then when a user registers, simply insert the information they provide into the users table as a new row.
That would be massive overkill. You should probably read up on database design (start with normalisation, but don't overdo it). Then write down what you want to save for each user, and think about how to save it without saving data double.
But I'm pretty sure a table-per-user is not an option for this.
You must be confusing the meaning of the words database, table, field (or column), record (or row).
A database contains all your data for a specific project. There is always one database per project (or almost always)
A table contains all data of a specific entity and by saying entity, I mean an object type that is imaginable as real or seperatelly existing by itself. A person is an entity, a book is an entity, a phone is an entity, a movie is an entity, etc. Each of these would be seperate tables in a database.
A field (or column) is a data type that represents a specific characteristic (feature) of a table's entity. For example a table of users can have the fields: NAME, SURNAME, AGE, etc. These are all features that a user has.
A record (or row) is an actual item of one table. It is a single 'piece' of the table's entity. For example in a table of users, one record is one single user, namely {NAME:"John", SURNAME:"Smith", AGE:"32"}.
In your example, I can tell you for sure that you only need one database. You want to store information for many users, so you need one table called USER. You will need to store features to your users, like: name, surname, age, address, etc., then you will need to create the respective fields in this table: NAME, SURNAME, AGE, ADDRESS, etc. Then you will need to insert your data in the database as records. It will be one record per user you want to store.